From 5932b8817b412e89c928c608fb0874c8672ba6f7 Mon Sep 17 00:00:00 2001 From: "Alexander S. Aganichev" Date: Fri, 25 Feb 2000 10:15:17 +0000 Subject: [PATCH] GoldED+ sources: Initial revision. --- File_id.diz | 6 + GNUmakef.def | 63 + GNUmakef.inc | 74 + GNUmakef.lib | 11 + GNUmakef.prg | 23 + Makefile | 24 + cfgs/charset/850_850.chs | 161 + cfgs/charset/850_asc.chs | 161 + cfgs/charset/850_iqp.chs | 289 + cfgs/charset/850_iso.chs | 161 + cfgs/charset/can_asc.chs | 162 + cfgs/charset/can_ibm.chs | 162 + cfgs/charset/cmp_ibm.esc | 70 + cfgs/charset/dut_asc.chs | 162 + cfgs/charset/dut_ibm.chs | 162 + cfgs/charset/fin_asc.chs | 162 + cfgs/charset/fin_ibm.chs | 162 + cfgs/charset/frn_asc.chs | 162 + cfgs/charset/frn_ibm.chs | 162 + cfgs/charset/ger_asc.chs | 162 + cfgs/charset/ger_ibm.chs | 162 + cfgs/charset/i1m_ibm.chs | 162 + cfgs/charset/i51_ibm.esc | 65 + cfgs/charset/ibm_asc.chs | 161 + cfgs/charset/ibm_cmp.chs | 161 + cfgs/charset/ibm_i51.chs | 162 + cfgs/charset/ibm_ibm.chs | 161 + cfgs/charset/ibm_iqp.chs | 289 + cfgs/charset/ibm_iso.chs | 161 + cfgs/charset/ibm_mac.chs | 161 + cfgs/charset/ibm_mne.chs | 161 + cfgs/charset/ibm_swe.chs | 161 + cfgs/charset/ibm_vt1.chs | 164 + cfgs/charset/iqp_850.chs | 161 + cfgs/charset/iqp_ibm.chs | 161 + cfgs/charset/iso_850.chs | 161 + cfgs/charset/iso_asc.chs | 161 + cfgs/charset/iso_ibm.chs | 161 + cfgs/charset/iso_iso.chs | 161 + cfgs/charset/iso_mac.chs | 161 + cfgs/charset/iso_vt1.chs | 161 + cfgs/charset/ita_asc.chs | 162 + cfgs/charset/itl_ibm.chs | 162 + cfgs/charset/mac_850.chs | 161 + cfgs/charset/mac_asc.chs | 161 + cfgs/charset/mac_ibm.chs | 161 + cfgs/charset/mac_iso.chs | 161 + cfgs/charset/mac_vt1.chs | 164 + cfgs/charset/mne_850.esc | 182 + cfgs/charset/mne_ibm.esc | 185 + cfgs/charset/nor_asc.chs | 162 + cfgs/charset/nor_ibm.chs | 162 + cfgs/charset/prt_asc.chs | 162 + cfgs/charset/prt_ibm.chs | 162 + cfgs/charset/spn_asc.chs | 162 + cfgs/charset/spn_ibm.chs | 162 + cfgs/charset/swe_asc.chs | 162 + cfgs/charset/swe_ibm.chs | 162 + cfgs/charset/swi_asc.chs | 162 + cfgs/charset/swi_ibm.chs | 162 + cfgs/charset/uk__asc.chs | 162 + cfgs/charset/uk__ibm.chs | 162 + cfgs/colorset/gedcol00.cfg | 50 + cfgs/colorset/gedcol01.cfg | 50 + cfgs/colorset/gedcol02.cfg | 50 + cfgs/colorset/gedcol03.cfg | 50 + cfgs/colorset/gedcol04.cfg | 50 + cfgs/colorset/gedcol05.cfg | 50 + cfgs/colorset/gedcol06.cfg | 50 + cfgs/colorset/gedcol07.cfg | 50 + cfgs/colorset/gedcol08.cfg | 98 + cfgs/colorset/gedcol09.cfg | 50 + cfgs/colorset/gedcol10.cfg | 51 + cfgs/colorset/gedcol11.cfg | 54 + cfgs/colorset/gedcol12.cfg | 52 + cfgs/colorset/gedcol13.cfg | 62 + cfgs/colorset/gedcol14.cfg | 50 + cfgs/colorset/gedcol15.cfg | 51 + cfgs/colorset/gedcol16.cfg | 49 + cfgs/colorset/gedcol17.cfg | 62 + cfgs/colorset/gedcol18.cfg | 50 + cfgs/colorset/gedcol19.cfg | 50 + cfgs/colorset/gedcol20.cfg | 53 + cfgs/colorset/gedcol21.cfg | 67 + cfgs/colorset/gedcol22.cfg | 58 + cfgs/colorset/gedcol23.cfg | 68 + cfgs/colorset/gedmon00.cfg | 50 + cfgs/colorset/gedmon01.cfg | 50 + cfgs/colorset/gedmon02.cfg | 50 + cfgs/config/advanced.cfg | 1811 ++++++ cfgs/config/gedlngdk.cfg | 59 + cfgs/config/gedlngit.cfg | 63 + cfgs/config/gedlngnl.cfg | 63 + cfgs/config/gedlngus.cfg | 59 + cfgs/config/goldhelp.cfg | 714 +++ cfgs/config/goldkeys.cfg | 420 ++ cfgs/config/goldlang.cfg | 499 ++ cfgs/config/goldlang.ger | 488 ++ cfgs/config/goldlang.it | 501 ++ cfgs/config/goldlang.nl | 480 ++ cfgs/config/goldlang.ru2 | 511 ++ cfgs/config/goldlang.rus | 509 ++ cfgs/config/simple.cfg | 150 + cfgs/template/dansk.tpl | 94 + cfgs/template/default.tpl | 30 + cfgs/template/email.tpl | 25 + cfgs/template/golded.cfm | 12 + cfgs/template/golded.tpl | 94 + cfgs/template/newsgrps.tpl | 25 + docs/StyleGuide | 153 + docs/building.txt | 29 + docs/copying | 340 ++ docs/copying.lib | 482 ++ docs/license.txt | 76 + docs/linux.txt | 116 + docs/ncurses.txt | 73 + docs/notework.txt | 2809 ++++++++++ docs/readme.txt | 15 + docs/rusfaq.txt | 121 + docs/tips.os2 | 113 + docs/tips.txt | 32 + docs/todowork.txt | 76 + goldlib/gall/Makefile | 22 + goldlib/gall/gall.all | 164 + goldlib/gall/gasmamis.h | 42 + goldlib/gall/gbmh.cpp | 134 + goldlib/gall/gbmh.h | 65 + goldlib/gall/gcmpall.h | 111 + goldlib/gall/gcrc16tb.cpp | 76 + goldlib/gall/gcrc32tb.cpp | 157 + goldlib/gall/gcrcall.h | 90 + goldlib/gall/gcrchash.cpp | 63 + goldlib/gall/gcrckeyv.cpp | 155 + goldlib/gall/gcrcm16.cpp | 53 + goldlib/gall/gcrcm32.cpp | 54 + goldlib/gall/gcrcs16.cpp | 53 + goldlib/gall/gcrcs32.cpp | 53 + goldlib/gall/gctype.h | 62 + goldlib/gall/gcurses.h | 248 + goldlib/gall/gdbgerr.cpp | 82 + goldlib/gall/gdbgerr.h | 187 + goldlib/gall/gdbgexit.cpp | 47 + goldlib/gall/gdbgtrk.cpp | 146 + goldlib/gall/gdbgtrk.h | 82 + goldlib/gall/gdefs.h | 172 + goldlib/gall/gdirposx.cpp | 133 + goldlib/gall/gdirposx.h | 78 + goldlib/gall/geval.cpp | 110 + goldlib/gall/geval.h | 131 + goldlib/gall/gevalhum.cpp | 100 + goldlib/gall/gevalrpn.cpp | 69 + goldlib/gall/gfile.cpp | 419 ++ goldlib/gall/gfile.h | 248 + goldlib/gall/gfilport.cpp | 204 + goldlib/gall/gfilutil.h | 255 + goldlib/gall/gfilutl1.cpp | 455 ++ goldlib/gall/gfilutl2.cpp | 213 + goldlib/gall/gftnaddr.cpp | 392 ++ goldlib/gall/gftnall.h | 257 + goldlib/gall/gftnnl.cpp | 103 + goldlib/gall/gftnnl.h | 136 + goldlib/gall/gftnnlfd.cpp | 739 +++ goldlib/gall/gftnnlfd.h | 363 ++ goldlib/gall/gftnnlfu.cpp | 306 + goldlib/gall/gftnnlfu.h | 88 + goldlib/gall/gftnnlge.cpp | 498 ++ goldlib/gall/gftnnlge.h | 128 + goldlib/gall/gftnnlv7.cpp | 708 +++ goldlib/gall/gftnnlv7.h | 291 + goldlib/gall/gfuzzy.cpp | 189 + goldlib/gall/gfuzzy.h | 76 + goldlib/gall/ghdrmime.cpp | 71 + goldlib/gall/ghdrmime.h | 38 + goldlib/gall/gkbdbase.cpp | 1462 +++++ goldlib/gall/gkbdbase.h | 167 + goldlib/gall/gkbdcode.h | 465 ++ goldlib/gall/gkbdgetm.cpp | 328 ++ goldlib/gall/gkbdunix.cpp | 640 +++ goldlib/gall/gkbdunix.h | 72 + goldlib/gall/gkbdwait.cpp | 67 + goldlib/gall/glog.cpp | 196 + goldlib/gall/glog.h | 99 + goldlib/gall/glzh.cpp | 651 +++ goldlib/gall/glzh.h | 41 + goldlib/gall/gmemall.h | 77 + goldlib/gall/gmemdbg.cpp | 695 +++ goldlib/gall/gmemdbg.h | 163 + goldlib/gall/gmemi86.h | 234 + goldlib/gall/gmemutil.cpp | 69 + goldlib/gall/gmnubase.h | 134 + goldlib/gall/gmoubase.cpp | 455 ++ goldlib/gall/gmoubase.h | 173 + goldlib/gall/gmsgattr.cpp | 202 + goldlib/gall/gmsgattr.h | 494 ++ goldlib/gall/gprnall.h | 41 + goldlib/gall/gprnutil.cpp | 88 + goldlib/gall/gregex.cpp | 91 + goldlib/gall/gregex.h | 73 + goldlib/gall/gsearch.cpp | 169 + goldlib/gall/gsearch.h | 106 + goldlib/gall/gshare.h | 66 + goldlib/gall/gsigunix.cpp | 82 + goldlib/gall/gsigunix.h | 46 + goldlib/gall/gsnd.cpp | 494 ++ goldlib/gall/gsndall.h | 129 + goldlib/gall/gsndsapi.h | 83 + goldlib/gall/gsndwrap.cpp | 94 + goldlib/gall/gsrchmgr.cpp | 94 + goldlib/gall/gsrchmgr.h | 142 + goldlib/gall/gstrall.h | 164 + goldlib/gall/gstrarr.h | 64 + goldlib/gall/gstrbags.cpp | 165 + goldlib/gall/gstrbags.h | 140 + goldlib/gall/gstrctyp.cpp | 138 + goldlib/gall/gstrmail.cpp | 178 + goldlib/gall/gstrmail.h | 96 + goldlib/gall/gstrname.cpp | 82 + goldlib/gall/gstrutil.cpp | 607 ++ goldlib/gall/gtimall.h | 161 + goldlib/gall/gtimjuld.cpp | 74 + goldlib/gall/gtimutil.cpp | 504 ++ goldlib/gall/gtxtpara.cpp | 197 + goldlib/gall/gtxtpara.h | 168 + goldlib/gall/gusrbase.cpp | 228 + goldlib/gall/gusrbase.h | 104 + goldlib/gall/gusrezyc.cpp | 143 + goldlib/gall/gusrezyc.h | 222 + goldlib/gall/gusrgold.cpp | 114 + goldlib/gall/gusrgold.h | 121 + goldlib/gall/gusrhuds.cpp | 114 + goldlib/gall/gusrhuds.h | 122 + goldlib/gall/gusrmax.cpp | 119 + goldlib/gall/gusrmax.h | 164 + goldlib/gall/gusrpcb.cpp | 119 + goldlib/gall/gusrpcb.h | 151 + goldlib/gall/gusrra2.cpp | 152 + goldlib/gall/gusrra2.h | 165 + goldlib/gall/gusrwcat.h | 124 + goldlib/gall/gusrxbbs.cpp | 87 + goldlib/gall/gusrxbbs.h | 210 + goldlib/gall/gutlclip.cpp | 160 + goldlib/gall/gutlclip.h | 72 + goldlib/gall/gutlcode.cpp | 291 + goldlib/gall/gutlcode.h | 113 + goldlib/gall/gutldos.cpp | 402 ++ goldlib/gall/gutlgrp.cpp | 263 + goldlib/gall/gutlgrp.h | 175 + goldlib/gall/gutlmisc.cpp | 195 + goldlib/gall/gutlmisc.h | 67 + goldlib/gall/gutlmtsk.cpp | 220 + goldlib/gall/gutlmtsk.h | 80 + goldlib/gall/gutlos.h | 87 + goldlib/gall/gutlos2.cpp | 349 ++ goldlib/gall/gutlos2m.cpp | 73 + goldlib/gall/gutltag.cpp | 323 ++ goldlib/gall/gutltag.h | 115 + goldlib/gall/gutlunix.h | 60 + goldlib/gall/gutlvers.cpp | 172 + goldlib/gall/gutlwin.cpp | 331 ++ goldlib/gall/gutlwinm.cpp | 54 + goldlib/gall/gvidall.h | 420 ++ goldlib/gall/gvidbase.cpp | 2351 ++++++++ goldlib/gall/gvidinit.cpp | 1023 ++++ goldlib/gall/gwildmat.cpp | 196 + goldlib/gall/gwildmat.h | 77 + goldlib/gall/gwinall.h | 443 ++ goldlib/gall/gwinbase.cpp | 2097 +++++++ goldlib/gall/gwindow.cpp | 91 + goldlib/gall/gwindow.h | 687 +++ goldlib/gall/gwinhelp.h | 102 + goldlib/gall/gwinhlp1.cpp | 768 +++ goldlib/gall/gwinhlp2.cpp | 99 + goldlib/gall/gwininit.cpp | 328 ++ goldlib/gall/gwinline.cpp | 317 ++ goldlib/gall/gwinmenu.cpp | 1418 +++++ goldlib/gall/gwinmnub.cpp | 312 ++ goldlib/gall/gwinpckf.cpp | 257 + goldlib/gall/gwinpcks.cpp | 701 +++ goldlib/gall/gwinpick.cpp | 734 +++ goldlib/gall/gwinpick.h | 185 + goldlib/gall/gwinput.h | 226 + goldlib/gall/gwinput2.cpp | 1170 ++++ goldlib/gcfg/Makefile | 8 + goldlib/gcfg/gcfg.all | 133 + goldlib/gcfg/gedacfg.cpp | 417 ++ goldlib/gcfg/gedacfg.h | 382 ++ goldlib/gcfg/gs_db.h | 203 + goldlib/gcfg/gs_ez102.h | 500 ++ goldlib/gcfg/gs_ez110.h | 515 ++ goldlib/gcfg/gs_fd.h | 374 ++ goldlib/gcfg/gs_fech6.h | 251 + goldlib/gcfg/gs_fm092.h | 285 + goldlib/gcfg/gs_fm10g.h | 399 ++ goldlib/gcfg/gs_fm116.h | 482 ++ goldlib/gcfg/gs_ge120.h | 469 ++ goldlib/gcfg/gs_im160.h | 329 ++ goldlib/gcfg/gs_im175.h | 349 ++ goldlib/gcfg/gs_inter.h | 477 ++ goldlib/gcfg/gs_lo240.h | 526 ++ goldlib/gcfg/gs_max3.h | 604 ++ goldlib/gcfg/gs_opus.h | 1540 ++++++ goldlib/gcfg/gs_pb200.h | 506 ++ goldlib/gcfg/gs_pcb.h | 336 ++ goldlib/gcfg/gs_pop.h | 478 ++ goldlib/gcfg/gs_qbbs.h | 416 ++ goldlib/gcfg/gs_qfrnt.h | 118 + goldlib/gcfg/gs_qwk.h | 54 + goldlib/gcfg/gs_ra.h | 188 + goldlib/gcfg/gs_ra2.h | 498 ++ goldlib/gcfg/gs_recho.h | 211 + goldlib/gcfg/gs_sbbs.h | 486 ++ goldlib/gcfg/gs_ts.h | 92 + goldlib/gcfg/gs_wmail.h | 116 + goldlib/gcfg/gs_wtr.h | 536 ++ goldlib/gcfg/gs_xbbs.h | 642 +++ goldlib/gcfg/gs_xmail.h | 107 + goldlib/gcfg/gxareas.cpp | 91 + goldlib/gcfg/gxcrash.cpp | 214 + goldlib/gcfg/gxdb.cpp | 444 ++ goldlib/gcfg/gxdutch.cpp | 99 + goldlib/gcfg/gxezy102.cpp | 275 + goldlib/gcfg/gxezy110.cpp | 335 ++ goldlib/gcfg/gxfd.cpp | 164 + goldlib/gcfg/gxfecho6.cpp | 212 + goldlib/gcfg/gxfidpcb.cpp | 230 + goldlib/gcfg/gxfm092.cpp | 208 + goldlib/gcfg/gxfm100.cpp | 236 + goldlib/gcfg/gxfm116.cpp | 307 ++ goldlib/gcfg/gxgecho.cpp | 453 ++ goldlib/gcfg/gxhpt.cpp | 445 ++ goldlib/gcfg/gximail4.cpp | 160 + goldlib/gcfg/gximail5.cpp | 170 + goldlib/gcfg/gximail6.cpp | 228 + goldlib/gcfg/gxinter.cpp | 223 + goldlib/gcfg/gxlora.cpp | 202 + goldlib/gcfg/gxmax3.cpp | 246 + goldlib/gcfg/gxme2.cpp | 110 + goldlib/gcfg/gxopus.cpp | 159 + goldlib/gcfg/gxpcb.cpp | 361 ++ goldlib/gcfg/gxportal.cpp | 179 + goldlib/gcfg/gxprobrd.cpp | 157 + goldlib/gcfg/gxqecho.cpp | 109 + goldlib/gcfg/gxqfront.cpp | 105 + goldlib/gcfg/gxquick.cpp | 264 + goldlib/gcfg/gxra.cpp | 212 + goldlib/gcfg/gxraecho.cpp | 138 + goldlib/gcfg/gxsquish.cpp | 220 + goldlib/gcfg/gxsuper.cpp | 187 + goldlib/gcfg/gxtimed.cpp | 246 + goldlib/gcfg/gxtmail.cpp | 158 + goldlib/gcfg/gxts.cpp | 153 + goldlib/gcfg/gxwmail.cpp | 182 + goldlib/gcfg/gxwtr.cpp | 202 + goldlib/gcfg/gxxbbs.cpp | 195 + goldlib/gcfg/gxxmail.cpp | 236 + goldlib/glibc/Makefile | 9 + goldlib/glibc/config.h | 14 + goldlib/glibc/dummy.c | 3 + goldlib/glibc/fnmatch.c | 385 ++ goldlib/glibc/fnmatch.h | 84 + goldlib/glibc/glibc.all | 4 + goldlib/glibc/glob.c | 1388 +++++ goldlib/glibc/glob.h | 194 + goldlib/glibc/regex.c | 5829 ++++++++++++++++++++ goldlib/glibc/regex.h | 572 ++ goldlib/gmb3/Makefile | 13 + goldlib/gmb3/gmb3.all | 67 + goldlib/gmb3/gmo_msg.h | 321 ++ goldlib/gmb3/gmoarea.cpp | 68 + goldlib/gmb3/gmoarea.h | 290 + goldlib/gmb3/gmoezyc.h | 258 + goldlib/gmb3/gmoezyc1.cpp | 440 ++ goldlib/gmb3/gmoezyc2.cpp | 153 + goldlib/gmb3/gmoezyc3.cpp | 132 + goldlib/gmb3/gmoezyc4.cpp | 316 ++ goldlib/gmb3/gmoezyc5.cpp | 112 + goldlib/gmb3/gmofido.h | 206 + goldlib/gmb3/gmofido1.cpp | 249 + goldlib/gmb3/gmofido2.cpp | 262 + goldlib/gmb3/gmofido3.cpp | 189 + goldlib/gmb3/gmofido4.cpp | 304 + goldlib/gmb3/gmofido5.cpp | 199 + goldlib/gmb3/gmohuds.cpp | 121 + goldlib/gmb3/gmohuds.h | 358 ++ goldlib/gmb3/gmohuds1.cpp | 372 ++ goldlib/gmb3/gmohuds2.cpp | 727 +++ goldlib/gmb3/gmohuds3.cpp | 238 + goldlib/gmb3/gmohuds4.cpp | 373 ++ goldlib/gmb3/gmohuds5.cpp | 137 + goldlib/gmb3/gmojamm.h | 328 ++ goldlib/gmb3/gmojamm1.cpp | 205 + goldlib/gmb3/gmojamm2.cpp | 367 ++ goldlib/gmb3/gmojamm3.cpp | 388 ++ goldlib/gmb3/gmojamm4.cpp | 503 ++ goldlib/gmb3/gmojamm5.cpp | 190 + goldlib/gmb3/gmopcbd.h | 239 + goldlib/gmb3/gmopcbd1.cpp | 283 + goldlib/gmb3/gmopcbd2.cpp | 392 ++ goldlib/gmb3/gmopcbd3.cpp | 259 + goldlib/gmb3/gmopcbd4.cpp | 443 ++ goldlib/gmb3/gmopcbd5.cpp | 176 + goldlib/gmb3/gmoprot.h | 139 + goldlib/gmb3/gmosmb.h | 475 ++ goldlib/gmb3/gmosmb1.cpp | 1027 ++++ goldlib/gmb3/gmosmb2.cpp | 140 + goldlib/gmb3/gmosmb3.cpp | 1042 ++++ goldlib/gmb3/gmosqsh.h | 354 ++ goldlib/gmb3/gmosqsh1.cpp | 272 + goldlib/gmb3/gmosqsh2.cpp | 286 + goldlib/gmb3/gmosqsh3.cpp | 201 + goldlib/gmb3/gmosqsh4.cpp | 717 +++ goldlib/gmb3/gmosqsh5.cpp | 163 + goldlib/gmb3/gmowcat.h | 244 + goldlib/gmb3/gmowcat1.cpp | 238 + goldlib/gmb3/gmowcat2.cpp | 220 + goldlib/gmb3/gmowcat3.cpp | 219 + goldlib/gmb3/gmowcat4.cpp | 283 + goldlib/gmb3/gmowcat5.cpp | 126 + goldlib/gmb3/gmoxbbs.h | 286 + goldlib/gmb3/gmoxbbs1.cpp | 280 + goldlib/gmb3/gmoxbbs2.cpp | 227 + goldlib/gmb3/gmoxbbs3.cpp | 177 + goldlib/gmb3/gmoxbbs4.cpp | 419 ++ goldlib/gmb3/gmoxbbs5.cpp | 129 + goldlib/uulib/Makefile | 12 + goldlib/uulib/config.h | 76 + goldlib/uulib/fptools.c | 512 ++ goldlib/uulib/fptools.h | 60 + goldlib/uulib/uucheck.c | 1468 +++++ goldlib/uulib/uudeview.h | 245 + goldlib/uulib/uuencode.c | 1230 +++++ goldlib/uulib/uuint.h | 336 ++ goldlib/uulib/uulib.all | 8 + goldlib/uulib/uulib.c | 1200 ++++ goldlib/uulib/uunconc.c | 1500 +++++ goldlib/uulib/uuscan.c | 2751 +++++++++ goldlib/uulib/uustring.c | 165 + goldlib/uulib/uustring.h | 34 + goldlib/uulib/uuutil.c | 485 ++ goldnode/Makefile | 17 + goldnode/goldnode.all | 40 + goldnode/goldnode.cpp | 1539 ++++++ manuals/gold_ref.tei | 10418 +++++++++++++++++++++++++++++++++++ manuals/gold_ref.txt | 7028 +++++++++++++++++++++++ manuals/gold_usr.txt | 2543 +++++++++ rddt/Makefile | 17 + rddt/rddt.all | 31 + rddt/rddt.cpp | 471 ++ 448 files changed, 142031 insertions(+) create mode 100644 File_id.diz create mode 100644 GNUmakef.def create mode 100644 GNUmakef.inc create mode 100644 GNUmakef.lib create mode 100644 GNUmakef.prg create mode 100644 Makefile create mode 100644 cfgs/charset/850_850.chs create mode 100644 cfgs/charset/850_asc.chs create mode 100644 cfgs/charset/850_iqp.chs create mode 100644 cfgs/charset/850_iso.chs create mode 100644 cfgs/charset/can_asc.chs create mode 100644 cfgs/charset/can_ibm.chs create mode 100644 cfgs/charset/cmp_ibm.esc create mode 100644 cfgs/charset/dut_asc.chs create mode 100644 cfgs/charset/dut_ibm.chs create mode 100644 cfgs/charset/fin_asc.chs create mode 100644 cfgs/charset/fin_ibm.chs create mode 100644 cfgs/charset/frn_asc.chs create mode 100644 cfgs/charset/frn_ibm.chs create mode 100644 cfgs/charset/ger_asc.chs create mode 100644 cfgs/charset/ger_ibm.chs create mode 100644 cfgs/charset/i1m_ibm.chs create mode 100644 cfgs/charset/i51_ibm.esc create mode 100644 cfgs/charset/ibm_asc.chs create mode 100644 cfgs/charset/ibm_cmp.chs create mode 100644 cfgs/charset/ibm_i51.chs create mode 100644 cfgs/charset/ibm_ibm.chs create mode 100644 cfgs/charset/ibm_iqp.chs create mode 100644 cfgs/charset/ibm_iso.chs create mode 100644 cfgs/charset/ibm_mac.chs create mode 100644 cfgs/charset/ibm_mne.chs create mode 100644 cfgs/charset/ibm_swe.chs create mode 100644 cfgs/charset/ibm_vt1.chs create mode 100644 cfgs/charset/iqp_850.chs create mode 100644 cfgs/charset/iqp_ibm.chs create mode 100644 cfgs/charset/iso_850.chs create mode 100644 cfgs/charset/iso_asc.chs create mode 100644 cfgs/charset/iso_ibm.chs create mode 100644 cfgs/charset/iso_iso.chs create mode 100644 cfgs/charset/iso_mac.chs create mode 100644 cfgs/charset/iso_vt1.chs create mode 100644 cfgs/charset/ita_asc.chs create mode 100644 cfgs/charset/itl_ibm.chs create mode 100644 cfgs/charset/mac_850.chs create mode 100644 cfgs/charset/mac_asc.chs create mode 100644 cfgs/charset/mac_ibm.chs create mode 100644 cfgs/charset/mac_iso.chs create mode 100644 cfgs/charset/mac_vt1.chs create mode 100644 cfgs/charset/mne_850.esc create mode 100644 cfgs/charset/mne_ibm.esc create mode 100644 cfgs/charset/nor_asc.chs create mode 100644 cfgs/charset/nor_ibm.chs create mode 100644 cfgs/charset/prt_asc.chs create mode 100644 cfgs/charset/prt_ibm.chs create mode 100644 cfgs/charset/spn_asc.chs create mode 100644 cfgs/charset/spn_ibm.chs create mode 100644 cfgs/charset/swe_asc.chs create mode 100644 cfgs/charset/swe_ibm.chs create mode 100644 cfgs/charset/swi_asc.chs create mode 100644 cfgs/charset/swi_ibm.chs create mode 100644 cfgs/charset/uk__asc.chs create mode 100644 cfgs/charset/uk__ibm.chs create mode 100644 cfgs/colorset/gedcol00.cfg create mode 100644 cfgs/colorset/gedcol01.cfg create mode 100644 cfgs/colorset/gedcol02.cfg create mode 100644 cfgs/colorset/gedcol03.cfg create mode 100644 cfgs/colorset/gedcol04.cfg create mode 100644 cfgs/colorset/gedcol05.cfg create mode 100644 cfgs/colorset/gedcol06.cfg create mode 100644 cfgs/colorset/gedcol07.cfg create mode 100644 cfgs/colorset/gedcol08.cfg create mode 100644 cfgs/colorset/gedcol09.cfg create mode 100644 cfgs/colorset/gedcol10.cfg create mode 100644 cfgs/colorset/gedcol11.cfg create mode 100644 cfgs/colorset/gedcol12.cfg create mode 100644 cfgs/colorset/gedcol13.cfg create mode 100644 cfgs/colorset/gedcol14.cfg create mode 100644 cfgs/colorset/gedcol15.cfg create mode 100644 cfgs/colorset/gedcol16.cfg create mode 100644 cfgs/colorset/gedcol17.cfg create mode 100644 cfgs/colorset/gedcol18.cfg create mode 100644 cfgs/colorset/gedcol19.cfg create mode 100644 cfgs/colorset/gedcol20.cfg create mode 100644 cfgs/colorset/gedcol21.cfg create mode 100644 cfgs/colorset/gedcol22.cfg create mode 100644 cfgs/colorset/gedcol23.cfg create mode 100644 cfgs/colorset/gedmon00.cfg create mode 100644 cfgs/colorset/gedmon01.cfg create mode 100644 cfgs/colorset/gedmon02.cfg create mode 100644 cfgs/config/advanced.cfg create mode 100644 cfgs/config/gedlngdk.cfg create mode 100644 cfgs/config/gedlngit.cfg create mode 100644 cfgs/config/gedlngnl.cfg create mode 100644 cfgs/config/gedlngus.cfg create mode 100644 cfgs/config/goldhelp.cfg create mode 100644 cfgs/config/goldkeys.cfg create mode 100644 cfgs/config/goldlang.cfg create mode 100644 cfgs/config/goldlang.ger create mode 100644 cfgs/config/goldlang.it create mode 100644 cfgs/config/goldlang.nl create mode 100644 cfgs/config/goldlang.ru2 create mode 100644 cfgs/config/goldlang.rus create mode 100644 cfgs/config/simple.cfg create mode 100644 cfgs/template/dansk.tpl create mode 100644 cfgs/template/default.tpl create mode 100644 cfgs/template/email.tpl create mode 100644 cfgs/template/golded.cfm create mode 100644 cfgs/template/golded.tpl create mode 100644 cfgs/template/newsgrps.tpl create mode 100644 docs/StyleGuide create mode 100644 docs/building.txt create mode 100644 docs/copying create mode 100644 docs/copying.lib create mode 100644 docs/license.txt create mode 100644 docs/linux.txt create mode 100644 docs/ncurses.txt create mode 100644 docs/notework.txt create mode 100644 docs/readme.txt create mode 100644 docs/rusfaq.txt create mode 100644 docs/tips.os2 create mode 100644 docs/tips.txt create mode 100644 docs/todowork.txt create mode 100644 goldlib/gall/Makefile create mode 100644 goldlib/gall/gall.all create mode 100644 goldlib/gall/gasmamis.h create mode 100644 goldlib/gall/gbmh.cpp create mode 100644 goldlib/gall/gbmh.h create mode 100644 goldlib/gall/gcmpall.h create mode 100644 goldlib/gall/gcrc16tb.cpp create mode 100644 goldlib/gall/gcrc32tb.cpp create mode 100644 goldlib/gall/gcrcall.h create mode 100644 goldlib/gall/gcrchash.cpp create mode 100644 goldlib/gall/gcrckeyv.cpp create mode 100644 goldlib/gall/gcrcm16.cpp create mode 100644 goldlib/gall/gcrcm32.cpp create mode 100644 goldlib/gall/gcrcs16.cpp create mode 100644 goldlib/gall/gcrcs32.cpp create mode 100644 goldlib/gall/gctype.h create mode 100644 goldlib/gall/gcurses.h create mode 100644 goldlib/gall/gdbgerr.cpp create mode 100644 goldlib/gall/gdbgerr.h create mode 100644 goldlib/gall/gdbgexit.cpp create mode 100644 goldlib/gall/gdbgtrk.cpp create mode 100644 goldlib/gall/gdbgtrk.h create mode 100644 goldlib/gall/gdefs.h create mode 100644 goldlib/gall/gdirposx.cpp create mode 100644 goldlib/gall/gdirposx.h create mode 100644 goldlib/gall/geval.cpp create mode 100644 goldlib/gall/geval.h create mode 100644 goldlib/gall/gevalhum.cpp create mode 100644 goldlib/gall/gevalrpn.cpp create mode 100644 goldlib/gall/gfile.cpp create mode 100644 goldlib/gall/gfile.h create mode 100644 goldlib/gall/gfilport.cpp create mode 100644 goldlib/gall/gfilutil.h create mode 100644 goldlib/gall/gfilutl1.cpp create mode 100644 goldlib/gall/gfilutl2.cpp create mode 100644 goldlib/gall/gftnaddr.cpp create mode 100644 goldlib/gall/gftnall.h create mode 100644 goldlib/gall/gftnnl.cpp create mode 100644 goldlib/gall/gftnnl.h create mode 100644 goldlib/gall/gftnnlfd.cpp create mode 100644 goldlib/gall/gftnnlfd.h create mode 100644 goldlib/gall/gftnnlfu.cpp create mode 100644 goldlib/gall/gftnnlfu.h create mode 100644 goldlib/gall/gftnnlge.cpp create mode 100644 goldlib/gall/gftnnlge.h create mode 100644 goldlib/gall/gftnnlv7.cpp create mode 100644 goldlib/gall/gftnnlv7.h create mode 100644 goldlib/gall/gfuzzy.cpp create mode 100644 goldlib/gall/gfuzzy.h create mode 100644 goldlib/gall/ghdrmime.cpp create mode 100644 goldlib/gall/ghdrmime.h create mode 100644 goldlib/gall/gkbdbase.cpp create mode 100644 goldlib/gall/gkbdbase.h create mode 100644 goldlib/gall/gkbdcode.h create mode 100644 goldlib/gall/gkbdgetm.cpp create mode 100644 goldlib/gall/gkbdunix.cpp create mode 100644 goldlib/gall/gkbdunix.h create mode 100644 goldlib/gall/gkbdwait.cpp create mode 100644 goldlib/gall/glog.cpp create mode 100644 goldlib/gall/glog.h create mode 100644 goldlib/gall/glzh.cpp create mode 100644 goldlib/gall/glzh.h create mode 100644 goldlib/gall/gmemall.h create mode 100644 goldlib/gall/gmemdbg.cpp create mode 100644 goldlib/gall/gmemdbg.h create mode 100644 goldlib/gall/gmemi86.h create mode 100644 goldlib/gall/gmemutil.cpp create mode 100644 goldlib/gall/gmnubase.h create mode 100644 goldlib/gall/gmoubase.cpp create mode 100644 goldlib/gall/gmoubase.h create mode 100644 goldlib/gall/gmsgattr.cpp create mode 100644 goldlib/gall/gmsgattr.h create mode 100644 goldlib/gall/gprnall.h create mode 100644 goldlib/gall/gprnutil.cpp create mode 100644 goldlib/gall/gregex.cpp create mode 100644 goldlib/gall/gregex.h create mode 100644 goldlib/gall/gsearch.cpp create mode 100644 goldlib/gall/gsearch.h create mode 100644 goldlib/gall/gshare.h create mode 100644 goldlib/gall/gsigunix.cpp create mode 100644 goldlib/gall/gsigunix.h create mode 100644 goldlib/gall/gsnd.cpp create mode 100644 goldlib/gall/gsndall.h create mode 100644 goldlib/gall/gsndsapi.h create mode 100644 goldlib/gall/gsndwrap.cpp create mode 100644 goldlib/gall/gsrchmgr.cpp create mode 100644 goldlib/gall/gsrchmgr.h create mode 100644 goldlib/gall/gstrall.h create mode 100644 goldlib/gall/gstrarr.h create mode 100644 goldlib/gall/gstrbags.cpp create mode 100644 goldlib/gall/gstrbags.h create mode 100644 goldlib/gall/gstrctyp.cpp create mode 100644 goldlib/gall/gstrmail.cpp create mode 100644 goldlib/gall/gstrmail.h create mode 100644 goldlib/gall/gstrname.cpp create mode 100644 goldlib/gall/gstrutil.cpp create mode 100644 goldlib/gall/gtimall.h create mode 100644 goldlib/gall/gtimjuld.cpp create mode 100644 goldlib/gall/gtimutil.cpp create mode 100644 goldlib/gall/gtxtpara.cpp create mode 100644 goldlib/gall/gtxtpara.h create mode 100644 goldlib/gall/gusrbase.cpp create mode 100644 goldlib/gall/gusrbase.h create mode 100644 goldlib/gall/gusrezyc.cpp create mode 100644 goldlib/gall/gusrezyc.h create mode 100644 goldlib/gall/gusrgold.cpp create mode 100644 goldlib/gall/gusrgold.h create mode 100644 goldlib/gall/gusrhuds.cpp create mode 100644 goldlib/gall/gusrhuds.h create mode 100644 goldlib/gall/gusrmax.cpp create mode 100644 goldlib/gall/gusrmax.h create mode 100644 goldlib/gall/gusrpcb.cpp create mode 100644 goldlib/gall/gusrpcb.h create mode 100644 goldlib/gall/gusrra2.cpp create mode 100644 goldlib/gall/gusrra2.h create mode 100644 goldlib/gall/gusrwcat.h create mode 100644 goldlib/gall/gusrxbbs.cpp create mode 100644 goldlib/gall/gusrxbbs.h create mode 100644 goldlib/gall/gutlclip.cpp create mode 100644 goldlib/gall/gutlclip.h create mode 100644 goldlib/gall/gutlcode.cpp create mode 100644 goldlib/gall/gutlcode.h create mode 100644 goldlib/gall/gutldos.cpp create mode 100644 goldlib/gall/gutlgrp.cpp create mode 100644 goldlib/gall/gutlgrp.h create mode 100644 goldlib/gall/gutlmisc.cpp create mode 100644 goldlib/gall/gutlmisc.h create mode 100644 goldlib/gall/gutlmtsk.cpp create mode 100644 goldlib/gall/gutlmtsk.h create mode 100644 goldlib/gall/gutlos.h create mode 100644 goldlib/gall/gutlos2.cpp create mode 100644 goldlib/gall/gutlos2m.cpp create mode 100644 goldlib/gall/gutltag.cpp create mode 100644 goldlib/gall/gutltag.h create mode 100644 goldlib/gall/gutlunix.h create mode 100644 goldlib/gall/gutlvers.cpp create mode 100644 goldlib/gall/gutlwin.cpp create mode 100644 goldlib/gall/gutlwinm.cpp create mode 100644 goldlib/gall/gvidall.h create mode 100644 goldlib/gall/gvidbase.cpp create mode 100644 goldlib/gall/gvidinit.cpp create mode 100644 goldlib/gall/gwildmat.cpp create mode 100644 goldlib/gall/gwildmat.h create mode 100644 goldlib/gall/gwinall.h create mode 100644 goldlib/gall/gwinbase.cpp create mode 100644 goldlib/gall/gwindow.cpp create mode 100644 goldlib/gall/gwindow.h create mode 100644 goldlib/gall/gwinhelp.h create mode 100644 goldlib/gall/gwinhlp1.cpp create mode 100644 goldlib/gall/gwinhlp2.cpp create mode 100644 goldlib/gall/gwininit.cpp create mode 100644 goldlib/gall/gwinline.cpp create mode 100644 goldlib/gall/gwinmenu.cpp create mode 100644 goldlib/gall/gwinmnub.cpp create mode 100644 goldlib/gall/gwinpckf.cpp create mode 100644 goldlib/gall/gwinpcks.cpp create mode 100644 goldlib/gall/gwinpick.cpp create mode 100644 goldlib/gall/gwinpick.h create mode 100644 goldlib/gall/gwinput.h create mode 100644 goldlib/gall/gwinput2.cpp create mode 100644 goldlib/gcfg/Makefile create mode 100644 goldlib/gcfg/gcfg.all create mode 100644 goldlib/gcfg/gedacfg.cpp create mode 100644 goldlib/gcfg/gedacfg.h create mode 100644 goldlib/gcfg/gs_db.h create mode 100644 goldlib/gcfg/gs_ez102.h create mode 100644 goldlib/gcfg/gs_ez110.h create mode 100644 goldlib/gcfg/gs_fd.h create mode 100644 goldlib/gcfg/gs_fech6.h create mode 100644 goldlib/gcfg/gs_fm092.h create mode 100644 goldlib/gcfg/gs_fm10g.h create mode 100644 goldlib/gcfg/gs_fm116.h create mode 100644 goldlib/gcfg/gs_ge120.h create mode 100644 goldlib/gcfg/gs_im160.h create mode 100644 goldlib/gcfg/gs_im175.h create mode 100644 goldlib/gcfg/gs_inter.h create mode 100644 goldlib/gcfg/gs_lo240.h create mode 100644 goldlib/gcfg/gs_max3.h create mode 100644 goldlib/gcfg/gs_opus.h create mode 100644 goldlib/gcfg/gs_pb200.h create mode 100644 goldlib/gcfg/gs_pcb.h create mode 100644 goldlib/gcfg/gs_pop.h create mode 100644 goldlib/gcfg/gs_qbbs.h create mode 100644 goldlib/gcfg/gs_qfrnt.h create mode 100644 goldlib/gcfg/gs_qwk.h create mode 100644 goldlib/gcfg/gs_ra.h create mode 100644 goldlib/gcfg/gs_ra2.h create mode 100644 goldlib/gcfg/gs_recho.h create mode 100644 goldlib/gcfg/gs_sbbs.h create mode 100644 goldlib/gcfg/gs_ts.h create mode 100644 goldlib/gcfg/gs_wmail.h create mode 100644 goldlib/gcfg/gs_wtr.h create mode 100644 goldlib/gcfg/gs_xbbs.h create mode 100644 goldlib/gcfg/gs_xmail.h create mode 100644 goldlib/gcfg/gxareas.cpp create mode 100644 goldlib/gcfg/gxcrash.cpp create mode 100644 goldlib/gcfg/gxdb.cpp create mode 100644 goldlib/gcfg/gxdutch.cpp create mode 100644 goldlib/gcfg/gxezy102.cpp create mode 100644 goldlib/gcfg/gxezy110.cpp create mode 100644 goldlib/gcfg/gxfd.cpp create mode 100644 goldlib/gcfg/gxfecho6.cpp create mode 100644 goldlib/gcfg/gxfidpcb.cpp create mode 100644 goldlib/gcfg/gxfm092.cpp create mode 100644 goldlib/gcfg/gxfm100.cpp create mode 100644 goldlib/gcfg/gxfm116.cpp create mode 100644 goldlib/gcfg/gxgecho.cpp create mode 100644 goldlib/gcfg/gxhpt.cpp create mode 100644 goldlib/gcfg/gximail4.cpp create mode 100644 goldlib/gcfg/gximail5.cpp create mode 100644 goldlib/gcfg/gximail6.cpp create mode 100644 goldlib/gcfg/gxinter.cpp create mode 100644 goldlib/gcfg/gxlora.cpp create mode 100644 goldlib/gcfg/gxmax3.cpp create mode 100644 goldlib/gcfg/gxme2.cpp create mode 100644 goldlib/gcfg/gxopus.cpp create mode 100644 goldlib/gcfg/gxpcb.cpp create mode 100644 goldlib/gcfg/gxportal.cpp create mode 100644 goldlib/gcfg/gxprobrd.cpp create mode 100644 goldlib/gcfg/gxqecho.cpp create mode 100644 goldlib/gcfg/gxqfront.cpp create mode 100644 goldlib/gcfg/gxquick.cpp create mode 100644 goldlib/gcfg/gxra.cpp create mode 100644 goldlib/gcfg/gxraecho.cpp create mode 100644 goldlib/gcfg/gxsquish.cpp create mode 100644 goldlib/gcfg/gxsuper.cpp create mode 100644 goldlib/gcfg/gxtimed.cpp create mode 100644 goldlib/gcfg/gxtmail.cpp create mode 100644 goldlib/gcfg/gxts.cpp create mode 100644 goldlib/gcfg/gxwmail.cpp create mode 100644 goldlib/gcfg/gxwtr.cpp create mode 100644 goldlib/gcfg/gxxbbs.cpp create mode 100644 goldlib/gcfg/gxxmail.cpp create mode 100644 goldlib/glibc/Makefile create mode 100644 goldlib/glibc/config.h create mode 100644 goldlib/glibc/dummy.c create mode 100644 goldlib/glibc/fnmatch.c create mode 100644 goldlib/glibc/fnmatch.h create mode 100644 goldlib/glibc/glibc.all create mode 100644 goldlib/glibc/glob.c create mode 100644 goldlib/glibc/glob.h create mode 100644 goldlib/glibc/regex.c create mode 100644 goldlib/glibc/regex.h create mode 100644 goldlib/gmb3/Makefile create mode 100644 goldlib/gmb3/gmb3.all create mode 100644 goldlib/gmb3/gmo_msg.h create mode 100644 goldlib/gmb3/gmoarea.cpp create mode 100644 goldlib/gmb3/gmoarea.h create mode 100644 goldlib/gmb3/gmoezyc.h create mode 100644 goldlib/gmb3/gmoezyc1.cpp create mode 100644 goldlib/gmb3/gmoezyc2.cpp create mode 100644 goldlib/gmb3/gmoezyc3.cpp create mode 100644 goldlib/gmb3/gmoezyc4.cpp create mode 100644 goldlib/gmb3/gmoezyc5.cpp create mode 100644 goldlib/gmb3/gmofido.h create mode 100644 goldlib/gmb3/gmofido1.cpp create mode 100644 goldlib/gmb3/gmofido2.cpp create mode 100644 goldlib/gmb3/gmofido3.cpp create mode 100644 goldlib/gmb3/gmofido4.cpp create mode 100644 goldlib/gmb3/gmofido5.cpp create mode 100644 goldlib/gmb3/gmohuds.cpp create mode 100644 goldlib/gmb3/gmohuds.h create mode 100644 goldlib/gmb3/gmohuds1.cpp create mode 100644 goldlib/gmb3/gmohuds2.cpp create mode 100644 goldlib/gmb3/gmohuds3.cpp create mode 100644 goldlib/gmb3/gmohuds4.cpp create mode 100644 goldlib/gmb3/gmohuds5.cpp create mode 100644 goldlib/gmb3/gmojamm.h create mode 100644 goldlib/gmb3/gmojamm1.cpp create mode 100644 goldlib/gmb3/gmojamm2.cpp create mode 100644 goldlib/gmb3/gmojamm3.cpp create mode 100644 goldlib/gmb3/gmojamm4.cpp create mode 100644 goldlib/gmb3/gmojamm5.cpp create mode 100644 goldlib/gmb3/gmopcbd.h create mode 100644 goldlib/gmb3/gmopcbd1.cpp create mode 100644 goldlib/gmb3/gmopcbd2.cpp create mode 100644 goldlib/gmb3/gmopcbd3.cpp create mode 100644 goldlib/gmb3/gmopcbd4.cpp create mode 100644 goldlib/gmb3/gmopcbd5.cpp create mode 100644 goldlib/gmb3/gmoprot.h create mode 100644 goldlib/gmb3/gmosmb.h create mode 100644 goldlib/gmb3/gmosmb1.cpp create mode 100644 goldlib/gmb3/gmosmb2.cpp create mode 100644 goldlib/gmb3/gmosmb3.cpp create mode 100644 goldlib/gmb3/gmosqsh.h create mode 100644 goldlib/gmb3/gmosqsh1.cpp create mode 100644 goldlib/gmb3/gmosqsh2.cpp create mode 100644 goldlib/gmb3/gmosqsh3.cpp create mode 100644 goldlib/gmb3/gmosqsh4.cpp create mode 100644 goldlib/gmb3/gmosqsh5.cpp create mode 100644 goldlib/gmb3/gmowcat.h create mode 100644 goldlib/gmb3/gmowcat1.cpp create mode 100644 goldlib/gmb3/gmowcat2.cpp create mode 100644 goldlib/gmb3/gmowcat3.cpp create mode 100644 goldlib/gmb3/gmowcat4.cpp create mode 100644 goldlib/gmb3/gmowcat5.cpp create mode 100644 goldlib/gmb3/gmoxbbs.h create mode 100644 goldlib/gmb3/gmoxbbs1.cpp create mode 100644 goldlib/gmb3/gmoxbbs2.cpp create mode 100644 goldlib/gmb3/gmoxbbs3.cpp create mode 100644 goldlib/gmb3/gmoxbbs4.cpp create mode 100644 goldlib/gmb3/gmoxbbs5.cpp create mode 100644 goldlib/uulib/Makefile create mode 100644 goldlib/uulib/config.h create mode 100644 goldlib/uulib/fptools.c create mode 100644 goldlib/uulib/fptools.h create mode 100644 goldlib/uulib/uucheck.c create mode 100644 goldlib/uulib/uudeview.h create mode 100644 goldlib/uulib/uuencode.c create mode 100644 goldlib/uulib/uuint.h create mode 100644 goldlib/uulib/uulib.all create mode 100644 goldlib/uulib/uulib.c create mode 100644 goldlib/uulib/uunconc.c create mode 100644 goldlib/uulib/uuscan.c create mode 100644 goldlib/uulib/uustring.c create mode 100644 goldlib/uulib/uustring.h create mode 100644 goldlib/uulib/uuutil.c create mode 100644 goldnode/Makefile create mode 100644 goldnode/goldnode.all create mode 100644 goldnode/goldnode.cpp create mode 100644 manuals/gold_ref.tei create mode 100644 manuals/gold_ref.txt create mode 100644 manuals/gold_usr.txt create mode 100644 rddt/Makefile create mode 100644 rddt/rddt.all create mode 100644 rddt/rddt.cpp diff --git a/File_id.diz b/File_id.diz new file mode 100644 index 0000000..b9e5f59 --- /dev/null +++ b/File_id.diz @@ -0,0 +1,6 @@ +GoldED+ 1.1.4.3 [source code] +----------------------------- +GoldED+ is a successor of the +wellknown GoldED mail editor. +----------------------------- +URL: http://asa.i-connect.com diff --git a/GNUmakef.def b/GNUmakef.def new file mode 100644 index 0000000..3ab0309 --- /dev/null +++ b/GNUmakef.def @@ -0,0 +1,63 @@ +# -*- makefile -*- + +ifeq ($(findstring EMX, $(PATH)), EMX) +CC=gcc +AR=ar +PLATFORM=emx +SHELL=bash +EXEEXT=.exe +OBJEXT=.o +LIBEXT=.a +#CC=gcc -Zomf -Zcrtdll +#AR=emxomfar +#PLATFORM=emx +#SHELL=bash +#EXEEXT=.exe +#OBJEXT=.obj +#LIBEXT=.lib +CXX=$(CC) +else +ifneq ($(DJGPP),) +CC=gcc +CXX=gpp +AR=ar +PLATFORM=djg +SHELL=bash +EXEEXT=.exe +OBJEXT=.o +LIBEXT=.a +else +ifeq ($(TERM),cygwin) +CC=gcc -mno-cygwin +CXX=g++ -mno-cygwin +AR=ar +PLATFORM=cyg +SHELL=bash +EXEEXT=.exe +OBJEXT=.o +LIBEXT=.a +else +CC=egcc +CXX=g++ +AR=ar +PLATFORM=lnx +EXEEXT= +OBJEXT=.o +LIBEXT=.a +endif +endif +endif +CFLAGS+=-g -funsigned-char $(INCS) -Wall -Wno-sign-compare -pedantic -O2# -fomit-frame-pointer +LNKFLAGS+=-g +CPPFLAGS+=$(CFLAGS) -fno-exceptions -fno-rtti + +# comment following lines if you dislike ncurses +ifeq ($(PLATFORM),lnx) +CPPFLAGS+=-D__USE_NCURSES__ +STDLIBS+=-lncurses +endif + +BIN=bin +OBJPATH=obj +LIBPATH=lib +DEPPATH=dep diff --git a/GNUmakef.inc b/GNUmakef.inc new file mode 100644 index 0000000..3897d0e --- /dev/null +++ b/GNUmakef.inc @@ -0,0 +1,74 @@ +# -*- makefile -*- + +.PHONY: all clean + +all: $(TARGET) + +include $(TOP)/GNUmakef.def + +FOBJPATH=$(TOP)/$(OBJPATH)/$(PLATFORM)/$(TARGET) +FLIBPATH=$(TOP)/$(LIBPATH)/$(PLATFORM) +FDEPPATH=$(TOP)/$(DEPPATH)/$(PLATFORM) + +.SUFFIXES: .c .cpp .all .rc + +bld$(PLATFORM).inc: $(TARGET).all + @echo making sourcelist + @grep -w $(PLATFORM) $< \ + | sed 's/^\([[:alnum:]_]*\)[ ]*\([[:alnum:]_]*\).*/SOURCES+=\1.\2/g' > $@ + +ifeq ($(FDEPPATH)/dep,$(wildcard $(FDEPPATH)/de?)) +$(FDEPPATH)/$(TARGET)/%.d: %.cpp + @echo making depends for $< + @$(SHELL) -ec '$(CXX) -c -M $(CPPFLAGS) $< \ + | sed '\''s;\($*\)\$(OBJEXT)[ :]*;$(subst /,\/,$(FOBJPATH))\/\1\$(OBJEXT) $(subst /,\/,$@): ;g'\'' > $@' + +$(FDEPPATH)/$(TARGET)/%.d: %.c + @echo making depends for $< + @$(SHELL) -ec '$(CC) -c -M $(CFLAGS) $< \ + | sed '\''s;\($*\)\$(OBJEXT)[ :]*;$(subst /,\/,$(FOBJPATH))\/\1\$(OBJEXT) $(subst /,\/,$@): ;g'\'' > $@' +endif + +$(FOBJPATH)/%$(OBJEXT): %.cpp + @echo building $(basename $<)$(OBJEXT) + @$(CXX) -c $(CPPFLAGS) -o $@ $< + +$(FOBJPATH)/%$(OBJEXT): %.c + @echo building $(basename $<)$(OBJEXT) + @$(CC) -c $(CFLAGS) -o $@ $< + +ifeq ($(PLATFORM),cyg) +$(FOBJPATH)/%$(OBJEXT): %.rc + @echo creating resources + @windres -o $@ $< +endif + +ifeq ($(PLATFORM),emx) +$(FOBJPATH)/%.res: %.rc + @echo creating resources + @rc $(subst -I,-i ,$(INCS)) -x1 -r $< +endif + +SOURCES= +include bld$(PLATFORM).inc +ifeq ($(PLATFORM),cyg) +OBJS=$(addprefix $(FOBJPATH)/,$(patsubst %.rc,%.o,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(filter %.c %.cpp %.rc,$(SOURCES)))))) +else +ifeq ($(PLATFORM),emx) +OBJS=$(addprefix $(FOBJPATH)/,$(patsubst %.rc,%.res,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(filter %.c %.cpp %.rc,$(SOURCES)))))) +else +OBJS=$(addprefix $(FOBJPATH)/,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(filter %.c %.cpp %.rc,$(SOURCES))))) +endif +endif +DEPS=$(addprefix $(FDEPPATH)/$(TARGET)/,$(patsubst %.c,%.d,$(patsubst %.cpp,%.d,$(filter %.c %.cpp,$(SOURCES))))) + +clean: + @echo cleaning... + @rm -f $(OBJS) $(DEPS) bld$(PLATFORM).inc + +ifeq ($(FDEPPATH)/dep,$(wildcard $(FDEPPATH)/de?)) +ifneq ($(DEPS),) +include $(DEPS) +endif +endif + diff --git a/GNUmakef.lib b/GNUmakef.lib new file mode 100644 index 0000000..343f200 --- /dev/null +++ b/GNUmakef.lib @@ -0,0 +1,11 @@ +# -*- makefile -*- + +.PHONY: $(TARGET) + +$(TARGET): $(FLIBPATH)/lib$(TARGET)$(LIBEXT) + +$(FLIBPATH)/lib$(TARGET)$(LIBEXT): $(OBJS) + @echo -n Creating library $(TARGET)... + @$(AR) cru $@ $(FOBJPATH)/*$(OBJEXT) + @ranlib $@ + @echo done diff --git a/GNUmakef.prg b/GNUmakef.prg new file mode 100644 index 0000000..93106e1 --- /dev/null +++ b/GNUmakef.prg @@ -0,0 +1,23 @@ +# -*- makefile -*- + +.PHONY: $(TARGET) $(GLIBS) + +$(TARGET): $(TOP)/$(BIN)/$(SHORTTARGET)$(PLATFORM)$(EXEEXT) + +ifeq ($(PLATFORM),emx) +LIBS=$(addprefix -llib,$(GLIBS)) +else +LIBS=$(addprefix -l,$(GLIBS)) +endif +LIBS+=$(STDLIBS) +FGLIBS=$(addprefix $(FLIBPATH)/lib, $(addsuffix .a, $(GLIBS))) + +$(TOP)/$(BIN)/$(SHORTTARGET)$(PLATFORM)$(EXEEXT): $(OBJS) $(FGLIBS) $(ADDS) + @echo -n Linking $(TARGET)... + @$(CXX) $(LNKFLAGS) -o $@ $(FOBJPATH)/*$(OBJEXT) $(ADDS) $(LIBS) -L$(FLIBPATH) + @echo done + +$(FGLIBS): $(GLIBS) + +$(GLIBS): + @cd $(TOP)/goldlib/$@; $(MAKE); cd `pwd` diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1415123 --- /dev/null +++ b/Makefile @@ -0,0 +1,24 @@ +# -*- makefile -*- + +include GNUmakef.def + +LIBS=gall gcfg gmb3 glibc uulib +EXECUTABLES=golded3 goldnode rddt + +all: + @$(MAKE) dirs + @echo -n >$(DEPPATH)/$(PLATFORM)/dep + @for i in $(foreach dir,$(LIBS),goldlib/$(dir)); do cd $$i && $(MAKE) && cd ../..; done + @for i in $(EXECUTABLES); do cd $$i && $(MAKE) && cd ..; done + +clean: + @rm -f $(DEPPATH)/$(PLATFORM)/dep + @for i in $(foreach dir,$(LIBS),goldlib/$(dir)); do cd $$i && $(MAKE) clean && cd ../..; done + @for i in $(EXECUTABLES); do cd $$i && $(MAKE) clean && cd ..; done + +dirs: + @mkdir -p $(BIN) $(LIBPATH)/$(PLATFORM) + @mkdir -p $(foreach dir,$(LIBS),$(OBJPATH)/$(PLATFORM)/$(dir)) + @mkdir -p $(foreach dir,$(EXECUTABLES),$(OBJPATH)/$(PLATFORM)/$(dir)) + @mkdir -p $(foreach dir,$(LIBS),$(DEPPATH)/$(PLATFORM)/$(dir)) + @mkdir -p $(foreach dir,$(EXECUTABLES),$(DEPPATH)/$(PLATFORM)/$(dir)) diff --git a/cfgs/charset/850_850.chs b/cfgs/charset/850_850.chs new file mode 100644 index 0000000..2630415 --- /dev/null +++ b/cfgs/charset/850_850.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM CP850 to IBM CP850. (no conversion) +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +CP850 ; from set +CP850 ; to set +; +\0 \d128 ; 128 80 latin capital letter c with cedilla +\0 \d129 ; 129 81 latin small letter u with diaeresis +\0 \d130 ; 130 82 latin small letter e with acute +\0 \d131 ; 131 83 latin small letter a with circumflex +\0 \d132 ; 132 84 latin small letter a with diaeresis +\0 \d133 ; 133 85 latin small letter a with grave +\0 \d134 ; 134 86 latin small letter a with ring above +\0 \d135 ; 135 87 latin small letter c with cedilla +\0 \d136 ; 136 88 latin small letter e with circumflex +\0 \d137 ; 137 89 latin small letter e with diaeresis +\0 \d138 ; 138 8A latin small letter e with grave +\0 \d139 ; 139 8B latin small letter i with diaeresis +\0 \d140 ; 140 8C latin small letter i with circumflex +\0 \d141 ; 141 8D latin small letter i with grave +\0 \d142 ; 142 8E latin capital letter a with diaeresis +\0 \d143 ; 143 8F latin capital letter a with ring above +\0 \d144 ; 144 90 latin capital letter e with acute +\0 \d145 ; 145 91 latin small letter ae +\0 \d146 ; 146 92 latin capital letter ae +\0 \d147 ; 147 93 latin small letter o with circumflex +\0 \d148 ; 148 94 latin small letter o with diaeresis +\0 \d149 ; 149 95 latin small letter o with grave +\0 \d150 ; 150 96 latin small letter u with circumflex +\0 \d151 ; 151 97 latin small letter u with grave +\0 \d152 ; 152 98 latin small letter y with diaeresis +\0 \d153 ; 153 99 latin capital letter o with diaeresis +\0 \d154 ; 154 9A latin capital letter u with diaeresis +\0 \d155 ; 155 9B latin small letter o with stroke +\0 \d156 ; 156 9C pound sign +\0 \d157 ; 157 9D latin capital letter o with stroke +\0 \d158 ; 158 9E multiplication sign +\0 \d159 ; 159 9F dutch guilder sign (ibm437 159) +\0 \d160 ; 160 A0 latin small letter a with acute +\0 \d161 ; 161 A1 latin small letter i with acute +\0 \d162 ; 162 A2 latin small letter o with acute +\0 \d163 ; 163 A3 latin small letter u with acute +\0 \d164 ; 164 A4 latin small letter n with tilde +\0 \d165 ; 165 A5 latin capital letter n with tilde +\0 \d166 ; 166 A6 feminine ordinal indicator +\0 \d167 ; 167 A7 masculine ordinal indicator +\0 \d168 ; 168 A8 inverted question mark +\0 \d169 ; 169 A9 registered sign +\0 \d170 ; 170 AA not sign +\0 \d171 ; 171 AB vulgar fraction one half +\0 \d172 ; 172 AC vulgar fraction one quarter +\0 \d173 ; 173 AD inverted exclamation mark +\0 \d174 ; 174 AE left-pointing double angle quotation mark +\0 \d175 ; 175 AF right-pointing double angle quotation mark +\0 \d176 ; 176 B0 light shade +\0 \d177 ; 177 B1 medium shade +\0 \d178 ; 178 B2 dark shade +\0 \d179 ; 179 B3 box drawings light vertical +\0 \d180 ; 180 B4 box drawings light vertical and left +\0 \d181 ; 181 B5 latin capital letter a with acute +\0 \d182 ; 182 B6 latin capital letter a with circumflex +\0 \d183 ; 183 B7 latin capital letter a with grave +\0 \d184 ; 184 B8 copyright sign +\0 \d185 ; 185 B9 box drawings heavy vertical and left +\0 \d186 ; 186 BA box drawings heavy vertical +\0 \d187 ; 187 BB box drawings heavy down and left +\0 \d188 ; 188 BC box drawings heavy up and left +\0 \d189 ; 189 BD cent sign +\0 \d190 ; 190 BE yen sign +\0 \d191 ; 191 BF box drawings light down and left +\0 \d192 ; 192 C0 box drawings light up and right +\0 \d193 ; 193 C1 box drawings light up and horizontal +\0 \d194 ; 194 C2 box drawings light down and horizontal +\0 \d195 ; 195 C3 box drawings light vertical and right +\0 \d196 ; 196 C4 box drawings light horizontal +\0 \d197 ; 197 C5 box drawings light vertical and horizontal +\0 \d198 ; 198 C6 latin small letter a with tilde +\0 \d199 ; 199 C7 latin capital letter a with tilde +\0 \d200 ; 200 C8 box drawings heavy up and right +\0 \d201 ; 201 C9 box drawings heavy down and right +\0 \d202 ; 202 CA box drawings heavy up and horizontal +\0 \d203 ; 203 CB box drawings heavy down and horizontal +\0 \d204 ; 204 CC box drawings heavy vertical and right +\0 \d205 ; 205 CD box drawings heavy horizontal +\0 \d206 ; 206 CE box drawings heavy vertical and horizontal +\0 \d207 ; 207 CF currency sign +\0 \d208 ; 208 D0 latin small letter eth (icelandic) +\0 \d209 ; 209 D1 latin capital letter eth (icelandic) +\0 \d210 ; 210 D2 latin capital letter e with circumflex +\0 \d211 ; 211 D3 latin capital letter e with diaeresis +\0 \d212 ; 212 D4 latin capital letter e with grave +\0 \d213 ; 213 D5 latin small letter i dotless +\0 \d214 ; 214 D6 latin capital letter i with acute +\0 \d215 ; 215 D7 latin capital letter i with circumflex +\0 \d216 ; 216 D8 latin capital letter i with diaeresis +\0 \d217 ; 217 D9 box drawings light up and left +\0 \d218 ; 218 DA box drawings light down and right +\0 \d219 ; 219 DB full block +\0 \d220 ; 220 DC lower half block +\0 \d221 ; 221 DD broken bar +\0 \d222 ; 222 DE latin capital letter i with grave +\0 \d223 ; 223 DF upper half block +\0 \d224 ; 224 E0 latin capital letter o with acute +\0 \d225 ; 225 E1 latin small letter sharp s (german) +\0 \d226 ; 226 E2 latin capital letter o with circumflex +\0 \d227 ; 227 E3 latin capital letter o with grave +\0 \d228 ; 228 E4 latin small letter o with tilde +\0 \d229 ; 229 E5 latin capital letter o with tilde +\0 \d230 ; 230 E6 greek small letter mu +\0 \d231 ; 231 E7 latin capital letter thorn (icelandic) +\0 \d232 ; 232 E8 latin small letter thorn (icelandic) +\0 \d233 ; 233 E9 latin capital letter u with acute +\0 \d234 ; 234 EA latin capital letter u with circumflex +\0 \d235 ; 235 EB latin capital letter u with grave +\0 \d236 ; 236 EC latin small letter y with acute +\0 \d237 ; 237 ED latin capital letter y with acute +\0 \d238 ; 238 EE em dash +\0 \d239 ; 239 EF acute accent +\0 \d240 ; 240 F0 soft hyphen +\0 \d241 ; 241 F1 plus-minus sign +\0 \d242 ; 242 F2 left right double arrow +\0 \d243 ; 243 F3 vulgar fraction three quarters +\0 \d244 ; 244 F4 pilcrow sign +\0 \d245 ; 245 F5 section sign +\0 \d246 ; 246 F6 division sign +\0 \d247 ; 247 F7 ogonek +\0 \d248 ; 248 F8 degree sign +\0 \d249 ; 249 F9 diaeresis +\0 \d250 ; 250 FA dot above +\0 \d251 ; 251 FB superscript one +\0 \d252 ; 252 FC superscript three +\0 \d253 ; 253 FD superscript two +\0 \d254 ; 254 FE black square +\0 \d255 ; 255 FF no-break space +END diff --git a/cfgs/charset/850_asc.chs b/cfgs/charset/850_asc.chs new file mode 100644 index 0000000..8dfba51 --- /dev/null +++ b/cfgs/charset/850_asc.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM CP850 characters to ASCII. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +CP850 ; from set +ASCII ; to set +; +\0 C ; 128 80 latin capital letter c with cedilla +u e ; 129 81 latin small letter u with diaeresis +\0 e ; 130 82 latin small letter e with acute +\0 a ; 131 83 latin small letter a with circumflex +a e ; 132 84 latin small letter a with diaeresis +\0 a ; 133 85 latin small letter a with grave +a a ; 134 86 latin small letter a with ring above +\0 c ; 135 87 latin small letter c with cedilla +\0 e ; 136 88 latin small letter e with circumflex +e e ; 137 89 latin small letter e with diaeresis +\0 e ; 138 8A latin small letter e with grave +i e ; 139 8B latin small letter i with diaeresis +\0 i ; 140 8C latin small letter i with circumflex +\0 i ; 141 8D latin small letter i with grave +A e ; 142 8E latin capital letter a with diaeresis +A a ; 143 8F latin capital letter a with ring above +\0 E ; 144 90 latin capital letter e with acute +a e ; 145 91 latin small letter ae +A E ; 146 92 latin capital letter ae +\0 o ; 147 93 latin small letter o with circumflex +o e ; 148 94 latin small letter o with diaeresis +\0 o ; 149 95 latin small letter o with grave +\0 u ; 150 96 latin small letter u with circumflex +\0 u ; 151 97 latin small letter u with grave +y e ; 152 98 latin small letter y with diaeresis +O e ; 153 99 latin capital letter o with diaeresis +U e ; 154 9A latin capital letter u with diaeresis +o e ; 155 9B latin small letter o with stroke +\0 # ; 156 9C pound sign +O e ; 157 9D latin capital letter o with stroke +\0 x ; 158 9E multiplication sign +F l ; 159 9F dutch guilder sign (ibm437 159) +\0 a ; 160 A0 latin small letter a with acute +\0 i ; 161 A1 latin small letter i with acute +\0 o ; 162 A2 latin small letter o with acute +\0 u ; 163 A3 latin small letter u with acute +\0 n ; 164 A4 latin small letter n with tilde +\0 N ; 165 A5 latin capital letter n with tilde +\0 a ; 166 A6 feminine ordinal indicator +\0 o ; 167 A7 masculine ordinal indicator +\0 ? ; 168 A8 inverted question mark +( R ) ; 169 A9 registered sign +\0 ! ; 170 AA not sign +1 / 2 ; 171 AB vulgar fraction one half +1 / 4 ; 172 AC vulgar fraction one quarter +\0 1 ; 173 AD inverted exclamation mark +< < ; 174 AE left-pointing double angle quotation mark +> > ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left +\0 A ; 181 B5 latin capital letter a with acute +\0 A ; 182 B6 latin capital letter a with circumflex +\0 A ; 183 B7 latin capital letter a with grave +( C ) ; 184 B8 copyright sign +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left +C t ; 189 BD cent sign +Y e ; 190 BE yen sign +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal +\0 a ; 198 C6 latin small letter a with tilde +\0 A ; 199 C7 latin capital letter a with tilde +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal +C u ; 207 CF currency sign +\0 d ; 208 D0 latin small letter eth (icelandic) +\0 D ; 209 D1 latin capital letter eth (icelandic) +\0 E ; 210 D2 latin capital letter e with circumflex +\0 E ; 211 D3 latin capital letter e with diaeresis +\0 E ; 212 D4 latin capital letter e with grave +\0 i ; 213 D5 latin small letter i dotless +\0 I ; 214 D6 latin capital letter i with acute +\0 I ; 215 D7 latin capital letter i with circumflex +\0 I ; 216 D8 latin capital letter i with diaeresis +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 - ; 220 DC lower half block +\0 | ; 221 DD broken bar +\0 I ; 222 DE latin capital letter i with grave +\0 - ; 223 DF upper half block +\0 O ; 224 E0 latin capital letter o with acute +s s ; 225 E1 latin small letter sharp s (german) +\0 O ; 226 E2 latin capital letter o with circumflex +\0 O ; 227 E3 latin capital letter o with grave +\0 o ; 228 E4 latin small letter o with tilde +\0 O ; 229 E5 latin capital letter o with tilde +m u ; 230 E6 greek small letter mu +T h ; 231 E7 latin capital letter thorn (icelandic) +t h ; 232 E8 latin small letter thorn (icelandic) +\0 U ; 233 E9 latin capital letter u with acute +\0 U ; 234 EA latin capital letter u with circumflex +\0 U ; 235 EB latin capital letter u with grave +\0 y ; 236 EC latin small letter y with acute +\0 Y ; 237 ED latin capital letter y with acute +\0 - ; 238 EE em dash +\0 ' ; 239 EF acute accent +\0 - ; 240 F0 soft hyphen ++ - ; 241 F1 plus-minus sign += = ; 242 F2 left right double arrow +3 / 4 ; 243 F3 vulgar fraction three quarters +\0 P ; 244 F4 pilcrow sign +\0 S ; 245 F5 section sign +\0 / ; 246 F6 division sign +\0 , ; 247 F7 ogonek +\0 ' ; 248 F8 degree sign +\0 " ; 249 F9 diaeresis +\0 . ; 250 FA dot above +^ 1 ; 251 FB superscript one +^ 3 ; 252 FC superscript three +^ 2 ; 253 FD superscript two +\0 * ; 254 FE black square +\0 \d32 ; 255 FF no-break space +END diff --git a/cfgs/charset/850_iqp.chs b/cfgs/charset/850_iqp.chs new file mode 100644 index 0000000..c967948 --- /dev/null +++ b/cfgs/charset/850_iqp.chs @@ -0,0 +1,289 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM CP850 characters to ISO 8859-1 q-p characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +100000 ; ID number (when >65535, all 255 chars will be translated) +0 ; version number +; +2 ; level number +; +CP850 ; from set +LATIN1QP ; to set +; ; dec hx description +\0 \d0 ; 0 00 +\0 \d1 ; 1 01 +\0 \d2 ; 2 02 +\0 \d3 ; 3 03 +\0 \d4 ; 4 04 +\0 \d5 ; 5 05 +\0 \d6 ; 6 06 +\0 \d7 ; 7 07 +\0 \d8 ; 8 08 +\0 \d9 ; 9 09 +\0 \d10 ; 10 0A +\0 \d11 ; 11 0B +\0 \d12 ; 12 0C +\0 \d13 ; 13 0D +\0 \d14 ; 14 0E +\0 \d15 ; 15 0F +\0 \d16 ; 16 10 +\0 \d17 ; 17 11 +\0 \d18 ; 18 12 +\0 \d19 ; 19 13 +\0 \d20 ; 20 14 +\0 \d21 ; 21 15 +\0 \d22 ; 22 16 +\0 \d23 ; 23 17 +\0 \d24 ; 24 18 +\0 \d25 ; 25 19 +\0 \d26 ; 26 1A +\0 \d27 ; 27 1B +\0 \d28 ; 28 1C +\0 \d29 ; 29 1D +\0 \d30 ; 30 1E +\0 \d31 ; 31 1F +\0 \d32 ; 32 20 +\0 \d33 ; 33 21 +\0 \d34 ; 34 22 +\0 \d35 ; 35 23 +\0 \d36 ; 36 24 +\0 \d37 ; 37 25 +\0 \d38 ; 38 26 +\0 \d39 ; 39 27 +\0 \d40 ; 40 28 +\0 \d41 ; 41 29 +\0 \d42 ; 42 2A +\0 \d43 ; 43 2B +\0 \d44 ; 44 2C +\0 \d45 ; 45 2D +\0 \d46 ; 46 2E +\0 \d47 ; 47 2F +\0 \d48 ; 48 30 +\0 \d49 ; 49 31 +\0 \d50 ; 50 32 +\0 \d51 ; 51 33 +\0 \d52 ; 52 34 +\0 \d53 ; 53 35 +\0 \d54 ; 54 36 +\0 \d55 ; 55 37 +\0 \d56 ; 56 38 +\0 \d57 ; 57 39 +\0 \d58 ; 58 3A +\0 \d59 ; 59 3B +\0 \d60 ; 60 3C += 3 D ; 61 3D +\0 \d62 ; 62 3E +\0 \d63 ; 63 3F +\0 \d64 ; 64 40 +\0 \d65 ; 65 41 +\0 \d66 ; 66 42 +\0 \d67 ; 67 43 +\0 \d68 ; 68 44 +\0 \d69 ; 69 45 +\0 \d70 ; 70 46 +\0 \d71 ; 71 47 +\0 \d72 ; 72 48 +\0 \d73 ; 73 49 +\0 \d74 ; 74 4A +\0 \d75 ; 75 4B +\0 \d76 ; 76 4C +\0 \d77 ; 77 4D +\0 \d78 ; 78 4E +\0 \d79 ; 79 4F +\0 \d80 ; 80 50 +\0 \d81 ; 81 51 +\0 \d82 ; 82 52 +\0 \d83 ; 83 53 +\0 \d84 ; 84 54 +\0 \d85 ; 85 55 +\0 \d86 ; 86 56 +\0 \d87 ; 87 57 +\0 \d88 ; 88 58 +\0 \d89 ; 89 59 +\0 \d90 ; 90 5A +\0 \d91 ; 91 5B +\0 \d92 ; 92 5C +\0 \d93 ; 93 5D +\0 \d94 ; 94 5E +\0 \d95 ; 95 5F +\0 \d96 ; 96 60 +\0 \d97 ; 97 61 +\0 \d98 ; 98 62 +\0 \d99 ; 99 63 +\0 \d100 ; 100 64 +\0 \d101 ; 101 65 +\0 \d102 ; 102 66 +\0 \d103 ; 103 67 +\0 \d104 ; 104 68 +\0 \d105 ; 105 69 +\0 \d106 ; 106 6A +\0 \d107 ; 107 6B +\0 \d108 ; 108 6C +\0 \d109 ; 109 6D +\0 \d110 ; 110 6E +\0 \d111 ; 111 6F +\0 \d112 ; 112 70 +\0 \d113 ; 113 71 +\0 \d114 ; 114 72 +\0 \d115 ; 115 73 +\0 \d116 ; 116 74 +\0 \d117 ; 117 75 +\0 \d118 ; 118 76 +\0 \d119 ; 119 77 +\0 \d120 ; 120 78 +\0 \d121 ; 121 79 +\0 \d122 ; 122 7A +\0 \d123 ; 123 7B +\0 \d124 ; 124 7C +\0 \d125 ; 125 7D +\0 \d126 ; 126 7E +\0 \d127 ; 127 7F += C 7 ; 128 80 latin capital letter c with cedilla += F C ; 129 81 latin small letter u with diaeresis += E 9 ; 130 82 latin small letter e with acute += E 2 ; 131 83 latin small letter a with circumflex += E 4 ; 132 84 latin small letter a with diaeresis += E 0 ; 133 85 latin small letter a with grave += E 5 ; 134 86 latin small letter a with ring above += E 7 ; 135 87 latin small letter c with cedilla += E A ; 136 88 latin small letter e with circumflex += E B ; 137 89 latin small letter e with diaeresis += E 8 ; 138 8A latin small letter e with grave += E F ; 139 8B latin small letter i with diaeresis += E E ; 140 8C latin small letter i with circumflex += E C ; 141 8D latin small letter i with grave += C 4 ; 142 8E latin capital letter a with diaeresis += C 5 ; 143 8F latin capital letter a with ring above += C 9 ; 144 90 latin capital letter e with acute += E 6 ; 145 91 latin small letter ae += C 6 ; 146 92 latin capital letter ae += F 4 ; 147 93 latin small letter o with circumflex += F 6 ; 148 94 latin small letter o with diaeresis += F 3 ; 149 95 latin small letter o with grave += D B ; 150 96 latin small letter u with circumflex += D 9 ; 151 97 latin small letter u with grave += F F ; 152 98 latin small letter y with diaeresis += D 6 ; 153 99 latin capital letter o with diaeresis += D C ; 154 9A latin capital letter u with diaeresis += F 8 ; 155 9B latin small letter o with stroke += A 3 ; 156 9C pound sign += D 8 ; 157 9D latin capital letter o with stroke += D 7 ; 158 9E multiplication sign +F l ; 159 9F dutch guilder sign (ibm437 159) += E 1 ; 160 A0 latin small letter a with acute += C C ; 161 A1 latin small letter i with acute += F 2 ; 162 A2 latin small letter o with acute += F 9 ; 163 A3 latin small letter u with acute += F 1 ; 164 A4 latin small letter n with tilde += D 1 ; 165 A5 latin capital letter n with tilde += A A ; 166 A6 feminine ordinal indicator += B A ; 167 A7 masculine ordinal indicator += B F ; 168 A8 inverted question mark += A E ; 169 A9 registered sign += A C ; 170 AA not sign += B D ; 171 AB vulgar fraction one half += B C ; 172 AC vulgar fraction one quarter += A 1 ; 173 AD inverted exclamation mark += A B ; 174 AE left-pointing double angle quotation mark += B B ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left += C 1 ; 181 B5 latin capital letter a with acute += C 2 ; 182 B6 latin capital letter a with circumflex += C 0 ; 183 B7 latin capital letter a with grave += A 9 ; 184 B8 copyright sign +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left += A 2 ; 189 BD cent sign += A E ; 190 BE yen sign +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal += E 3 ; 198 C6 latin small letter a with tilde += C 3 ; 199 C7 latin capital letter a with tilde +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal += A 4 ; 207 CF currency sign += F 0 ; 208 D0 latin small letter eth (icelandic) += D 0 ; 209 D1 latin capital letter eth (icelandic) += C A ; 210 D2 latin capital letter e with circumflex += C B ; 211 D3 latin capital letter e with diaeresis += D 4 ; 212 D4 latin capital letter e with grave +\0 i ; 213 D5 latin small letter i dotless += C D ; 214 D6 latin capital letter i with acute += C E ; 215 D7 latin capital letter i with circumflex += C F ; 216 D8 latin capital letter i with diaeresis +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 # ; 220 DC lower half block += A 6 ; 221 DD broken bar += C C ; 222 DE latin capital letter i with grave +\0 # ; 223 DF upper half block += D 3 ; 224 E0 latin capital letter o with acute += D F ; 225 E1 latin small letter sharp s (german) += D 4 ; 226 E2 latin capital letter o with circumflex += D 2 ; 227 E3 latin capital letter o with grave += F 5 ; 228 E4 latin small letter o with tilde += D 5 ; 229 E5 latin capital letter o with tilde += B 5 ; 230 E6 greek small letter mu += D E ; 231 E7 latin capital letter thorn (icelandic) += F E ; 232 E8 latin small letter thorn (icelandic) += D A ; 233 E9 latin capital letter u with acute += D B ; 234 EA latin capital letter u with circumflex += D 9 ; 235 EB latin capital letter u with grave += F D ; 236 EC latin small letter y with acute += D D ; 237 ED latin capital letter y with acute += A F ; 238 EE em dash += B 4 ; 239 EF acute accent += A D ; 240 F0 soft hyphen += B 1 ; 241 F1 plus-minus sign += = ; 242 F2 left right double arrow += B E ; 243 F3 vulgar fraction three quarters += B 6 ; 244 F4 pilcrow sign += A 7 ; 245 F5 section sign += F 7 ; 246 F6 division sign += B 8 ; 247 F7 ogonek += B 0 ; 248 F8 degree sign += A 8 ; 249 F9 diaeresis +\0 . ; 250 FA dot above += B 9 ; 251 FB superscript one += B 3 ; 252 FC superscript three += B 2 ; 253 FD superscript two += B 7 ; 254 FE black square += A 0 ; 255 FF no-break space +END diff --git a/cfgs/charset/850_iso.chs b/cfgs/charset/850_iso.chs new file mode 100644 index 0000000..f92cd60 --- /dev/null +++ b/cfgs/charset/850_iso.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM CP850 characters to ISO 8859-1 characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +CP850 ; from set +LATIN-1 ; to set +; ; dec hx description +\0 \xC7 ; 128 80 latin capital letter c with cedilla +\0 \xFC ; 129 81 latin small letter u with diaeresis +\0 \xE9 ; 130 82 latin small letter e with acute +\0 \xE2 ; 131 83 latin small letter a with circumflex +\0 \xE4 ; 132 84 latin small letter a with diaeresis +\0 \xE0 ; 133 85 latin small letter a with grave +\0 \xE5 ; 134 86 latin small letter a with ring above +\0 \xE7 ; 135 87 latin small letter c with cedilla +\0 \xEA ; 136 88 latin small letter e with circumflex +\0 \xEB ; 137 89 latin small letter e with diaeresis +\0 \xE8 ; 138 8A latin small letter e with grave +\0 \xEF ; 139 8B latin small letter i with diaeresis +\0 \xEE ; 140 8C latin small letter i with circumflex +\0 \xEC ; 141 8D latin small letter i with grave +\0 \xC4 ; 142 8E latin capital letter a with diaeresis +\0 \xC5 ; 143 8F latin capital letter a with ring above +\0 \xC9 ; 144 90 latin capital letter e with acute +\0 \xE6 ; 145 91 latin small letter ae +\0 \xC6 ; 146 92 latin capital letter ae +\0 \xF4 ; 147 93 latin small letter o with circumflex +\0 \xF6 ; 148 94 latin small letter o with diaeresis +\0 \xF3 ; 149 95 latin small letter o with grave +\0 \xDB ; 150 96 latin small letter u with circumflex +\0 \xD9 ; 151 97 latin small letter u with grave +\0 \xFF ; 152 98 latin small letter y with diaeresis +\0 \xD6 ; 153 99 latin capital letter o with diaeresis +\0 \xDC ; 154 9A latin capital letter u with diaeresis +\0 \xF8 ; 155 9B latin small letter o with stroke +\0 \xA3 ; 156 9C pound sign +\0 \xD8 ; 157 9D latin capital letter o with stroke +\0 \xD7 ; 158 9E multiplication sign +F l ; 159 9F dutch guilder sign (ibm437 159) +\0 \xE1 ; 160 A0 latin small letter a with acute +\0 \xCC ; 161 A1 latin small letter i with acute +\0 \xF2 ; 162 A2 latin small letter o with acute +\0 \xF9 ; 163 A3 latin small letter u with acute +\0 \xF1 ; 164 A4 latin small letter n with tilde +\0 \xD1 ; 165 A5 latin capital letter n with tilde +\0 \xAA ; 166 A6 feminine ordinal indicator +\0 \xBA ; 167 A7 masculine ordinal indicator +\0 \xBF ; 168 A8 inverted question mark +\0 \xAE ; 169 A9 registered sign +\0 \xAC ; 170 AA not sign +\0 \xBD ; 171 AB vulgar fraction one half +\0 \xBC ; 172 AC vulgar fraction one quarter +\0 \xA1 ; 173 AD inverted exclamation mark +\0 \xAB ; 174 AE left-pointing double angle quotation mark +\0 \xBB ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left +\0 \xC1 ; 181 B5 latin capital letter a with acute +\0 \xC2 ; 182 B6 latin capital letter a with circumflex +\0 \xC0 ; 183 B7 latin capital letter a with grave +\0 \xA9 ; 184 B8 copyright sign +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left +\0 \xA2 ; 189 BD cent sign +\0 \xAE ; 190 BE yen sign +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal +\0 \xE3 ; 198 C6 latin small letter a with tilde +\0 \xC3 ; 199 C7 latin capital letter a with tilde +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal +\0 \xA4 ; 207 CF currency sign +\0 \xF0 ; 208 D0 latin small letter eth (icelandic) +\0 \xD0 ; 209 D1 latin capital letter eth (icelandic) +\0 \xCA ; 210 D2 latin capital letter e with circumflex +\0 \xCB ; 211 D3 latin capital letter e with diaeresis +\0 \xD4 ; 212 D4 latin capital letter e with grave +\0 i ; 213 D5 latin small letter i dotless +\0 \xCD ; 214 D6 latin capital letter i with acute +\0 \xCE ; 215 D7 latin capital letter i with circumflex +\0 \xCF ; 216 D8 latin capital letter i with diaeresis +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 # ; 220 DC lower half block +\0 \xA6 ; 221 DD broken bar +\0 \xCC ; 222 DE latin capital letter i with grave +\0 # ; 223 DF upper half block +\0 \xD3 ; 224 E0 latin capital letter o with acute +\0 \xDF ; 225 E1 latin small letter sharp s (german) +\0 \xD4 ; 226 E2 latin capital letter o with circumflex +\0 \xD2 ; 227 E3 latin capital letter o with grave +\0 \xF5 ; 228 E4 latin small letter o with tilde +\0 \xD5 ; 229 E5 latin capital letter o with tilde +\0 \xB5 ; 230 E6 greek small letter mu +\0 \xDE ; 231 E7 latin capital letter thorn (icelandic) +\0 \xFE ; 232 E8 latin small letter thorn (icelandic) +\0 \xDA ; 233 E9 latin capital letter u with acute +\0 \xDB ; 234 EA latin capital letter u with circumflex +\0 \xD9 ; 235 EB latin capital letter u with grave +\0 \xFD ; 236 EC latin small letter y with acute +\0 \xDD ; 237 ED latin capital letter y with acute +\0 \xAF ; 238 EE em dash +\0 \xB4 ; 239 EF acute accent +\0 \xAD ; 240 F0 soft hyphen +\0 \xB1 ; 241 F1 plus-minus sign += = ; 242 F2 left right double arrow +\0 \xBE ; 243 F3 vulgar fraction three quarters +\0 \xB6 ; 244 F4 pilcrow sign +\0 \xA7 ; 245 F5 section sign +\0 \xF7 ; 246 F6 division sign +\0 \xB8 ; 247 F7 ogonek +\0 \xB0 ; 248 F8 degree sign +\0 \xA8 ; 249 F9 diaeresis +\0 . ; 250 FA dot above +\0 \xB9 ; 251 FB superscript one +\0 \xB3 ; 252 FC superscript three +\0 \xB2 ; 253 FD superscript two +\0 \xB7 ; 254 FE black square +\0 \xA0 ; 255 FF no-break space +END diff --git a/cfgs/charset/can_asc.chs b/cfgs/charset/can_asc.chs new file mode 100644 index 0000000..aad11fa --- /dev/null +++ b/cfgs/charset/can_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Canadian set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +CANADIAN ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 a ; at -> a grave +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 a ; bracket left -> a circumflex +\0 c ; backslash -> c cedilla +\0 e ; bracket right -> e circumflex +\0 i ; circum -> i circumflex +\0 _ ; underscore +\0 o ; quote left -> o circumflex +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 e ; brace left -> e acute +\0 u ; bar -> u grave +\0 e ; brace right -> e grave +\0 u ; tilde -> u circumflex +\0 \x7F ; DEL +END diff --git a/cfgs/charset/can_ibm.chs b/cfgs/charset/can_ibm.chs new file mode 100644 index 0000000..8ff121a --- /dev/null +++ b/cfgs/charset/can_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Canadian set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +CANADIAN ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x85 ; at -> a grave +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x83 ; bracket left -> a circumflex +\0 \x87 ; backslash -> c cedilla +\0 \x88 ; bracket right -> e circumflex +\0 \x8C ; circum -> i circumflex +\0 _ ; underscore +\0 \x93 ; quote left -> o circumflex +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x82 ; brace left -> e acute +\0 \x97 ; bar -> u grave +\0 \x8A ; brace right -> e grave +\0 \x96 ; tilde -> u circumflex +\0 \x7F ; DEL +END diff --git a/cfgs/charset/cmp_ibm.esc b/cfgs/charset/cmp_ibm.esc new file mode 100644 index 0000000..7a062bd --- /dev/null +++ b/cfgs/charset/cmp_ibm.esc @@ -0,0 +1,70 @@ +; -------------------------------------------------------------------- +; Escaped Characters Table for GoldED 2.30. +; Based on IBM Code Page 437 with additions for CP850 and 865. +; -------------------------------------------------------------------- +; Composed Characters Table, Andre van de Wijdeven (2:500/131). +; -------------------------------------------------------------------- +IBMPC ; Map codes to charset. +; -------------------------------------------------------------------- +!! \d173 ; Inverted Exclamation Mark +'2 \d171 ; Half +'4 \d172 ; Quarter ++- \d241 ; Plusminus +,C \d128 ; C Cedilla +,c \d135 ; c Cedilla +<< \d174 ; Left Double Guillemet +<= \d243 ; Smaller equals +== \d240 ; Equivalence +>= \d242 ; Greater equals +>> \d175 ; Right Double Guillemet +?? \d168 ; Inverted Question Mark +A" \d142 ; A Umlaut +A* \d143 ; A Ring +AA \d143 ; A Ring (Nordic digraph version) +AE \d146 ; AE Digraph +Ct \d155 ; Dollarcent [CP437] +E' \d144 ; E Acute +Fl \d159 ; Florin (Guilder) +N~ \d165 ; N Tilde +O" \d153 ; O Umlaut +O/ \d157 ; O Slash [CP850,865] +OE \d157 ; OE Digraph (O Slash) [CP850,865] +Pd \d156 ; Pound Sterling +Pt \d158 ; Pesetas +U" \d154 ; U Umlaut +Yn \d157 ; Yen [CP437] +^2 \d253 ; To the second power +^n \d252 ; To the n'th power +a" \d132 ; a Umlaut +a' \d160 ; a Acute +a* \d134 ; a Ring +a^ \d131 ; a Caret +a_ \d166 ; Feminine Spanish Ordinal +a` \d133 ; a Grave +aa \d134 ; a Ring (Nordic digraph version) +ae \d145 ; ae Digraph +e" \d137 ; e Umlaut +e' \d130 ; e Acute +e^ \d136 ; e Caret +e` \d138 ; e Grave +i" \d139 ; i Umlaut +i' \d161 ; i Acute +i^ \d140 ; i Caret +i` \d141 ; i Grave +n~ \d164 ; n Tilde +o" \d148 ; o Umlaut +o' \d162 ; o Acute +o/ \d155 ; o Slash [CP850,865] +o^ \d147 ; o Caret +o_ \d167 ; Masculine Spanish Ordinal +o` \d149 ; o Grave +oe \d155 ; oe Digraph (o Slash) [CP850,865] +pi \d227 ; Pi (math symbol) +ss \d225 ; German double s (or Beta) +u" \d129 ; u Umlaut +u' \d163 ; u Acute +u^ \d150 ; u Caret +u` \d151 ; u Grave +y" \d152 ; dotted y +~= \d247 ; approximate equivalence +; -------------------------------------------------------------------- diff --git a/cfgs/charset/dut_asc.chs b/cfgs/charset/dut_asc.chs new file mode 100644 index 0000000..631b62a --- /dev/null +++ b/cfgs/charset/dut_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Dutch set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +DUTCH ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\d1 ? ; at -> 3/4 +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 y ; bracket left -> y dieresis +. 5 ; backslash -> 1/2 +\0 | ; bracket right -> | +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\d1 ? ; brace left -> 1/4 +f l ; bar -> florin +\d1 ? ; brace right -> dieresis +\0 ` ; tilde -> grave +\0 \x7F ; DEL +END diff --git a/cfgs/charset/dut_ibm.chs b/cfgs/charset/dut_ibm.chs new file mode 100644 index 0000000..205edc5 --- /dev/null +++ b/cfgs/charset/dut_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Dutch set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +DUTCH ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 \x9C ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\d1 ? ; at -> 3/4 +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x98 ; bracket left -> y dieresis +\0 \xAB ; backslash -> 1/2 +\0 | ; bracket right -> | +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \xAC ; brace left -> 1/4 +\0 \x9F ; bar -> florin +\d1 ? ; brace right -> dieresis +\0 ` ; tilde -> grave +\0 \x7F ; DEL +END diff --git a/cfgs/charset/fin_asc.chs b/cfgs/charset/fin_asc.chs new file mode 100644 index 0000000..6fde381 --- /dev/null +++ b/cfgs/charset/fin_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Finnish set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +FINNISH ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 A ; bracket left -> A dieresis +\0 O ; backslash -> O dieresis +\0 A ; bracket right -> A ring +\0 U ; circum -> U dieresis +\0 _ ; underscore +\0 e ; quote left -> e acute +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a dieresis +\0 o ; bar -> o dieresis +\0 a ; brace right -> a ring +\0 u ; tilde -> u dieresis +\0 \x7F ; DEL +END diff --git a/cfgs/charset/fin_ibm.chs b/cfgs/charset/fin_ibm.chs new file mode 100644 index 0000000..9c6b7bb --- /dev/null +++ b/cfgs/charset/fin_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Finnish set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +FINNISH ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x8E ; bracket left -> A dieresis +\0 \x99 ; backslash -> O dieresis +\0 \x8F ; bracket right -> A ring +\0 \x9A ; circum -> U dieresis +\0 _ ; underscore +\0 \x82 ; quote left -> e acute +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x84 ; brace left -> a dieresis +\0 \x94 ; bar -> o dieresis +\0 \x86 ; brace right -> a ring +\0 \x81 ; tilde -> u dieresis +\0 \x7F ; DEL +END diff --git a/cfgs/charset/frn_asc.chs b/cfgs/charset/frn_asc.chs new file mode 100644 index 0000000..6354a1c --- /dev/null +++ b/cfgs/charset/frn_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the French set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +FRENCH ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 a ; at -> a grave +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 o ; bracket left -> ring / degree +\0 c ; backslash -> c cedilla +\0 S ; bracket right -> section +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 e ; brace left -> e acute +\0 u ; bar -> u grave +\0 e ; brace right -> e grave +\d1 ? ; tilde -> dieresis +\0 \x7F ; DEL +END diff --git a/cfgs/charset/frn_ibm.chs b/cfgs/charset/frn_ibm.chs new file mode 100644 index 0000000..823595f --- /dev/null +++ b/cfgs/charset/frn_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the French set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +FRENCH ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 \x9C ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x85 ; at -> a grave +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \xF8 ; bracket left -> ring / degree +\0 \x87 ; backslash -> c cedilla +\0 \x15 ; bracket right -> section +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x82 ; brace left -> e acute +\0 \x97 ; bar -> u grave +\0 \x8A ; brace right -> e grave +\d1 ? ; tilde -> dieresis +\0 \x7F ; DEL +END diff --git a/cfgs/charset/ger_asc.chs b/cfgs/charset/ger_asc.chs new file mode 100644 index 0000000..f7b5bb9 --- /dev/null +++ b/cfgs/charset/ger_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the German set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +GERMAN ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclaim +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 S ; at -> section +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 A ; bracket left -> A dieresis +\0 O ; backslash -> O dieresis +\0 U ; bracket right -> U dieresis +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a dieresis +\0 o ; bar -> o dieresis +\0 u ; brace right -> u dieresis +s s ; tilde -> german double s +\0 \x7F ; DEL +END diff --git a/cfgs/charset/ger_ibm.chs b/cfgs/charset/ger_ibm.chs new file mode 100644 index 0000000..d1ab38f --- /dev/null +++ b/cfgs/charset/ger_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the German set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +GERMAN ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclaim +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x15 ; at -> section +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x8E ; bracket left -> A dieresis +\0 \x99 ; backslash -> O dieresis +\0 \x9A ; bracket right -> U dieresis +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x84 ; brace left -> a dieresis +\0 \x94 ; bar -> o dieresis +\0 \x81 ; brace right -> u dieresis +\0 \xE1 ; tilde -> german double s (or the beta-like char) +\0 \x7F ; DEL +END diff --git a/cfgs/charset/i1m_ibm.chs b/cfgs/charset/i1m_ibm.chs new file mode 100644 index 0000000..1b34c2d --- /dev/null +++ b/cfgs/charset/i1m_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO-8859-1 extended characters to IBM-PC characters. +; It contains modifications to convert a few MAC characters to IBMPC. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN1MAC ; from set +IBMPC ; to set +; +\0 \d128 ; 128 (missing) These codes are unused in the LATIN-1 set. +\0 \x8f ; 129 MAC: A ring +\0 \d130 ; 130 (missing) +\0 \d131 ; 131 (missing) 4 +\0 \d132 ; 132 (missing) +\0 \d133 ; 133 (missing) +\0 \d134 ; 134 (missing) +\0 \d135 ; 135 (missing) 8 +\0 \d136 ; 136 (missing) +\0 \d137 ; 137 (missing) +\0 \d138 ; 138 (missing) +\0 \d139 ; 139 (missing) 12 +\0 \x86 ; 140 MAC: a ring +\0 \d141 ; 141 (missing) +\0 \d142 ; 142 (missing) +\0 \d143 ; 143 (missing) 16 +\0 \d144 ; 144 (missing) +\0 \d145 ; 145 (missing) +\0 \d146 ; 146 (missing) +\0 \d147 ; 147 (missing) 20 +\0 \d148 ; 148 (missing) +\0 \d149 ; 149 (missing) +\0 \d150 ; 150 (missing) +\0 \d151 ; 151 (missing) 24 +\0 \d152 ; 152 (missing) +\0 \d153 ; 153 (missing) +\0 \d154 ; 154 (missing) +\0 \d155 ; 155 (missing) 28 +\0 \d156 ; 156 (missing) +\0 \d157 ; 157 (missing) +\0 \d158 ; 158 (missing) +\0 \d159 ; 159 (missing) 32 +\0 \xff ; 160 non-breaking space +\0 \xad ; 161 exclam downwards +\0 \x9b ; 162 MAC: o slash +\0 \x9c ; 163 pound sterling +\0 \x0f ; 164 currency +\0 \x9d ; 165 Yen +\0 | ; 166 broken bar +\0 \x15 ; 167 section +\x1 ? ; 168 dieresis +\0 c ; 169 copyright +\0 \xa6 ; 170 ord feminine +\0 \xae ; 171 guillemot left +\0 \xaa ; 172 logical not +\0 - ; 173 soft hyphen (or em dash) +\0 \x92 ; 174 MAC: AE +\x1 ? ; 175 overbar (macron) +\0 \xf8 ; 176 ring / degree +\0 \xf1 ; 177 plusminus +\0 \xfd ; 178 superscript two (squared) +^ 3 ; 179 superscript three (cubed) +\0 \x9d ; 180 MAC: O slash +\0 \xe6 ; 181 mu +\0 \x14 ; 182 paragraph +\0 \xfe ; 183 bullet +\0 , ; 184 cedilla +^ 1 ; 185 superscript one +\0 \xa7 ; 186 ord masculine +\0 \xaf ; 187 guillemot right +\0 \xac ; 188 one quarter +\0 \xab ; 189 half +\0 \x91 ; 190 MAC: ae +\0 \xa8 ; 191 question downwards +\0 A ; 192 A grave +\0 A ; 193 A acute +\0 A ; 194 A circumflex +\0 A ; 195 A tilde +\0 \x8e ; 196 A dieresis +\0 \x8f ; 197 A ring +\0 \x92 ; 198 AE +\0 \x80 ; 199 C cedilla +\0 E ; 200 E grave +\0 \x90 ; 201 E acute +\0 E ; 202 E circumflex +E e ; 203 E dieresis +\0 I ; 204 I grave +\0 I ; 205 I acute +\0 I ; 206 I circumflex +I e ; 207 I dieresis +\0 D ; 208 Eth +\0 \xa5 ; 209 N tilde +\0 O ; 210 O grave +\0 O ; 211 O acute +\0 O ; 212 O circumflex +\0 O ; 213 O tilde +\0 \x99 ; 214 O dieresis +\0 x ; 215 multiplication +\0 \x9d ; 216 O slash (mapping for CP850/865) +\0 U ; 217 U grave +\0 U ; 218 U acute +\0 U ; 219 U circumflex +\0 \x9a ; 220 U dieresis +\0 Y ; 221 Y acute +\x1 ? ; 222 Thorn +\0 \xe1 ; 223 german double s / beta +\0 \x85 ; 224 a grave +\0 \xa0 ; 225 a acute +\0 \x83 ; 226 a circumflex +\0 a ; 227 a tilde +\0 \x84 ; 228 a dieresis +\0 \x86 ; 229 a ring +\0 \x91 ; 230 ae +\0 \x87 ; 231 c cedilla +\0 \x8a ; 232 e grave +\0 \x82 ; 233 e acute +\0 \x88 ; 234 e circumflex +\0 \x89 ; 235 e dieresis +\0 \x8d ; 236 i grave +\0 \xa1 ; 237 i acute +\0 \x8c ; 238 i circumflex +\0 \x8b ; 239 i dieresis +\0 \xe7 ; 240 eth +\0 \xa4 ; 241 n tilde +\0 \x95 ; 242 o grave +\0 \xa2 ; 243 o acute +\0 \x93 ; 244 o circumflex +\0 o ; 245 o tilde +\0 \x94 ; 246 o dieresis +\0 \xf6 ; 247 division +\0 \x9b ; 248 o slash (mapping for CP 850/865) +\0 \x97 ; 249 u grave +\0 \xa3 ; 250 u acute +\0 \x96 ; 251 u circumflex +\0 \x81 ; 252 u dieresis +y e ; 253 y acute +\x1 ? ; 254 thorn +\0 \x98 ; 255 y dieresis +END diff --git a/cfgs/charset/i51_ibm.esc b/cfgs/charset/i51_ibm.esc new file mode 100644 index 0000000..c466125 --- /dev/null +++ b/cfgs/charset/i51_ibm.esc @@ -0,0 +1,65 @@ +; -------------------------------------------------------------------- +; Escaped Characters Table for GoldED 2.30. +; Based on IBM Code Page 437 with additions for CP850 and 865. +; -------------------------------------------------------------------- +; FSC-0051.003 (I51) Combined Characters, Thomas Gradin (2:200/108). +; -------------------------------------------------------------------- +IBMPC ; Map codes to charset. +; -------------------------------------------------------------------- + 0 0 ; superscript zero + 1 1 ; superscript one + 2 \xFD ; superscript two + 3 3 ; superscript three + 4 4 ; superscript four + 5 5 ; superscript five + 6 6 ; superscript six + 7 7 ; superscript seven + 8 8 ; superscript eight + 9 9 ; superscript nine + I I ; I with dot + i \xD5 ; dot-less i + n \xFC ; superscript n +"U U ; U with double acute accent +"u u ; u with double acute accent +$P \x9E ; peseta sign +$f \x9F ; guilder sign +,A A ; A with cedilla +,E E ; E with cedilla +,S S ; S with cedilla +,a a ; a with cedilla +,e e ; e with cedilla +,s s ; s with cedilla +-< \xF3 ; equal or less than +-= \xF0 ; defined as +-> \xF2 ; equal or greater than +-C C ; complement of +-I \xEE ; part of lot +-S S ; Polish S with dash +-Z Z ; Polish Z with dash +-s s ; Polish s with dash +-z z ; Polish z with dash +-~ \xF7 ; about equal +.0 0 ; subscript zero +.1 1 ; subscript one +.2 2 ; subscript two +.3 3 ; subscript three +.4 4 ; subscript four +.5 5 ; subscript five +.6 6 ; subscript six +.7 7 ; subscript seven +.8 8 ; subscript eight +.9 9 ; subscript nine +.S S ; Polish S with dot +.Z Z ; Polish Z with dot +.s s ; Polish s with dot +.z z ; Polish z with dot +/L L ; Polish L slash +/l l ; Polish l slash +^G G ; G with inversed circ. accent +^S S ; S with inversed circ. accent +^g g ; g with inversed circ. accent +^s s ; s with inversed circ. accent +gG \xE2 ; capital gamma +ga \xE0 ; alpha +tm tm ; trade mark sign +; -------------------------------------------------------------------- diff --git a/cfgs/charset/ibm_asc.chs b/cfgs/charset/ibm_asc.chs new file mode 100644 index 0000000..95433f3 --- /dev/null +++ b/cfgs/charset/ibm_asc.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to ASCII. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set (actually CP865) +ASCII ; to set +; +\0 C ; 128 80 latin capital letter c with cedilla +u e ; 129 81 latin small letter u with diaeresis +\0 e ; 130 82 latin small letter e with acute +\0 a ; 131 83 latin small letter a with circumflex +a e ; 132 84 latin small letter a with diaeresis +\0 a ; 133 85 latin small letter a with grave +a a ; 134 86 latin small letter a with ring above +\0 c ; 135 87 latin small letter c with cedilla +\0 e ; 136 88 latin small letter e with circumflex +e e ; 137 89 latin small letter e with diaeresis +\0 e ; 138 8A latin small letter e with grave +i e ; 139 8B latin small letter i with diaeresis +\0 i ; 140 8C latin small letter i with circumflex +\0 i ; 141 8D latin small letter i with grave +A e ; 142 8E latin capital letter a with diaeresis +\0 A ; 143 8F latin capital letter a with ring above +\0 E ; 144 90 latin capital letter e with acute +a e ; 145 91 latin small letter ae +A E ; 146 92 latin capital letter ae +\0 o ; 147 93 latin small letter o with circumflex +o e ; 148 94 latin small letter o with diaeresis +\0 o ; 149 95 latin small letter o with grave +\0 u ; 150 96 latin small letter u with circumflex +\0 u ; 151 97 latin small letter u with grave +y e ; 152 98 latin small letter y with diaeresis +O e ; 153 99 latin capital letter o with diaeresis +U e ; 154 9A latin capital letter u with diaeresis +o e ; 155 9B latin small letter o with stroke (CP865 mapping) +\0 # ; 156 9C pound sign +O e ; 157 9D latin capital letter o with stroke (CP865 mapping) +P t ; 158 9E peseta sign +F l ; 159 9F dutch guilder sign (ibm437 159) +\0 a ; 160 A0 latin small letter a with acute +\0 i ; 161 A1 latin small letter i with acute +\0 o ; 162 A2 latin small letter o with acute +\0 u ; 163 A3 latin small letter u with acute +\0 n ; 164 A4 latin small letter n with tilde +\0 N ; 165 A5 latin capital letter n with tilde +\0 a ; 166 A6 feminine ordinal indicator +\0 o ; 167 A7 masculine ordinal indicator +\0 ? ; 168 A8 inverted question mark +\0 - ; 169 A9 reversed not sign +\0 ! ; 170 AA not sign +1 / 2 ; 171 AB vulgar fraction one half +1 / 4 ; 172 AC vulgar fraction one quarter +\0 ! ; 173 AD inverted exclamation mark +< < ; 174 AE left-pointing double angle quotation mark +> > ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left +\0 | ; 181 B5 box drawings vertical light and left heavy +\0 | ; 182 B6 box drawings vertical heavy and left light +\0 + ; 183 B7 box drawings down heavy and left light +\0 + ; 184 B8 box drawings down light and left heavy +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left +\0 + ; 189 BD box drawings up heavy and left light +\0 + ; 190 BE box drawings up light and left heavy +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal +\0 | ; 198 C6 box drawings vertical light and right heavy +\0 | ; 199 C7 box drawings vertical heavy and right light +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal +\0 = ; 207 CF box drawings up light and horizontal heavy +\0 - ; 208 D0 box drawings up heavy and horizontal light +\0 = ; 209 D1 box drawings down light and horizontal heavy +\0 - ; 210 D2 box drawings down heavy and horizontal light +\0 + ; 211 D3 box drawings up heavy and right light +\0 + ; 212 D4 box drawings up light and right heavy +\0 + ; 213 D5 box drawings down light and right heavy +\0 + ; 214 D6 box drawings down heavy and right light +\0 | ; 215 D7 box drawings vertical heavy and horizontal light +\0 + ; 216 D8 box drawings vertical light and horizontal heavy +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 - ; 220 DC lower half block +\0 | ; 221 DD left half block +\0 | ; 222 DE right half block +\0 - ; 223 DF upper half block +\0 a ; 224 E0 greek small letter alpha +s s ; 225 E1 greek small letter beta (here used as german ss) +\x1 ? ; 226 E2 greek capital letter gamma +p i ; 227 E3 greek small letter pi +\x1 ? ; 228 E4 greek capital letter sigma +\x1 ? ; 229 E5 greek small letter sigma +m u ; 230 E6 greek small letter mu +\x1 ? ; 231 E7 greek small letter tau +\x1 ? ; 232 E8 greek capital letter phi +\x1 ? ; 233 E9 greek capital letter theta +\0 O ; 234 EA greek capital letter omega +\0 d ; 235 EB greek small letter delta +\x1 ? ; 236 EC infinity +\0 o ; 237 ED empty set +\x1 ? ; 238 EE greek small letter epsilon +\x1 ? ; 239 EF intersection += = ; 240 F0 identical to ++ - ; 241 F1 plus-minus sign +> = ; 242 F2 greater-than or equal to +< = ; 243 F3 less-than or equal to +\x1 ? ; 244 F4 top half integral +\x1 ? ; 245 F5 bottom half integral +\0 / ; 246 F6 division sign +~ = ; 247 F7 almost equal to +\0 ' ; 248 F8 ring operator +\0 . ; 249 F9 middle dot +\0 - ; 250 FA bullet operator +\x1 ? ; 251 FB square root +^ n ; 252 FC superscript latin small letter n +^ 2 ; 253 FD superscript two +\0 * ; 254 FE black square +\0 \d32 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_cmp.chs b/cfgs/charset/ibm_cmp.chs new file mode 100644 index 0000000..172929e --- /dev/null +++ b/cfgs/charset/ibm_cmp.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to Composed characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +0 ; level number +; +IBMPC ; from set (actually CP865) +COMPOSED ; to set +; +, \x8D C ; 128 80 latin capital letter c with cedilla +u \x8D " ; 129 81 latin small letter u with diaeresis +e \x8D ' ; 130 82 latin small letter e with acute +a \x8D ^ ; 131 83 latin small letter a with circumflex +a \x8D " ; 132 84 latin small letter a with diaeresis +a \x8D ` ; 133 85 latin small letter a with grave +a \x8D * ; 134 86 latin small letter a with ring above +, \x8D c ; 135 87 latin small letter c with cedilla +e \x8D ^ ; 136 88 latin small letter e with circumflex +e \x8D " ; 137 89 latin small letter e with diaeresis +e \x8D ` ; 138 8A latin small letter e with grave +i \x8D " ; 139 8B latin small letter i with diaeresis +i \x8D ^ ; 140 8C latin small letter i with circumflex +i \x8D ` ; 141 8D latin small letter i with grave +A \x8D " ; 142 8E latin capital letter a with diaeresis +A \x8D * ; 143 8F latin capital letter a with ring above +E \x8D ' ; 144 90 latin capital letter e with acute +a \x8D e ; 145 91 latin small letter ae +A \x8D E ; 146 92 latin capital letter ae +o \x8D ^ ; 147 93 latin small letter o with circumflex +o \x8D " ; 148 94 latin small letter o with diaeresis +o \x8D ` ; 149 95 latin small letter o with grave +u \x8D ^ ; 150 96 latin small letter u with circumflex +u \x8D ` ; 151 97 latin small letter u with grave +y \x8D " ; 152 98 latin small letter y with diaeresis +O \x8D " ; 153 99 latin capital letter o with diaeresis +U \x8D " ; 154 9A latin capital letter u with diaeresis +o \x8D e ; 155 9B latin small letter o with stroke (CP865 mapping) +P \x8D d ; 156 9C pound sign +O \x8D E ; 157 9D latin capital letter o with stroke (CP865 mapping) +P \x8D t ; 158 9E peseta sign +F \x8D l ; 159 9F dutch guilder sign (ibm437 159) +a \x8D ' ; 160 A0 latin small letter a with acute +i \x8D ' ; 161 A1 latin small letter i with acute +o \x8D ' ; 162 A2 latin small letter o with acute +u \x8D ' ; 163 A3 latin small letter u with acute +n \x8D ~ ; 164 A4 latin small letter n with tilde +N \x8D ~ ; 165 A5 latin capital letter n with tilde +a \x8D _ ; 166 A6 feminine ordinal indicator +o \x8D _ ; 167 A7 masculine ordinal indicator +? \x8D ? ; 168 A8 inverted question mark +? ; 169 A9 reversed not sign +? ; 170 AA not sign +' \x8D 2 ; 171 AB vulgar fraction one half +' \x8D 4 ; 172 AC vulgar fraction one quarter +! \x8D ! ; 173 AD inverted exclamation mark +< \x8D < ; 174 AE left-pointing double angle quotation mark +> \x8D > ; 175 AF right-pointing double angle quotation mark +# ; 176 B0 light shade +# ; 177 B1 medium shade +# ; 178 B2 dark shade +| ; 179 B3 box drawings light vertical +| ; 180 B4 box drawings light vertical and left +| ; 181 B5 box drawings vertical light and left heavy +| ; 182 B6 box drawings vertical heavy and left light ++ ; 183 B7 box drawings down heavy and left light ++ ; 184 B8 box drawings down light and left heavy +| ; 185 B9 box drawings heavy vertical and left +| ; 186 BA box drawings heavy vertical ++ ; 187 BB box drawings heavy down and left ++ ; 188 BC box drawings heavy up and left ++ ; 189 BD box drawings up heavy and left light ++ ; 190 BE box drawings up light and left heavy ++ ; 191 BF box drawings light down and left ++ ; 192 C0 box drawings light up and right +- ; 193 C1 box drawings light up and horizontal +- ; 194 C2 box drawings light down and horizontal +| ; 195 C3 box drawings light vertical and right +- ; 196 C4 box drawings light horizontal ++ ; 197 C5 box drawings light vertical and horizontal +| ; 198 C6 box drawings vertical light and right heavy +| ; 199 C7 box drawings vertical heavy and right light ++ ; 200 C8 box drawings heavy up and right ++ ; 201 C9 box drawings heavy down and right += ; 202 CA box drawings heavy up and horizontal += ; 203 CB box drawings heavy down and horizontal +| ; 204 CC box drawings heavy vertical and right += ; 205 CD box drawings heavy horizontal ++ ; 206 CE box drawings heavy vertical and horizontal += ; 207 CF box drawings up light and horizontal heavy +- ; 208 D0 box drawings up heavy and horizontal light += ; 209 D1 box drawings down light and horizontal heavy +- ; 210 D2 box drawings down heavy and horizontal light ++ ; 211 D3 box drawings up heavy and right light ++ ; 212 D4 box drawings up light and right heavy ++ ; 213 D5 box drawings down light and right heavy ++ ; 214 D6 box drawings down heavy and right light +| ; 215 D7 box drawings vertical heavy and horizontal light ++ ; 216 D8 box drawings vertical light and horizontal heavy ++ ; 217 D9 box drawings light up and left ++ ; 218 DA box drawings light down and right +# ; 219 DB full block +- ; 220 DC lower half block +| ; 221 DD left half block +| ; 222 DE right half block +- ; 223 DF upper half block +? ; 224 E0 greek small letter alpha +s \x8D s ; 225 E1 greek small letter beta (here used as german ss) +? ; 226 E2 greek capital letter gamma +p \x8D i ; 227 E3 greek small letter pi +? ; 228 E4 greek capital letter sigma +? ; 229 E5 greek small letter sigma +? ; 230 E6 greek small letter mu +? ; 231 E7 greek small letter tau +? ; 232 E8 greek capital letter phi +? ; 233 E9 greek capital letter theta +? ; 234 EA greek capital letter omega +? ; 235 EB greek small letter delta +? ; 236 EC infinity +? ; 237 ED empty set +? ; 238 EE greek small letter epsilon +? ; 239 EF intersection += \x8D = ; 240 F0 identical to ++ \x8D - ; 241 F1 plus-minus sign +> \x8D = ; 242 F2 greater-than or equal to +< \x8D = ; 243 F3 less-than or equal to +? ; 244 F4 top half integral +? ; 245 F5 bottom half integral +/ ; 246 F6 division sign +~ \x8D = ; 247 F7 almost equal to +? ; 248 F8 ring operator +. ; 249 F9 middle dot +- ; 250 FA bullet operator +? ; 251 FB square root +^ \x8D n ; 252 FC superscript latin small letter n +^ \x8D 2 ; 253 FD superscript two +* ; 254 FE black square +\d32 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_i51.chs b/cfgs/charset/ibm_i51.chs new file mode 100644 index 0000000..ebe1d8f --- /dev/null +++ b/cfgs/charset/ibm_i51.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to ISO 8859-1 characters, +; and uses I51 compatible escape sequences for non-ISO chars. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +0 ; level number +; +IBMPC ; from set +I51 ; to set +; +\xC7 ; C with cedilla +\xDC ; u dieresis +\xE9 ; e acute +\xE2 ; a circumflex +\xE4 ; a dieresis +\xE0 ; a grave +\xE5 ; a ring +\xE7 ; c cedilla +\xEA ; e circumflex +\xEB ; e dieresis +\xE8 ; e grave +\xEF ; i dieresis +\xEE ; i circumflex +\xEC ; i grave +\xC4 ; A dieresis +\xC5 ; A ring +\xC9 ; E acute +\xE6 ; ae +\xC6 ; AE +\xF4 ; o circumflex +\xF6 ; o dieresis +\xF3 ; o acute +\xDB ; u circumflex +\xD9 ; u grave +\xFF ; y dieresis +\xD6 ; O dieresis +\xDC ; U dieresis +\xA2 ; cent +\xA3 ; pound sterling +\xA5 ; yen +\d2 $P ; Pt +\d2 $f ; florin +\xE1 ; a acute +\xCC ; i grave +\xF2 ; o grave +\xF9 ; u grave +\xF1 ; n tilde +\xD1 ; N tilde +\xAA ; ord feminine +\xBA ; ord masculine +\xBF ; question downwards +- ; +\xAC ; logical not +\xBD ; half fraction +\xBC ; quarter fraction +\xA1 ; exclam downwards +\xAB ; guillemot left +\xBB ; guillemot right +# ; +# ; +# ; +| ; +| ; +| ; +| ; ++ ; ++ ; +| ; +| ; ++ ; ++ ; ++ ; ++ ; ++ ; ++ ; +- ; +- ; +| ; +- ; ++ ; +| ; +| ; ++ ; ++ ; += ; += ; +| ; += ; ++ ; += ; +- ; += ; +- ; ++ ; ++ ; ++ ; ++ ; +| ; ++ ; ++ ; ++ ; +# ; +- ; +| ; +| ; +- ; +\d2 ga ; alpha +\xDF ; german double s (misused as Beta) +\d2 gG ; Gamma +pi ; pi +? ; Sigma (summation) +? ; sigma +\xB5 ; mu +? ; gamma +? ; Phi +? ; Theta +? ; Omega +\xF0 ; delta +? ; infinity +\xF8 ; o slash +? ; element +? ; intersection +\d2 -= ; equivalence +\xB1 ; plusminus +\d2 -> ; greater equals +\d2 -< ; smaller equals +? ; integral top +? ; integral bottom +\xF7 ; divide +\d2 -~ ; approx. +\xB0 ; ring / degree +. ; centered dot +- ; en dash +? ; radical +^n ; to the n'th power +\xB2 ; to the second power +\xB7 ; bullet +\xA0 ; non-breaking space +END diff --git a/cfgs/charset/ibm_ibm.chs b/cfgs/charset/ibm_ibm.chs new file mode 100644 index 0000000..d734a28 --- /dev/null +++ b/cfgs/charset/ibm_ibm.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBMPC to IBMPC. (no conversion) +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set +IBMPC ; to set +; +\0 \d128 ; 128 80 latin capital letter c with cedilla +\0 \d129 ; 129 81 latin small letter u with diaeresis +\0 \d130 ; 130 82 latin small letter e with acute +\0 \d131 ; 131 83 latin small letter a with circumflex +\0 \d132 ; 132 84 latin small letter a with diaeresis +\0 \d133 ; 133 85 latin small letter a with grave +\0 \d134 ; 134 86 latin small letter a with ring above +\0 \d135 ; 135 87 latin small letter c with cedilla +\0 \d136 ; 136 88 latin small letter e with circumflex +\0 \d137 ; 137 89 latin small letter e with diaeresis +\0 \d138 ; 138 8A latin small letter e with grave +\0 \d139 ; 139 8B latin small letter i with diaeresis +\0 \d140 ; 140 8C latin small letter i with circumflex +\0 \d141 ; 141 8D latin small letter i with grave +\0 \d142 ; 142 8E latin capital letter a with diaeresis +\0 \d143 ; 143 8F latin capital letter a with ring above +\0 \d144 ; 144 90 latin capital letter e with acute +\0 \d145 ; 145 91 latin small letter ae +\0 \d146 ; 146 92 latin capital letter ae +\0 \d147 ; 147 93 latin small letter o with circumflex +\0 \d148 ; 148 94 latin small letter o with diaeresis +\0 \d149 ; 149 95 latin small letter o with grave +\0 \d150 ; 150 96 latin small letter u with circumflex +\0 \d151 ; 151 97 latin small letter u with grave +\0 \d152 ; 152 98 latin small letter y with diaeresis +\0 \d153 ; 153 99 latin capital letter o with diaeresis +\0 \d154 ; 154 9A latin capital letter u with diaeresis +\0 \d155 ; 155 9B latin small letter o with stroke (CP865 mapping) +\0 \d156 ; 156 9C pound sign +\0 \d157 ; 157 9D latin capital letter o with stroke (CP865 mapping) +\0 \d158 ; 158 9E peseta sign +\0 \d159 ; 159 9F dutch guilder sign (ibm437 159) +\0 \d160 ; 160 A0 latin small letter a with acute +\0 \d161 ; 161 A1 latin small letter i with acute +\0 \d162 ; 162 A2 latin small letter o with acute +\0 \d163 ; 163 A3 latin small letter u with acute +\0 \d164 ; 164 A4 latin small letter n with tilde +\0 \d165 ; 165 A5 latin capital letter n with tilde +\0 \d166 ; 166 A6 feminine ordinal indicator +\0 \d167 ; 167 A7 masculine ordinal indicator +\0 \d168 ; 168 A8 inverted question mark +\0 \d169 ; 169 A9 reversed not sign +\0 \d170 ; 170 AA not sign +\0 \d171 ; 171 AB vulgar fraction one half +\0 \d172 ; 172 AC vulgar fraction one quarter +\0 \d173 ; 173 AD inverted exclamation mark +\0 \d174 ; 174 AE left-pointing double angle quotation mark +\0 \d175 ; 175 AF right-pointing double angle quotation mark +\0 \d176 ; 176 B0 light shade +\0 \d177 ; 177 B1 medium shade +\0 \d178 ; 178 B2 dark shade +\0 \d179 ; 179 B3 box drawings light vertical +\0 \d180 ; 180 B4 box drawings light vertical and left +\0 \d181 ; 181 B5 box drawings vertical light and left heavy +\0 \d182 ; 182 B6 box drawings vertical heavy and left light +\0 \d183 ; 183 B7 box drawings down heavy and left light +\0 \d184 ; 184 B8 box drawings down light and left heavy +\0 \d185 ; 185 B9 box drawings heavy vertical and left +\0 \d186 ; 186 BA box drawings heavy vertical +\0 \d187 ; 187 BB box drawings heavy down and left +\0 \d188 ; 188 BC box drawings heavy up and left +\0 \d189 ; 189 BD box drawings up heavy and left light +\0 \d190 ; 190 BE box drawings up light and left heavy +\0 \d191 ; 191 BF box drawings light down and left +\0 \d192 ; 192 C0 box drawings light up and right +\0 \d193 ; 193 C1 box drawings light up and horizontal +\0 \d194 ; 194 C2 box drawings light down and horizontal +\0 \d195 ; 195 C3 box drawings light vertical and right +\0 \d196 ; 196 C4 box drawings light horizontal +\0 \d197 ; 197 C5 box drawings light vertical and horizontal +\0 \d198 ; 198 C6 box drawings vertical light and right heavy +\0 \d199 ; 199 C7 box drawings vertical heavy and right light +\0 \d200 ; 200 C8 box drawings heavy up and right +\0 \d201 ; 201 C9 box drawings heavy down and right +\0 \d202 ; 202 CA box drawings heavy up and horizontal +\0 \d203 ; 203 CB box drawings heavy down and horizontal +\0 \d204 ; 204 CC box drawings heavy vertical and right +\0 \d205 ; 205 CD box drawings heavy horizontal +\0 \d206 ; 206 CE box drawings heavy vertical and horizontal +\0 \d207 ; 207 CF box drawings up light and horizontal heavy +\0 \d208 ; 208 D0 box drawings up heavy and horizontal light +\0 \d209 ; 209 D1 box drawings down light and horizontal heavy +\0 \d210 ; 210 D2 box drawings down heavy and horizontal light +\0 \d211 ; 211 D3 box drawings up heavy and right light +\0 \d212 ; 212 D4 box drawings up light and right heavy +\0 \d213 ; 213 D5 box drawings down light and right heavy +\0 \d214 ; 214 D6 box drawings down heavy and right light +\0 \d215 ; 215 D7 box drawings vertical heavy and horizontal light +\0 \d216 ; 216 D8 box drawings vertical light and horizontal heavy +\0 \d217 ; 217 D9 box drawings light up and left +\0 \d218 ; 218 DA box drawings light down and right +\0 \d219 ; 219 DB full block +\0 \d220 ; 220 DC lower half block +\0 \d221 ; 221 DD left half block +\0 \d222 ; 222 DE right half block +\0 \d223 ; 223 DF upper half block +\0 \d224 ; 224 E0 greek small letter alpha +\0 \d225 ; 225 E1 greek small letter beta (here used as german ss) +\0 \d226 ; 226 E2 greek capital letter gamma +\0 \d227 ; 227 E3 greek small letter pi +\0 \d228 ; 228 E4 greek capital letter sigma +\0 \d229 ; 229 E5 greek small letter sigma +\0 \d230 ; 230 E6 greek small letter mu +\0 \d231 ; 231 E7 greek small letter tau +\0 \d232 ; 232 E8 greek capital letter phi +\0 \d233 ; 233 E9 greek capital letter theta +\0 \d234 ; 234 EA greek capital letter omega +\0 \d235 ; 235 EB greek small letter delta +\0 \d236 ; 236 EC infinity +\0 \d237 ; 237 ED empty set +\0 \d238 ; 238 EE greek small letter epsilon +\0 \d239 ; 239 EF intersection +\0 \d240 ; 240 F0 identical to +\0 \d241 ; 241 F1 plus-minus sign +\0 \d242 ; 242 F2 greater-than or equal to +\0 \d243 ; 243 F3 less-than or equal to +\0 \d244 ; 244 F4 top half integral +\0 \d245 ; 245 F5 bottom half integral +\0 \d246 ; 246 F6 division sign +\0 \d247 ; 247 F7 almost equal to +\0 \d248 ; 248 F8 ring operator +\0 \d249 ; 249 F9 middle dot +\0 \d250 ; 250 FA bullet operator +\0 \d251 ; 251 FB square root +\0 \d252 ; 252 FC superscript latin small letter n +\0 \d253 ; 253 FD superscript two +\0 \d254 ; 254 FE black square +\0 \d255 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_iqp.chs b/cfgs/charset/ibm_iqp.chs new file mode 100644 index 0000000..325cc28 --- /dev/null +++ b/cfgs/charset/ibm_iqp.chs @@ -0,0 +1,289 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to ISO 8859-1 q-p characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +100000 ; ID number (when >65535, all 255 chars will be translated) +0 ; version number +; +2 ; level number +; +IBMPC ; from set (actually CP865) +LATIN1QP ; to set +; ; dec hx description +\0 \d0 ; 0 00 +\0 \d1 ; 1 01 +\0 \d2 ; 2 02 +\0 \d3 ; 3 03 +\0 \d4 ; 4 04 +\0 \d5 ; 5 05 +\0 \d6 ; 6 06 +\0 \d7 ; 7 07 +\0 \d8 ; 8 08 +\0 \d9 ; 9 09 +\0 \d10 ; 10 0A +\0 \d11 ; 11 0B +\0 \d12 ; 12 0C +\0 \d13 ; 13 0D +\0 \d14 ; 14 0E +\0 \d15 ; 15 0F +\0 \d16 ; 16 10 +\0 \d17 ; 17 11 +\0 \d18 ; 18 12 +\0 \d19 ; 19 13 +\0 \d20 ; 20 14 +\0 \d21 ; 21 15 +\0 \d22 ; 22 16 +\0 \d23 ; 23 17 +\0 \d24 ; 24 18 +\0 \d25 ; 25 19 +\0 \d26 ; 26 1A +\0 \d27 ; 27 1B +\0 \d28 ; 28 1C +\0 \d29 ; 29 1D +\0 \d30 ; 30 1E +\0 \d31 ; 31 1F +\0 \d32 ; 32 20 +\0 \d33 ; 33 21 +\0 \d34 ; 34 22 +\0 \d35 ; 35 23 +\0 \d36 ; 36 24 +\0 \d37 ; 37 25 +\0 \d38 ; 38 26 +\0 \d39 ; 39 27 +\0 \d40 ; 40 28 +\0 \d41 ; 41 29 +\0 \d42 ; 42 2A +\0 \d43 ; 43 2B +\0 \d44 ; 44 2C +\0 \d45 ; 45 2D +\0 \d46 ; 46 2E +\0 \d47 ; 47 2F +\0 \d48 ; 48 30 +\0 \d49 ; 49 31 +\0 \d50 ; 50 32 +\0 \d51 ; 51 33 +\0 \d52 ; 52 34 +\0 \d53 ; 53 35 +\0 \d54 ; 54 36 +\0 \d55 ; 55 37 +\0 \d56 ; 56 38 +\0 \d57 ; 57 39 +\0 \d58 ; 58 3A +\0 \d59 ; 59 3B +\0 \d60 ; 60 3C += 3 D ; 61 3D +\0 \d62 ; 62 3E +\0 \d63 ; 63 3F +\0 \d64 ; 64 40 +\0 \d65 ; 65 41 +\0 \d66 ; 66 42 +\0 \d67 ; 67 43 +\0 \d68 ; 68 44 +\0 \d69 ; 69 45 +\0 \d70 ; 70 46 +\0 \d71 ; 71 47 +\0 \d72 ; 72 48 +\0 \d73 ; 73 49 +\0 \d74 ; 74 4A +\0 \d75 ; 75 4B +\0 \d76 ; 76 4C +\0 \d77 ; 77 4D +\0 \d78 ; 78 4E +\0 \d79 ; 79 4F +\0 \d80 ; 80 50 +\0 \d81 ; 81 51 +\0 \d82 ; 82 52 +\0 \d83 ; 83 53 +\0 \d84 ; 84 54 +\0 \d85 ; 85 55 +\0 \d86 ; 86 56 +\0 \d87 ; 87 57 +\0 \d88 ; 88 58 +\0 \d89 ; 89 59 +\0 \d90 ; 90 5A +\0 \d91 ; 91 5B +\0 \d92 ; 92 5C +\0 \d93 ; 93 5D +\0 \d94 ; 94 5E +\0 \d95 ; 95 5F +\0 \d96 ; 96 60 +\0 \d97 ; 97 61 +\0 \d98 ; 98 62 +\0 \d99 ; 99 63 +\0 \d100 ; 100 64 +\0 \d101 ; 101 65 +\0 \d102 ; 102 66 +\0 \d103 ; 103 67 +\0 \d104 ; 104 68 +\0 \d105 ; 105 69 +\0 \d106 ; 106 6A +\0 \d107 ; 107 6B +\0 \d108 ; 108 6C +\0 \d109 ; 109 6D +\0 \d110 ; 110 6E +\0 \d111 ; 111 6F +\0 \d112 ; 112 70 +\0 \d113 ; 113 71 +\0 \d114 ; 114 72 +\0 \d115 ; 115 73 +\0 \d116 ; 116 74 +\0 \d117 ; 117 75 +\0 \d118 ; 118 76 +\0 \d119 ; 119 77 +\0 \d120 ; 120 78 +\0 \d121 ; 121 79 +\0 \d122 ; 122 7A +\0 \d123 ; 123 7B +\0 \d124 ; 124 7C +\0 \d125 ; 125 7D +\0 \d126 ; 126 7E +\0 \d127 ; 127 7F += C 7 ; 128 80 latin capital letter c with cedilla += F C ; 129 81 latin small letter u with diaeresis += E 9 ; 130 82 latin small letter e with acute += E 2 ; 131 83 latin small letter a with circumflex += E 4 ; 132 84 latin small letter a with diaeresis += E 0 ; 133 85 latin small letter a with grave += E 5 ; 134 86 latin small letter a with ring above += E 7 ; 135 87 latin small letter c with cedilla += E A ; 136 88 latin small letter e with circumflex += E B ; 137 89 latin small letter e with diaeresis += E 8 ; 138 8A latin small letter e with grave += E F ; 139 8B latin small letter i with diaeresis += E E ; 140 8C latin small letter i with circumflex += E C ; 141 8D latin small letter i with grave += C 4 ; 142 8E latin capital letter a with diaeresis += C 5 ; 143 8F latin capital letter a with ring above += C 9 ; 144 90 latin capital letter e with acute += E 6 ; 145 91 latin small letter ae += C 6 ; 146 92 latin capital letter ae += F 4 ; 147 93 latin small letter o with circumflex += F 6 ; 148 94 latin small letter o with diaeresis += F 2 ; 149 95 latin small letter o with grave += F B ; 150 96 latin small letter u with circumflex += F 9 ; 151 97 latin small letter u with grave += F F ; 152 98 latin small letter y with diaeresis += D 6 ; 153 99 latin capital letter o with diaeresis += D C ; 154 9A latin capital letter u with diaeresis += F 8 ; 155 9B latin small letter o with stroke (CP865 mapping) += A 3 ; 156 9C pound sign += D 8 ; 157 9D latin capital letter o with stroke (CP865 mapping) +P t ; 158 9E peseta sign +f l ; 159 9F dutch guilder sign (ibm437 159) += E 1 ; 160 A0 latin small letter a with acute += E D ; 161 A1 latin small letter i with acute += F 3 ; 162 A2 latin small letter o with acute += F A ; 163 A3 latin small letter u with acute += F 1 ; 164 A4 latin small letter n with tilde += D 1 ; 165 A5 latin capital letter n with tilde += A A ; 166 A6 feminine ordinal indicator += B A ; 167 A7 masculine ordinal indicator += B F ; 168 A8 inverted question mark +\0 - ; 169 A9 reversed not sign += A C ; 170 AA not sign += B D ; 171 AB vulgar fraction one half += B C ; 172 AC vulgar fraction one quarter += A 1 ; 173 AD inverted exclamation mark += A B ; 174 AE left-pointing double angle quotation mark += B B ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left +\0 | ; 181 B5 box drawings vertical light and left heavy +\0 | ; 182 B6 box drawings vertical heavy and left light +\0 + ; 183 B7 box drawings down heavy and left light +\0 + ; 184 B8 box drawings down light and left heavy +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left +\0 + ; 189 BD box drawings up heavy and left light +\0 + ; 190 BE box drawings up light and left heavy +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal +\0 | ; 198 C6 box drawings vertical light and right heavy +\0 | ; 199 C7 box drawings vertical heavy and right light +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal +\0 = ; 207 CF box drawings up light and horizontal heavy +\0 - ; 208 D0 box drawings up heavy and horizontal light +\0 = ; 209 D1 box drawings down light and horizontal heavy +\0 - ; 210 D2 box drawings down heavy and horizontal light +\0 + ; 211 D3 box drawings up heavy and right light +\0 + ; 212 D4 box drawings up light and right heavy +\0 + ; 213 D5 box drawings down light and right heavy +\0 + ; 214 D6 box drawings down heavy and right light +\0 | ; 215 D7 box drawings vertical heavy and horizontal light +\0 + ; 216 D8 box drawings vertical light and horizontal heavy +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 n ; 220 DC lower half block +\0 | ; 221 DD left half block +\0 | ; 222 DE right half block +\0 ~ ; 223 DF upper half block +\0 a ; 224 E0 greek small letter alpha += D F ; 225 E1 greek small letter beta (here used as german ss) +\x1 ? ; 226 E2 greek capital letter gamma +p i ; 227 E3 greek small letter pi +\x1 ? ; 228 E4 greek capital letter sigma +\x1 ? ; 229 E5 greek small letter sigma += B 5 ; 230 E6 greek small letter mu +\x1 ? ; 231 E7 greek small letter tau +\x1 ? ; 232 E8 greek capital letter phi +\x1 ? ; 233 E9 greek capital letter theta +\x1 ? ; 234 EA greek capital letter omega += F 0 ; 235 EB greek small letter delta +\x1 ? ; 236 EC infinity += F 8 ; 237 ED empty set +\x1 ? ; 238 EE greek small letter epsilon +\x1 ? ; 239 EF intersection += = ; 240 F0 identical to += B 1 ; 241 F1 plus-minus sign +> = ; 242 F2 greater-than or equal to +< = ; 243 F3 less-than or equal to +\x1 ? ; 244 F4 top half integral +\x1 ? ; 245 F5 bottom half integral += F 7 ; 246 F6 division sign +~ = ; 247 F7 almost equal to += B 0 ; 248 F8 ring operator +\0 . ; 249 F9 middle dot +\0 - ; 250 FA bullet operator +\x1 ? ; 251 FB square root +^ n ; 252 FC superscript latin small letter n += B 2 ; 253 FD superscript two += B 7 ; 254 FE black square += A 0 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_iso.chs b/cfgs/charset/ibm_iso.chs new file mode 100644 index 0000000..86b8401 --- /dev/null +++ b/cfgs/charset/ibm_iso.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to ISO 8859-1 characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set (actually CP865) +LATIN-1 ; to set +; +\0 \xC7 ; 128 80 latin capital letter c with cedilla +\0 \xFC ; 129 81 latin small letter u with diaeresis +\0 \xE9 ; 130 82 latin small letter e with acute +\0 \xE2 ; 131 83 latin small letter a with circumflex +\0 \xE4 ; 132 84 latin small letter a with diaeresis +\0 \xE0 ; 133 85 latin small letter a with grave +\0 \xE5 ; 134 86 latin small letter a with ring above +\0 \xE7 ; 135 87 latin small letter c with cedilla +\0 \xEA ; 136 88 latin small letter e with circumflex +\0 \xEB ; 137 89 latin small letter e with diaeresis +\0 \xE8 ; 138 8A latin small letter e with grave +\0 \xEF ; 139 8B latin small letter i with diaeresis +\0 \xEE ; 140 8C latin small letter i with circumflex +\0 \xEC ; 141 8D latin small letter i with grave +\0 \xC4 ; 142 8E latin capital letter a with diaeresis +\0 \xC5 ; 143 8F latin capital letter a with ring above +\0 \xC9 ; 144 90 latin capital letter e with acute +\0 \xE6 ; 145 91 latin small letter ae +\0 \xC6 ; 146 92 latin capital letter ae +\0 \xF4 ; 147 93 latin small letter o with circumflex +\0 \xF6 ; 148 94 latin small letter o with diaeresis +\0 \xF2 ; 149 95 latin small letter o with grave +\0 \xFB ; 150 96 latin small letter u with circumflex +\0 \xF9 ; 151 97 latin small letter u with grave +\0 \xFF ; 152 98 latin small letter y with diaeresis +\0 \xD6 ; 153 99 latin capital letter o with diaeresis +\0 \xDC ; 154 9A latin capital letter u with diaeresis +\0 \xF8 ; 155 9B latin small letter o with stroke (CP865 mapping) +\0 \xA3 ; 156 9C pound sign +\0 \xD8 ; 157 9D latin capital letter o with stroke (CP865 mapping) +P t ; 158 9E peseta sign +f l ; 159 9F dutch guilder sign (ibm437 159) +\0 \xE1 ; 160 A0 latin small letter a with acute +\0 \xED ; 161 A1 latin small letter i with acute +\0 \xF3 ; 162 A2 latin small letter o with acute +\0 \xFA ; 163 A3 latin small letter u with acute +\0 \xF1 ; 164 A4 latin small letter n with tilde +\0 \xD1 ; 165 A5 latin capital letter n with tilde +\0 \xAA ; 166 A6 feminine ordinal indicator +\0 \xBA ; 167 A7 masculine ordinal indicator +\0 \xBF ; 168 A8 inverted question mark +\0 - ; 169 A9 reversed not sign +\0 \xAC ; 170 AA not sign +\0 \xBD ; 171 AB vulgar fraction one half +\0 \xBC ; 172 AC vulgar fraction one quarter +\0 \xA1 ; 173 AD inverted exclamation mark +\0 \xAB ; 174 AE left-pointing double angle quotation mark +\0 \xBB ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left +\0 | ; 181 B5 box drawings vertical light and left heavy +\0 | ; 182 B6 box drawings vertical heavy and left light +\0 + ; 183 B7 box drawings down heavy and left light +\0 + ; 184 B8 box drawings down light and left heavy +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left +\0 + ; 189 BD box drawings up heavy and left light +\0 + ; 190 BE box drawings up light and left heavy +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal +\0 | ; 198 C6 box drawings vertical light and right heavy +\0 | ; 199 C7 box drawings vertical heavy and right light +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal +\0 = ; 207 CF box drawings up light and horizontal heavy +\0 - ; 208 D0 box drawings up heavy and horizontal light +\0 = ; 209 D1 box drawings down light and horizontal heavy +\0 - ; 210 D2 box drawings down heavy and horizontal light +\0 + ; 211 D3 box drawings up heavy and right light +\0 + ; 212 D4 box drawings up light and right heavy +\0 + ; 213 D5 box drawings down light and right heavy +\0 + ; 214 D6 box drawings down heavy and right light +\0 | ; 215 D7 box drawings vertical heavy and horizontal light +\0 + ; 216 D8 box drawings vertical light and horizontal heavy +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 n ; 220 DC lower half block +\0 | ; 221 DD left half block +\0 | ; 222 DE right half block +\0 ~ ; 223 DF upper half block +\0 a ; 224 E0 greek small letter alpha +\0 \xDF ; 225 E1 greek small letter beta (here used as german ss) +\x1 ? ; 226 E2 greek capital letter gamma +p i ; 227 E3 greek small letter pi +\x1 ? ; 228 E4 greek capital letter sigma +\x1 ? ; 229 E5 greek small letter sigma +\0 \xB5 ; 230 E6 greek small letter mu +\x1 ? ; 231 E7 greek small letter tau +\x1 ? ; 232 E8 greek capital letter phi +\x1 ? ; 233 E9 greek capital letter theta +\x1 ? ; 234 EA greek capital letter omega +\0 \xF0 ; 235 EB greek small letter delta +\x1 ? ; 236 EC infinity +/ 0 ; 237 ED empty set +\x1 ? ; 238 EE greek small letter epsilon +\x1 ? ; 239 EF intersection += = ; 240 F0 identical to +\0 \xB1 ; 241 F1 plus-minus sign +> = ; 242 F2 greater-than or equal to +< = ; 243 F3 less-than or equal to +\x1 ? ; 244 F4 top half integral +\x1 ? ; 245 F5 bottom half integral +\0 \xF7 ; 246 F6 division sign +~ = ; 247 F7 almost equal to +\0 \xB0 ; 248 F8 ring operator +\0 . ; 249 F9 middle dot +\0 - ; 250 FA bullet operator +\x1 ? ; 251 FB square root +^ n ; 252 FC superscript latin small letter n +\0 \xB2 ; 253 FD superscript two +\0 \xB7 ; 254 FE black square +\0 \xA0 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_mac.chs b/cfgs/charset/ibm_mac.chs new file mode 100644 index 0000000..3963ef9 --- /dev/null +++ b/cfgs/charset/ibm_mac.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to MAC characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set (actually CP865) +MAC ; to set +; +\0 \x82 ; 128 80 latin capital letter c with cedilla +\0 \x9F ; 129 81 latin small letter u with diaeresis +\0 \x8E ; 130 82 latin small letter e with acute +\0 \x89 ; 131 83 latin small letter a with circumflex +\0 \x8A ; 132 84 latin small letter a with diaeresis +\0 \x88 ; 133 85 latin small letter a with grave +\0 \x8C ; 134 86 latin small letter a with ring above +\0 \x8D ; 135 87 latin small letter c with cedilla +\0 \x90 ; 136 88 latin small letter e with circumflex +\0 \x91 ; 137 89 latin small letter e with diaeresis +\0 \x8F ; 138 8A latin small letter e with grave +\0 \x95 ; 139 8B latin small letter i with diaeresis +\0 \x94 ; 140 8C latin small letter i with circumflex +\0 \x93 ; 141 8D latin small letter i with grave +\0 \x80 ; 142 8E latin capital letter a with diaeresis +\0 \x81 ; 143 8F latin capital letter a with ring above +\0 \x83 ; 144 90 latin capital letter e with acute +\0 \xBE ; 145 91 latin small letter ae +\0 \xAE ; 146 92 latin capital letter ae +\0 \x99 ; 147 93 latin small letter o with circumflex +\0 \x9A ; 148 94 latin small letter o with diaeresis +\0 \x98 ; 149 95 latin small letter o with grave +\0 \x9E ; 150 96 latin small letter u with circumflex +\0 \x9D ; 151 97 latin small letter u with grave +\0 \xD8 ; 152 98 latin small letter y with diaeresis +\0 \x85 ; 153 99 latin capital letter o with diaeresis +\0 \x9F ; 154 9A latin capital letter u with diaeresis +\0 \xA2 ; 155 9B latin small letter o with stroke (CP865 mapping) +\0 \xA3 ; 156 9C pound sign +\0 \xB4 ; 157 9D latin capital letter o with stroke (CP865 mapping) +P t ; 158 9E peseta sign +\0 \xC4 ; 159 9F dutch guilder sign (ibm437 159) +\0 \x87 ; 160 A0 latin small letter a with acute +\0 \x92 ; 161 A1 latin small letter i with acute +\0 \x97 ; 162 A2 latin small letter o with acute +\0 \x9C ; 163 A3 latin small letter u with acute +\0 \x96 ; 164 A4 latin small letter n with tilde +\0 \x84 ; 165 A5 latin capital letter n with tilde +\0 \xBB ; 166 A6 feminine ordinal indicator +\0 \xBC ; 167 A7 masculine ordinal indicator +\0 \xC0 ; 168 A8 inverted question mark +\0 - ; 169 A9 reversed not sign +\0 \xC2 ; 170 AA not sign +. 5 ; 171 AB vulgar fraction one half +\x1 ? ; 172 AC vulgar fraction one quarter +\0 \xC1 ; 173 AD inverted exclamation mark +\0 \xC7 ; 174 AE left-pointing double angle quotation mark +\0 \xC8 ; 175 AF right-pointing double angle quotation mark +\0 # ; 176 B0 light shade +\0 # ; 177 B1 medium shade +\0 # ; 178 B2 dark shade +\0 | ; 179 B3 box drawings light vertical +\0 | ; 180 B4 box drawings light vertical and left +\0 | ; 181 B5 box drawings vertical light and left heavy +\0 | ; 182 B6 box drawings vertical heavy and left light +\0 + ; 183 B7 box drawings down heavy and left light +\0 + ; 184 B8 box drawings down light and left heavy +\0 | ; 185 B9 box drawings heavy vertical and left +\0 | ; 186 BA box drawings heavy vertical +\0 + ; 187 BB box drawings heavy down and left +\0 + ; 188 BC box drawings heavy up and left +\0 + ; 189 BD box drawings up heavy and left light +\0 + ; 190 BE box drawings up light and left heavy +\0 + ; 191 BF box drawings light down and left +\0 + ; 192 C0 box drawings light up and right +\0 - ; 193 C1 box drawings light up and horizontal +\0 - ; 194 C2 box drawings light down and horizontal +\0 | ; 195 C3 box drawings light vertical and right +\0 - ; 196 C4 box drawings light horizontal +\0 + ; 197 C5 box drawings light vertical and horizontal +\0 | ; 198 C6 box drawings vertical light and right heavy +\0 | ; 199 C7 box drawings vertical heavy and right light +\0 + ; 200 C8 box drawings heavy up and right +\0 + ; 201 C9 box drawings heavy down and right +\0 = ; 202 CA box drawings heavy up and horizontal +\0 = ; 203 CB box drawings heavy down and horizontal +\0 | ; 204 CC box drawings heavy vertical and right +\0 = ; 205 CD box drawings heavy horizontal +\0 + ; 206 CE box drawings heavy vertical and horizontal +\0 = ; 207 CF box drawings up light and horizontal heavy +\0 - ; 208 D0 box drawings up heavy and horizontal light +\0 = ; 209 D1 box drawings down light and horizontal heavy +\0 - ; 210 D2 box drawings down heavy and horizontal light +\0 + ; 211 D3 box drawings up heavy and right light +\0 + ; 212 D4 box drawings up light and right heavy +\0 + ; 213 D5 box drawings down light and right heavy +\0 + ; 214 D6 box drawings down heavy and right light +\0 | ; 215 D7 box drawings vertical heavy and horizontal light +\0 + ; 216 D8 box drawings vertical light and horizontal heavy +\0 + ; 217 D9 box drawings light up and left +\0 + ; 218 DA box drawings light down and right +\0 # ; 219 DB full block +\0 n ; 220 DC lower half block +\0 | ; 221 DD left half block +\0 | ; 222 DE right half block +\0 ~ ; 223 DF upper half block +\0 a ; 224 E0 greek small letter alpha +\0 \xA7 ; 225 E1 greek small letter beta (here used as german ss) +\x1 ? ; 226 E2 greek capital letter gamma +\0 \xB9 ; 227 E3 greek small letter pi +\0 \xB7 ; 228 E4 greek capital letter sigma +\x1 ? ; 229 E5 greek small letter sigma +\0 \xB5 ; 230 E6 greek small letter mu +\x1 ? ; 231 E7 greek small letter tau +\x1 ? ; 232 E8 greek capital letter phi +\x1 ? ; 233 E9 greek capital letter theta +\0 \xBD ; 234 EA greek capital letter omega +\0 \xB6 ; 235 EB greek small letter delta +\0 \xB0 ; 236 EC infinity +\0 \xBF ; 237 ED empty set +\x1 ? ; 238 EE greek small letter epsilon +\x1 ? ; 239 EF intersection += = ; 240 F0 identical to +\0 \xB1 ; 241 F1 plus-minus sign +\0 \xB3 ; 242 F2 greater-than or equal to +\0 \xB2 ; 243 F3 less-than or equal to +\x1 ? ; 244 F4 top half integral +\x1 ? ; 245 F5 bottom half integral +\0 \xD6 ; 246 F6 division sign +\0 \xC5 ; 247 F7 almost equal to +\0 \xA1 ; 248 F8 ring operator +\0 . ; 249 F9 middle dot +\0 \xD0 ; 250 FA bullet operator +\0 \xC3 ; 251 FB square root +^ n ; 252 FC superscript latin small letter n +^ 2 ; 253 FD superscript two +\0 \xA5 ; 254 FE black square +\0 \d32 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_mne.chs b/cfgs/charset/ibm_mne.chs new file mode 100644 index 0000000..fd883a7 --- /dev/null +++ b/cfgs/charset/ibm_mne.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to K. Simonsen mnemonics. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set (actually CP865) +MNEMONIC ; to set +; +\d29 C , ; 128 80 latin capital letter c with cedilla +\d29 u : ; 129 81 latin small letter u with diaeresis +\d29 e ' ; 130 82 latin small letter e with acute +\d29 a > ; 131 83 latin small letter a with circumflex +\d29 a : ; 132 84 latin small letter a with diaeresis +\d29 a ! ; 133 85 latin small letter a with grave +\d29 a a ; 134 86 latin small letter a with ring above +\d29 c , ; 135 87 latin small letter c with cedilla +\d29 e > ; 136 88 latin small letter e with circumflex +\d29 e : ; 137 89 latin small letter e with diaeresis +\d29 e ! ; 138 8A latin small letter e with grave +\d29 i : ; 139 8B latin small letter i with diaeresis +\d29 i > ; 140 8C latin small letter i with circumflex +\d29 i ! ; 141 8D latin small letter i with grave +\d29 A : ; 142 8E latin capital letter a with diaeresis +\d29 A A ; 143 8F latin capital letter a with ring above +\d29 E ' ; 144 90 latin capital letter e with acute +\d29 a e ; 145 91 latin small letter ae +\d29 A E ; 146 92 latin capital letter ae +\d29 o > ; 147 93 latin small letter o with circumflex +\d29 o : ; 148 94 latin small letter o with diaeresis +\d29 o ! ; 149 95 latin small letter o with grave +\d29 u > ; 150 96 latin small letter u with circumflex +\d29 u ! ; 151 97 latin small letter u with grave +\d29 y : ; 152 98 latin small letter y with diaeresis +\d29 O : ; 153 99 latin capital letter o with diaeresis +\d29 U : ; 154 9A latin capital letter u with diaeresis +\d29 o / ; 155 9B latin small letter o with stroke (CP865 mapping) +\d29 P d ; 156 9C pound sign +\d29 O / ; 157 9D latin capital letter o with stroke (CP865 mapping) +\d29 P t ; 158 9E peseta sign +\d29 F l ; 159 9F dutch guilder sign (ibm437 159) +\d29 a ' ; 160 A0 latin small letter a with acute +\d29 i ' ; 161 A1 latin small letter i with acute +\d29 o ' ; 162 A2 latin small letter o with acute +\d29 u ' ; 163 A3 latin small letter u with acute +\d29 n ? ; 164 A4 latin small letter n with tilde +\d29 N ? ; 165 A5 latin capital letter n with tilde +\d29 - a ; 166 A6 feminine ordinal indicator +\d29 - o ; 167 A7 masculine ordinal indicator +\d29 ? I ; 168 A8 inverted question mark +\d29 N I ; 169 A9 reversed not sign +\d29 N O ; 170 AA not sign +\d29 1 2 ; 171 AB vulgar fraction one half +\d29 1 4 ; 172 AC vulgar fraction one quarter +\d29 ! I ; 173 AD inverted exclamation mark +\d29 < < ; 174 AE left-pointing double angle quotation mark +\d29 > > ; 175 AF right-pointing double angle quotation mark +\d29 . S ; 176 B0 light shade +\d29 : S ; 177 B1 medium shade +\d29 ? S ; 178 B2 dark shade +\d29 v v ; 179 B3 box drawings light vertical +\d29 v l ; 180 B4 box drawings light vertical and left +\d29 v L ; 181 B5 box drawings vertical light and left heavy +\d29 V l ; 182 B6 box drawings vertical heavy and left light +\d29 D l ; 183 B7 box drawings down heavy and left light +\d29 d L ; 184 B8 box drawings down light and left heavy +\d29 V L ; 185 B9 box drawings heavy vertical and left +\d29 V V ; 186 BA box drawings heavy vertical +\d29 L D ; 187 BB box drawings heavy down and left +\d29 U L ; 188 BC box drawings heavy up and left +\d29 U l ; 189 BD box drawings up heavy and left light +\d29 u L ; 190 BE box drawings up light and left heavy +\d29 d l ; 191 BF box drawings light down and left +\d29 u r ; 192 C0 box drawings light up and right +\d29 u h ; 193 C1 box drawings light up and horizontal +\d29 d h ; 194 C2 box drawings light down and horizontal +\d29 v r ; 195 C3 box drawings light vertical and right +\d29 h h ; 196 C4 box drawings light horizontal +\d29 v h ; 197 C5 box drawings light vertical and horizontal +\d29 v R ; 198 C6 box drawings vertical light and right heavy +\d29 V r ; 199 C7 box drawings vertical heavy and right light +\d29 U R ; 200 C8 box drawings heavy up and right +\d29 D R ; 201 C9 box drawings heavy down and right +\d29 U H ; 202 CA box drawings heavy up and horizontal +\d29 D H ; 203 CB box drawings heavy down and horizontal +\d29 V R ; 204 CC box drawings heavy vertical and right +\d29 H H ; 205 CD box drawings heavy horizontal +\d29 V H ; 206 CE box drawings heavy vertical and horizontal +\d29 u H ; 207 CF box drawings up light and horizontal heavy +\d29 U h ; 208 D0 box drawings up heavy and horizontal light +\d29 d H ; 209 D1 box drawings down light and horizontal heavy +\d29 D h ; 210 D2 box drawings down heavy and horizontal light +\d29 U r ; 211 D3 box drawings up heavy and right light +\d29 u R ; 212 D4 box drawings up light and right heavy +\d29 D r ; 213 D5 box drawings down light and right heavy +\d29 d R ; 214 D6 box drawings down heavy and right light +\d29 V h ; 215 D7 box drawings vertical heavy and horizontal light +\d29 v H ; 216 D8 box drawings vertical light and horizontal heavy +\d29 u l ; 217 D9 box drawings light up and left +\d29 d r ; 218 DA box drawings light down and right +\d29 F B ; 219 DB full block +\d29 L B ; 220 DC lower half block +\d29 l B ; 221 DD left half block +\d29 R B ; 222 DE right half block +\d29 T B ; 223 DF upper half block +\d29 a * ; 224 E0 greek small letter alpha +\d29 b * ; 225 E1 greek small letter beta (here used as german ss) +\d29 G * ; 226 E2 greek capital letter gamma +\d29 p * ; 227 E3 greek small letter pi +\d29 S * ; 228 E4 greek capital letter sigma +\d29 s * ; 229 E5 greek small letter sigma +\d29 m * ; 230 E6 greek small letter mu +\d29 t * ; 231 E7 greek small letter tau +\d29 F * ; 232 E8 greek capital letter phi +\d29 H * ; 233 E9 greek capital letter theta +\d29 W * ; 234 EA greek capital letter omega +\d29 d * ; 235 EB greek small letter delta +\d29 0 0 ; 236 EC infinity +\d29 / 0 ; 237 ED empty set +\d29 e * ; 238 EE greek small letter epsilon +\d29 ( U ; 239 EF intersection +\d29 = 3 ; 240 F0 identical to +\d29 + - ; 241 F1 plus-minus sign +\d29 > = ; 242 F2 greater-than or equal to +\d29 < = ; 243 F3 less-than or equal to +\d29 I u ; 244 F4 top half integral +\d29 I l ; 245 F5 bottom half integral +\d29 - : ; 246 F6 division sign +\d29 ? 2 ; 247 F7 almost equal to +\d29 O b ; 248 F8 ring operator +\d29 . M ; 249 F9 middle dot +\d29 S b ; 250 FA bullet operator +\d29 R T ; 251 FB square root +\d29 n S ; 252 FC superscript latin small letter n +\d29 2 S ; 253 FD superscript two +\d29 f S ; 254 FE black square +\d29 N S ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_swe.chs b/cfgs/charset/ibm_swe.chs new file mode 100644 index 0000000..c4ed61d --- /dev/null +++ b/cfgs/charset/ibm_swe.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to swedish ASCII characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set (actually CP865) +SWEDISH ; to set +; +\0 \d128 ; 128 80 latin capital letter c with cedilla +\0 \d129 ; 129 81 latin small letter u with diaeresis +\0 \d130 ; 130 82 latin small letter e with acute +\0 \d131 ; 131 83 latin small letter a with circumflex +\0 { ; 132 84 latin small letter a with diaeresis +\0 \d133 ; 133 85 latin small letter a with grave +\0 } ; 134 86 latin small letter a with ring above +\0 \d135 ; 135 87 latin small letter c with cedilla +\0 \d136 ; 136 88 latin small letter e with circumflex +\0 \d137 ; 137 89 latin small letter e with diaeresis +\0 \d138 ; 138 8A latin small letter e with grave +\0 \d139 ; 139 8B latin small letter i with diaeresis +\0 \d140 ; 140 8C latin small letter i with circumflex +\0 \d141 ; 141 8D latin small letter i with grave +\0 [ ; 142 8E latin capital letter a with diaeresis +\0 ] ; 143 8F latin capital letter a with ring above +\0 \d064 ; 144 90 latin capital letter e with acute +\0 \d145 ; 145 91 latin small letter ae +\0 \d146 ; 146 92 latin capital letter ae +\0 \d147 ; 147 93 latin small letter o with circumflex +\0 | ; 148 94 latin small letter o with diaeresis +\0 \d149 ; 149 95 latin small letter o with grave +\0 \d150 ; 150 96 latin small letter u with circumflex +\0 \d151 ; 151 97 latin small letter u with grave +\0 \d152 ; 152 98 latin small letter y with diaeresis +\0 \\ ; 153 99 latin capital letter o with diaeresis +\0 \d154 ; 154 9A latin capital letter u with diaeresis +\0 \d155 ; 155 9B latin small letter o with stroke (CP865 mapping) +\0 \d156 ; 156 9C pound sign +\0 \d157 ; 157 9D latin capital letter o with stroke (CP865 mapping) +\0 \d158 ; 158 9E peseta sign +\0 \d159 ; 159 9F dutch guilder sign (ibm437 159) +\0 \d160 ; 160 A0 latin small letter a with acute +\0 \d161 ; 161 A1 latin small letter i with acute +\0 \d162 ; 162 A2 latin small letter o with acute +\0 \d163 ; 163 A3 latin small letter u with acute +\0 \d164 ; 164 A4 latin small letter n with tilde +\0 \d165 ; 165 A5 latin capital letter n with tilde +\0 \d166 ; 166 A6 feminine ordinal indicator +\0 \d167 ; 167 A7 masculine ordinal indicator +\0 \d168 ; 168 A8 inverted question mark +\0 \d169 ; 169 A9 reversed not sign +\0 \d170 ; 170 AA not sign +\0 \d171 ; 171 AB vulgar fraction one half +\0 \d172 ; 172 AC vulgar fraction one quarter +\0 \d173 ; 173 AD inverted exclamation mark +\0 \d174 ; 174 AE left-pointing double angle quotation mark +\0 \d175 ; 175 AF right-pointing double angle quotation mark +\0 \d176 ; 176 B0 light shade +\0 \d177 ; 177 B1 medium shade +\0 \d178 ; 178 B2 dark shade +\0 \d179 ; 179 B3 box drawings light vertical +\0 \d180 ; 180 B4 box drawings light vertical and left +\0 \d181 ; 181 B5 box drawings vertical light and left heavy +\0 \d182 ; 182 B6 box drawings vertical heavy and left light +\0 \d183 ; 183 B7 box drawings down heavy and left light +\0 \d184 ; 184 B8 box drawings down light and left heavy +\0 \d185 ; 185 B9 box drawings heavy vertical and left +\0 \d186 ; 186 BA box drawings heavy vertical +\0 \d187 ; 187 BB box drawings heavy down and left +\0 \d188 ; 188 BC box drawings heavy up and left +\0 \d189 ; 189 BD box drawings up heavy and left light +\0 \d190 ; 190 BE box drawings up light and left heavy +\0 \d191 ; 191 BF box drawings light down and left +\0 \d192 ; 192 C0 box drawings light up and right +\0 \d193 ; 193 C1 box drawings light up and horizontal +\0 \d194 ; 194 C2 box drawings light down and horizontal +\0 \d195 ; 195 C3 box drawings light vertical and right +\0 \d196 ; 196 C4 box drawings light horizontal +\0 \d197 ; 197 C5 box drawings light vertical and horizontal +\0 \d198 ; 198 C6 box drawings vertical light and right heavy +\0 \d199 ; 199 C7 box drawings vertical heavy and right light +\0 \d200 ; 200 C8 box drawings heavy up and right +\0 \d201 ; 201 C9 box drawings heavy down and right +\0 \d202 ; 202 CA box drawings heavy up and horizontal +\0 \d203 ; 203 CB box drawings heavy down and horizontal +\0 \d204 ; 204 CC box drawings heavy vertical and right +\0 \d205 ; 205 CD box drawings heavy horizontal +\0 \d206 ; 206 CE box drawings heavy vertical and horizontal +\0 \d207 ; 207 CF box drawings up light and horizontal heavy +\0 \d208 ; 208 D0 box drawings up heavy and horizontal light +\0 \d209 ; 209 D1 box drawings down light and horizontal heavy +\0 \d210 ; 210 D2 box drawings down heavy and horizontal light +\0 \d211 ; 211 D3 box drawings up heavy and right light +\0 \d212 ; 212 D4 box drawings up light and right heavy +\0 \d213 ; 213 D5 box drawings down light and right heavy +\0 \d214 ; 214 D6 box drawings down heavy and right light +\0 \d215 ; 215 D7 box drawings vertical heavy and horizontal light +\0 \d216 ; 216 D8 box drawings vertical light and horizontal heavy +\0 \d217 ; 217 D9 box drawings light up and left +\0 \d218 ; 218 DA box drawings light down and right +\0 \d219 ; 219 DB full block +\0 \d220 ; 220 DC lower half block +\0 \d221 ; 221 DD left half block +\0 \d222 ; 222 DE right half block +\0 \d223 ; 223 DF upper half block +\0 \d224 ; 224 E0 greek small letter alpha +\0 \d225 ; 225 E1 greek small letter beta (here used as german ss) +\0 \d226 ; 226 E2 greek capital letter gamma +\0 \d227 ; 227 E3 greek small letter pi +\0 \d228 ; 228 E4 greek capital letter sigma +\0 \d229 ; 229 E5 greek small letter sigma +\0 \d230 ; 230 E6 greek small letter mu +\0 \d231 ; 231 E7 greek small letter tau +\0 \d232 ; 232 E8 greek capital letter phi +\0 \d233 ; 233 E9 greek capital letter theta +\0 \d234 ; 234 EA greek capital letter omega +\0 \d235 ; 235 EB greek small letter delta +\0 \d236 ; 236 EC infinity +\0 \d237 ; 237 ED empty set +\0 \d238 ; 238 EE greek small letter epsilon +\0 \d239 ; 239 EF intersection +\0 \d240 ; 240 F0 identical to +\0 \d241 ; 241 F1 plus-minus sign +\0 \d242 ; 242 F2 greater-than or equal to +\0 \d243 ; 243 F3 less-than or equal to +\0 \d244 ; 244 F4 top half integral +\0 \d245 ; 245 F5 bottom half integral +\0 \d246 ; 246 F6 division sign +\0 \d247 ; 247 F7 almost equal to +\0 \d248 ; 248 F8 ring operator +\0 \d249 ; 249 F9 middle dot +\0 \d250 ; 250 FA bullet operator +\0 \d251 ; 251 FB square root +\0 \d252 ; 252 FC superscript latin small letter n +\0 \d253 ; 253 FD superscript two +\0 \d254 ; 254 FE black square +\0 \d255 ; 255 FF no-break space +END diff --git a/cfgs/charset/ibm_vt1.chs b/cfgs/charset/ibm_vt1.chs new file mode 100644 index 0000000..b4b6203 --- /dev/null +++ b/cfgs/charset/ibm_vt1.chs @@ -0,0 +1,164 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts IBM extended characters to VT100. +; +; NOTE: this file uses an implementation dependant feature! +; a 0 as the second character means "use DEC graphic set" +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +IBMPC ; from set +VT100 ; to set +; +\0 C ; C with cedilla +u e ; u dieresis +\0 e ; e acute +\0 a ; a circumflex +a e ; a dieresis +\0 a ; a grave +\0 a ; a ring +\0 c ; c cedilla +\0 e ; e circumflex +e e ; e dieresis +\0 e ; e grave +i e ; i dieresis +\0 i ; i circumflex +\0 i ; i grave +A e ; A dieresis +\0 A ; A ring +\0 E ; E acute +a e ; ae +A E ; AE +\0 o ; o circumflex +o e ; o dieresis +\0 o ; o acute +\0 u ; u circumflex +\0 u ; u grave +y e ; y dieresis +O e ; O dieresis +U e ; U dieresis +\0 c ; cent +\d125 \0 ; pound sterling +\0 Y ; yen +P t ; Pt +\0 f ; florin +\0 a ; a acute +\0 i ; i grave +\0 o ; o grave +\0 u ; u grave +\0 n ; n tilde +\0 N ; N tilde +\0 a ; ord feminine +\0 o ; ord masculine +\0 ? ; question downwards +\0 - ; +\0 ! ; logical not +. 5 ; half fraction +\x1 ? ; quarter fraction +\0 ! ; exclam downwards +< < ; guillemot left +> > ; guillemot right +\0 # ; grey +\d97 \0 ; grey +\d97 \0 ; grey +\d120 \0 ; | +\d117 \0 ; -| +\d117 \0 ; -| +\d117 \0 ; -| +\d107 \0 ; + +\d107 \0 ; + +\d117 \0 ; -| +\d120 \0 ; | +\d107 \0 ; + +\d106 \0 ; + +\d106 \0 ; + +\d106 \0 ; + +\d107 \0 ; + +\d109 \0 ; + +\d118 \0 ; - +\d119 \0 ; - +\d116 \0 ; |- +\d113 \0 ; - +\d110 \0 ; -|- +\d116 \0 ; |- +\d116 \0 ; |- +\d109 \0 ; + +\d108 \0 ; + +\d118 \0 ; - +\d119 \0 ; - +\d116 \0 ; |- +\d113 \0 ; - +\d110 \0 ; -|- +\d118 \0 ; - +\d118 \0 ; - +\d119 \0 ; - +\d119 \0 ; - +\d109 \0 ; + +\d109 \0 ; + +\d108 \0 ; + +\d108 \0 ; + +\d110 \0 ; -|- +\d110 \0 ; -|- +\d106 \0 ; + +\d108 \0 ; + +\0 # ; +\0 n ; +\0 | ; +\0 | ; +\0 ~ ; +\0 a ; alpha +\0 B ; german double s (misused as Beta) +\x1 ? ; Gamma +\d123 \0 ; pi +\x1 ? ; Sigma (summation) +\x1 ? ; sigma +m u ; mu +\x1 ? ; gamma +\x1 ? ; Phi +\x1 ? ; Theta +\0 O ; Omega +\0 d ; delta +\x1 ? ; infinity +\0 o ; o slash +\x1 ? ; element +\x1 ? ; intersection += = ; equivalence +\d103 \0 ; plusminus +\d122 \0 ; greater equals +\d121 \0 ; smaller equals +\x1 ? ; integral top +\x1 ? ; integral bottom +\0 / ; divide +~ = ; approx. +\d102 \0 ; ring / degree +\d126 \0 ; centered dot +\0 - ; en dash +\x1 ? ; radical +^ n ; to the n'th power +^ 2 ; to the second power +\0 o ; +\0 \d32 ; space +END diff --git a/cfgs/charset/iqp_850.chs b/cfgs/charset/iqp_850.chs new file mode 100644 index 0000000..f1b3cc5 --- /dev/null +++ b/cfgs/charset/iqp_850.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO 8859-1 extended characters to IBM CP850 characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN1QP ; from set +CP850 ; to set +; +\0 \d128 ; 128 80 (missing) These codes are unused in the LATIN-1 set. +\0 \d129 ; 129 81 (missing) For transparency, these are not mapped. +\0 \d130 ; 130 82 (missing) +\0 \d131 ; 131 83 (missing) 4 +\0 \d132 ; 132 84 (missing) +\0 \d133 ; 133 85 (missing) +\0 \d134 ; 134 86 (missing) +\0 \d135 ; 135 87 (missing) 8 +\0 \d136 ; 136 88 (missing) +\0 \d137 ; 137 89 (missing) +\0 \d138 ; 138 8A (missing) +\0 \d139 ; 139 8B (missing) 12 +\0 \d140 ; 140 8C (missing) +\0 \d141 ; 141 8D (missing) +\0 \d142 ; 142 8E (missing) +\0 \d143 ; 143 8F (missing) 16 +\0 \d144 ; 144 90 (missing) +\0 \d145 ; 145 91 (missing) +\0 \d146 ; 146 92 (missing) +\0 \d147 ; 147 93 (missing) 20 +\0 \d148 ; 148 94 (missing) +\0 \d149 ; 149 95 (missing) +\0 \d150 ; 150 96 (missing) +\0 \d151 ; 151 97 (missing) 24 +\0 \d152 ; 152 98 (missing) +\0 \d153 ; 153 99 (missing) +\0 \d154 ; 154 9A (missing) +\0 \d155 ; 155 9B (missing) 28 +\0 \d156 ; 156 9C (missing) +\0 \d157 ; 157 9D (missing) +\0 \d158 ; 158 9E (missing) +\0 \d159 ; 159 9F (missing) 32 +\0 \xFF ; 160 A0 no-break space +\0 \xAD ; 161 A1 inverted exclamation mark +\0 \xBD ; 162 A2 cent sign +\0 \x9C ; 163 A3 pound sign +\0 \xCF ; 164 A4 currency sign +\0 \xBE ; 165 A5 yen sign +\0 \xDD ; 166 A6 broken bar +\0 \xF5 ; 167 A7 section sign +\0 \xF9 ; 168 A8 diaeresis +\0 \xB8 ; 169 A9 copyright sign +\0 \xA6 ; 170 AA feminine ordinal indicator +\0 \xAE ; 171 AB left-pointing double angle quotation mark +\0 \xAA ; 172 AC not sign +\0 \xF0 ; 173 AD soft hyphen +\0 \xA9 ; 174 AE registered sign +\0 \xEE ; 175 AF overline +\0 \xF8 ; 176 B0 degree sign +\0 \xF1 ; 177 B1 plus-minus sign +\0 \xFD ; 178 B2 superscript two +\0 \xFC ; 179 B3 superscript three +\0 \xEF ; 180 B4 acute accent +\0 \xE6 ; 181 B5 micro sign +\0 \xF4 ; 182 B6 pilcrow sign +\0 \xFE ; 183 B7 middle dot +\0 \xF7 ; 184 B8 cedilla +\0 \xFB ; 185 B9 superscript one +\0 \xA7 ; 186 BA masculine ordinal indicator +\0 \xAF ; 187 BB right-pointing double angle quotation mark +\0 \xAC ; 188 BC vulgar fraction one quarter +\0 \xAB ; 189 BD vulgar fraction one half +\0 \xF3 ; 190 BE vulgar fraction three quarters +\0 \xA8 ; 191 BF inverted question mark +\0 \xB7 ; 192 C0 latin capital letter a with grave +\0 \xB5 ; 193 C1 latin capital letter a with acute +\0 \xB6 ; 194 C2 latin capital letter a with circumflex +\0 \xC7 ; 195 C3 latin capital letter a with tilde +\0 \x8E ; 196 C4 latin capital letter a with diaeresis +\0 \x8F ; 197 C5 latin capital letter a with ring above +\0 \x92 ; 198 C6 latin capital letter ae +\0 \x80 ; 199 C7 latin capital letter c with cedilla +\0 \xD4 ; 200 C8 latin capital letter e with grave +\0 \x90 ; 201 C9 latin capital letter e with acute +\0 \xD2 ; 202 CA latin capital letter e with circumflex +\0 \xD3 ; 203 CB latin capital letter e with diaeresis +\0 \xDE ; 204 CC latin capital letter i with grave +\0 \xD6 ; 205 CD latin capital letter i with acute +\0 \xD7 ; 206 CE latin capital letter i with circumflex +\0 \xD8 ; 207 CF latin capital letter i with diaeresis +\0 \xD1 ; 208 D0 latin capital letter eth (icelandic) +\0 \xA5 ; 209 D1 latin capital letter n with tilde +\0 \xE3 ; 210 D2 latin capital letter o with grave +\0 \xE0 ; 211 D3 latin capital letter o with acute +\0 \xE2 ; 212 D4 latin capital letter o with circumflex +\0 \xE5 ; 213 D5 latin capital letter o with tilde +\0 \x99 ; 214 D6 latin capital letter o with diaeresis +\0 \x9E ; 215 D7 multiplication sign +\0 \x9D ; 216 D8 latin capital letter o with stroke +\0 \xEB ; 217 D9 latin capital letter u with grave +\0 \xE9 ; 218 DA latin capital letter u with acute +\0 \xEA ; 219 DB latin capital letter u with circumflex +\0 \x9A ; 220 DC latin capital letter u with diaeresis +\0 \xED ; 221 DD latin capital letter y with acute +\0 \xE7 ; 222 DE latin capital letter thorn (icelandic) +\0 \xE1 ; 223 DF latin small letter sharp s (german) +\0 \x85 ; 224 E0 latin small letter a with grave +\0 \xA0 ; 225 E1 latin small letter a with acute +\0 \x83 ; 226 E2 latin small letter a with circumflex +\0 \xC6 ; 227 E3 latin small letter a with tilde +\0 \x84 ; 228 E4 latin small letter a with diaeresis +\0 \x86 ; 229 E5 latin small letter a with ring above +\0 \x91 ; 230 E6 latin small letter ae +\0 \x87 ; 231 E7 latin small letter c with cedilla +\0 \x8A ; 232 E8 latin small letter e with grave +\0 \x82 ; 233 E9 latin small letter e with acute +\0 \x88 ; 234 EA latin small letter e with circumflex +\0 \x89 ; 235 EB latin small letter e with diaeresis +\0 \x8D ; 236 EC latin small letter i with grave +\0 \xA1 ; 237 ED latin small letter i with acute +\0 \x8C ; 238 EE latin small letter i with circumflex +\0 \x8B ; 239 EF latin small letter i with diaeresis +\0 \xD0 ; 240 F0 latin small letter eth (icelandic) +\0 \xA4 ; 241 F1 latin small letter n with tilde +\0 \x95 ; 242 F2 latin small letter o with grave +\0 \xA2 ; 243 F3 latin small letter o with acute +\0 \x93 ; 244 F4 latin small letter o with circumflex +\0 \xE4 ; 245 F5 latin small letter o with tilde +\0 \x94 ; 246 F6 latin small letter o with diaeresis +\0 \xF6 ; 247 F7 division sign +\0 \x9B ; 248 F8 latin small letter o with stroke +\0 \x97 ; 249 F9 latin small letter u with grave +\0 \xA3 ; 250 FA latin small letter u with acute +\0 \x96 ; 251 FB latin small letter u with circumflex +\0 \x81 ; 252 FC latin small letter u with diaeresis +\0 \xEC ; 253 FD latin small letter y with acute +\0 \xE8 ; 254 FE latin small letter thorn (icelandic) +\0 \x98 ; 255 FF latin small letter y with diaeresis +END diff --git a/cfgs/charset/iqp_ibm.chs b/cfgs/charset/iqp_ibm.chs new file mode 100644 index 0000000..cd2e609 --- /dev/null +++ b/cfgs/charset/iqp_ibm.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO_8859-1 extended characters to IBM-PC characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN1QP ; from set +IBMPC ; to set (actually CP865) +; +\0 \d128 ; 128 80 (missing) These codes are unused in the LATIN-1 set. +\0 \d129 ; 129 81 (missing) For transparency, these are not mapped. +\0 \d130 ; 130 82 (missing) +\0 \d131 ; 131 83 (missing) 4 +\0 \d132 ; 132 84 (missing) +\0 \d133 ; 133 85 (missing) +\0 \d134 ; 134 86 (missing) +\0 \d135 ; 135 87 (missing) 8 +\0 \d136 ; 136 88 (missing) +\0 \d137 ; 137 89 (missing) +\0 \d138 ; 138 8A (missing) +\0 \d139 ; 139 8B (missing) 12 +\0 \d140 ; 140 8C (missing) +\0 \d141 ; 141 8D (missing) +\0 \d142 ; 142 8E (missing) +\0 \d143 ; 143 8F (missing) 16 +\0 \d144 ; 144 90 (missing) +\0 \d145 ; 145 91 (missing) +\0 \d146 ; 146 92 (missing) +\0 \d147 ; 147 93 (missing) 20 +\0 \d148 ; 148 94 (missing) +\0 \d149 ; 149 95 (missing) +\0 \d150 ; 150 96 (missing) +\0 \d151 ; 151 97 (missing) 24 +\0 \d152 ; 152 98 (missing) +\0 \d153 ; 153 99 (missing) +\0 \d154 ; 154 9A (missing) +\0 \d155 ; 155 9B (missing) 28 +\0 \d156 ; 156 9C (missing) +\0 \d157 ; 157 9D (missing) +\0 \d158 ; 158 9E (missing) +\0 \d159 ; 159 9F (missing) 32 +\0 \xFF ; 160 A0 no-break space +\0 \xAD ; 161 A1 inverted exclamation mark +\0 \x9B ; 162 A2 cent sign +\0 \x9C ; 163 A3 pound sign +\0 \x0F ; 164 A4 currency sign +\0 \x9D ; 165 A5 yen sign +\0 | ; 166 A6 broken bar +\0 \x15 ; 167 A7 section sign +\0 " ; 168 A8 diaeresis +\0 c ; 169 A9 copyright sign +\0 \xA6 ; 170 AA feminine ordinal indicator +\0 \xAE ; 171 AB left-pointing double angle quotation mark +\0 \xAA ; 172 AC not sign +\0 - ; 173 AD soft hyphen +\0 R ; 174 AE registered sign +\0 - ; 175 AF overline +\0 \xF8 ; 176 B0 degree sign +\0 \xF1 ; 177 B1 plus-minus sign +\0 \xFD ; 178 B2 superscript two +^ 3 ; 179 B3 superscript three +\0 ' ; 180 B4 acute accent +\0 \xE6 ; 181 B5 micro sign +\0 \x14 ; 182 B6 pilcrow sign +\0 \xFE ; 183 B7 middle dot +\0 , ; 184 B8 cedilla +^ 1 ; 185 B9 superscript one +\0 \xA7 ; 186 BA masculine ordinal indicator +\0 \xAF ; 187 BB right-pointing double angle quotation mark +\0 \xAC ; 188 BC vulgar fraction one quarter +\0 \xAB ; 189 BD vulgar fraction one half +3 / 4 ; 190 BE vulgar fraction three quarters +\0 \xA8 ; 191 BF inverted question mark +\0 A ; 192 C0 latin capital letter a with grave +\0 A ; 193 C1 latin capital letter a with acute +\0 A ; 194 C2 latin capital letter a with circumflex +\0 A ; 195 C3 latin capital letter a with tilde +\0 \x8E ; 196 C4 latin capital letter a with diaeresis +\0 \x8F ; 197 C5 latin capital letter a with ring above +\0 \x92 ; 198 C6 latin capital letter ae +\0 \x80 ; 199 C7 latin capital letter c with cedilla +\0 E ; 200 C8 latin capital letter e with grave +\0 \x90 ; 201 C9 latin capital letter e with acute +\0 E ; 202 CA latin capital letter e with circumflex +E e ; 203 CB latin capital letter e with diaeresis +\0 I ; 204 CC latin capital letter i with grave +\0 I ; 205 CD latin capital letter i with acute +\0 I ; 206 CE latin capital letter i with circumflex +I e ; 207 CF latin capital letter i with diaeresis +\0 D ; 208 D0 latin capital letter eth (icelandic) +\0 \xA5 ; 209 D1 latin capital letter n with tilde +\0 O ; 210 D2 latin capital letter o with grave +\0 O ; 211 D3 latin capital letter o with acute +\0 O ; 212 D4 latin capital letter o with circumflex +\0 O ; 213 D5 latin capital letter o with tilde +\0 \x99 ; 214 D6 latin capital letter o with diaeresis +\0 x ; 215 D7 multiplication sign +\0 \x9D ; 216 D8 latin capital letter o with stroke (CP865 mapping) +\0 U ; 217 D9 latin capital letter u with grave +\0 U ; 218 DA latin capital letter u with acute +\0 U ; 219 DB latin capital letter u with circumflex +\0 \x9A ; 220 DC latin capital letter u with diaeresis +\0 Y ; 221 DD latin capital letter y with acute +T h ; 222 DE latin capital letter thorn (icelandic) +\0 \xE1 ; 223 DF latin small letter sharp s (german) +\0 \x85 ; 224 E0 latin small letter a with grave +\0 \xA0 ; 225 E1 latin small letter a with acute +\0 \x83 ; 226 E2 latin small letter a with circumflex +\0 a ; 227 E3 latin small letter a with tilde +\0 \x84 ; 228 E4 latin small letter a with diaeresis +\0 \x86 ; 229 E5 latin small letter a with ring above +\0 \x91 ; 230 E6 latin small letter ae +\0 \x87 ; 231 E7 latin small letter c with cedilla +\0 \x8A ; 232 E8 latin small letter e with grave +\0 \x82 ; 233 E9 latin small letter e with acute +\0 \x88 ; 234 EA latin small letter e with circumflex +\0 \x89 ; 235 EB latin small letter e with diaeresis +\0 \x8D ; 236 EC latin small letter i with grave +\0 \xA1 ; 237 ED latin small letter i with acute +\0 \x8C ; 238 EE latin small letter i with circumflex +\0 \x8B ; 239 EF latin small letter i with diaeresis +\0 \xE7 ; 240 F0 latin small letter eth (icelandic) +\0 \xA4 ; 241 F1 latin small letter n with tilde +\0 \x95 ; 242 F2 latin small letter o with grave +\0 \xA2 ; 243 F3 latin small letter o with acute +\0 \x93 ; 244 F4 latin small letter o with circumflex +\0 o ; 245 F5 latin small letter o with tilde +\0 \x94 ; 246 F6 latin small letter o with diaeresis +\0 \xF6 ; 247 F7 division sign +\0 \x9B ; 248 F8 latin small letter o with stroke (CP865 mapping) +\0 \x97 ; 249 F9 latin small letter u with grave +\0 \xA3 ; 250 FA latin small letter u with acute +\0 \x96 ; 251 FB latin small letter u with circumflex +\0 \x81 ; 252 FC latin small letter u with diaeresis +y e ; 253 FD latin small letter y with acute +t h ; 254 FE latin small letter thorn (icelandic) +\0 \x98 ; 255 FF latin small letter y with diaeresis +END diff --git a/cfgs/charset/iso_850.chs b/cfgs/charset/iso_850.chs new file mode 100644 index 0000000..c5f7f65 --- /dev/null +++ b/cfgs/charset/iso_850.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO 8859-1 extended characters to IBM CP850 characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN-1 ; from set +CP850 ; to set +; +\0 \d128 ; 128 80 (missing) These codes are unused in the LATIN-1 set. +\0 \d129 ; 129 81 (missing) For transparency, these are not mapped. +\0 \d130 ; 130 82 (missing) +\0 \d131 ; 131 83 (missing) 4 +\0 \d132 ; 132 84 (missing) +\0 \d133 ; 133 85 (missing) +\0 \d134 ; 134 86 (missing) +\0 \d135 ; 135 87 (missing) 8 +\0 \d136 ; 136 88 (missing) +\0 \d137 ; 137 89 (missing) +\0 \d138 ; 138 8A (missing) +\0 \d139 ; 139 8B (missing) 12 +\0 \d140 ; 140 8C (missing) +\0 \d141 ; 141 8D (missing) +\0 \d142 ; 142 8E (missing) +\0 \d143 ; 143 8F (missing) 16 +\0 \d144 ; 144 90 (missing) +\0 \d145 ; 145 91 (missing) +\0 \d146 ; 146 92 (missing) +\0 \d147 ; 147 93 (missing) 20 +\0 \d148 ; 148 94 (missing) +\0 \d149 ; 149 95 (missing) +\0 \d150 ; 150 96 (missing) +\0 \d151 ; 151 97 (missing) 24 +\0 \d152 ; 152 98 (missing) +\0 \d153 ; 153 99 (missing) +\0 \d154 ; 154 9A (missing) +\0 \d155 ; 155 9B (missing) 28 +\0 \d156 ; 156 9C (missing) +\0 \d157 ; 157 9D (missing) +\0 \d158 ; 158 9E (missing) +\0 \d159 ; 159 9F (missing) 32 +\0 \xFF ; 160 A0 no-break space +\0 \xAD ; 161 A1 inverted exclamation mark +\0 \xBD ; 162 A2 cent sign +\0 \x9C ; 163 A3 pound sign +\0 \xCF ; 164 A4 currency sign +\0 \xBE ; 165 A5 yen sign +\0 \xDD ; 166 A6 broken bar +\0 \xF5 ; 167 A7 section sign +\0 \xF9 ; 168 A8 diaeresis +\0 \xB8 ; 169 A9 copyright sign +\0 \xA6 ; 170 AA feminine ordinal indicator +\0 \xAE ; 171 AB left-pointing double angle quotation mark +\0 \xAA ; 172 AC not sign +\0 \xF0 ; 173 AD soft hyphen +\0 \xA9 ; 174 AE registered sign +\0 \xEE ; 175 AF overline +\0 \xF8 ; 176 B0 degree sign +\0 \xF1 ; 177 B1 plus-minus sign +\0 \xFD ; 178 B2 superscript two +\0 \xFC ; 179 B3 superscript three +\0 \xEF ; 180 B4 acute accent +\0 \xE6 ; 181 B5 micro sign +\0 \xF4 ; 182 B6 pilcrow sign +\0 \xFE ; 183 B7 middle dot +\0 \xF7 ; 184 B8 cedilla +\0 \xFB ; 185 B9 superscript one +\0 \xA7 ; 186 BA masculine ordinal indicator +\0 \xAF ; 187 BB right-pointing double angle quotation mark +\0 \xAC ; 188 BC vulgar fraction one quarter +\0 \xAB ; 189 BD vulgar fraction one half +\0 \xF3 ; 190 BE vulgar fraction three quarters +\0 \xA8 ; 191 BF inverted question mark +\0 \xB7 ; 192 C0 latin capital letter a with grave +\0 \xB5 ; 193 C1 latin capital letter a with acute +\0 \xB6 ; 194 C2 latin capital letter a with circumflex +\0 \xC7 ; 195 C3 latin capital letter a with tilde +\0 \x8E ; 196 C4 latin capital letter a with diaeresis +\0 \x8F ; 197 C5 latin capital letter a with ring above +\0 \x92 ; 198 C6 latin capital letter ae +\0 \x80 ; 199 C7 latin capital letter c with cedilla +\0 \xD4 ; 200 C8 latin capital letter e with grave +\0 \x90 ; 201 C9 latin capital letter e with acute +\0 \xD2 ; 202 CA latin capital letter e with circumflex +\0 \xD3 ; 203 CB latin capital letter e with diaeresis +\0 \xDE ; 204 CC latin capital letter i with grave +\0 \xD6 ; 205 CD latin capital letter i with acute +\0 \xD7 ; 206 CE latin capital letter i with circumflex +\0 \xD8 ; 207 CF latin capital letter i with diaeresis +\0 \xD1 ; 208 D0 latin capital letter eth (icelandic) +\0 \xA5 ; 209 D1 latin capital letter n with tilde +\0 \xE3 ; 210 D2 latin capital letter o with grave +\0 \xE0 ; 211 D3 latin capital letter o with acute +\0 \xE2 ; 212 D4 latin capital letter o with circumflex +\0 \xE5 ; 213 D5 latin capital letter o with tilde +\0 \x99 ; 214 D6 latin capital letter o with diaeresis +\0 \x9E ; 215 D7 multiplication sign +\0 \x9D ; 216 D8 latin capital letter o with stroke +\0 \xEB ; 217 D9 latin capital letter u with grave +\0 \xE9 ; 218 DA latin capital letter u with acute +\0 \xEA ; 219 DB latin capital letter u with circumflex +\0 \x9A ; 220 DC latin capital letter u with diaeresis +\0 \xED ; 221 DD latin capital letter y with acute +\0 \xE7 ; 222 DE latin capital letter thorn (icelandic) +\0 \xE1 ; 223 DF latin small letter sharp s (german) +\0 \x85 ; 224 E0 latin small letter a with grave +\0 \xA0 ; 225 E1 latin small letter a with acute +\0 \x83 ; 226 E2 latin small letter a with circumflex +\0 \xC6 ; 227 E3 latin small letter a with tilde +\0 \x84 ; 228 E4 latin small letter a with diaeresis +\0 \x86 ; 229 E5 latin small letter a with ring above +\0 \x91 ; 230 E6 latin small letter ae +\0 \x87 ; 231 E7 latin small letter c with cedilla +\0 \x8A ; 232 E8 latin small letter e with grave +\0 \x82 ; 233 E9 latin small letter e with acute +\0 \x88 ; 234 EA latin small letter e with circumflex +\0 \x89 ; 235 EB latin small letter e with diaeresis +\0 \x8D ; 236 EC latin small letter i with grave +\0 \xA1 ; 237 ED latin small letter i with acute +\0 \x8C ; 238 EE latin small letter i with circumflex +\0 \x8B ; 239 EF latin small letter i with diaeresis +\0 \xD0 ; 240 F0 latin small letter eth (icelandic) +\0 \xA4 ; 241 F1 latin small letter n with tilde +\0 \x95 ; 242 F2 latin small letter o with grave +\0 \xA2 ; 243 F3 latin small letter o with acute +\0 \x93 ; 244 F4 latin small letter o with circumflex +\0 \xE4 ; 245 F5 latin small letter o with tilde +\0 \x94 ; 246 F6 latin small letter o with diaeresis +\0 \xF6 ; 247 F7 division sign +\0 \x9B ; 248 F8 latin small letter o with stroke +\0 \x97 ; 249 F9 latin small letter u with grave +\0 \xA3 ; 250 FA latin small letter u with acute +\0 \x96 ; 251 FB latin small letter u with circumflex +\0 \x81 ; 252 FC latin small letter u with diaeresis +\0 \xEC ; 253 FD latin small letter y with acute +\0 \xE8 ; 254 FE latin small letter thorn (icelandic) +\0 \x98 ; 255 FF latin small letter y with diaeresis +END diff --git a/cfgs/charset/iso_asc.chs b/cfgs/charset/iso_asc.chs new file mode 100644 index 0000000..66db52b --- /dev/null +++ b/cfgs/charset/iso_asc.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO 8859-1 extended characters to ASCII characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN-1 ; from set +ASCII ; to set +; +\0 ? ; (missing) these codes are unused +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 4 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 8 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 12 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 16 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 20 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 24 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 28 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 32 +\0 \d32 ; non-breaking space +\0 ! ; exclam downwards +\0 c ; cent +\0 # ; pound sterling +\x1 ? ; currency +\0 Y ; Yen +\0 | ; broken bar +\0 S ; section +\x1 ? ; dieresis +\0 c ; copyright +\0 a ; ord feminine +< < ; guillemot left +\0 ! ; logical not +\0 - ; soft hyphen (or em dash) +\0 R ; registered trademark +\x1 ? ; overbar (macron) +\0 o ; ring / degree ++ - ; plusminus +^ 2 ; superscript two (squared) +^ 3 ; superscript three (cubed) +\0 ' ; acute +m u ; mu +\x1 ? ; paragraph +\0 o ; bullet +\0 , ; cedilla +^ 1 ; superscript one +\0 o ; ord masculine +> > ; guillemot right +\x1 ? ; one quarter +. 5 ; half +\x1 ? ; three quarters +\0 ? ; question downwards +\0 A ; A grave +\0 A ; A acute +\0 A ; A circumflex +\0 A ; A tilde +A e ; A dieresis +\0 A ; A ring +A E ; AE +\0 C ; C cedilla +\0 E ; E grave +\0 E ; E acute +\0 E ; E circumflex +E e ; E dieresis +\0 I ; I grave +\0 I ; I acute +\0 I ; I circumflex +I e ; I dieresis +\0 D ; Eth +\0 N ; N tilde +\0 O ; O grave +\0 O ; O acute +\0 O ; O circumflex +\0 O ; O tilde +O e ; O dieresis +\0 x ; multiplication +\0 0 ; O slash +\0 U ; U grave +\0 U ; U acute +\0 U ; U circumflex +U e ; U dieresis +\0 Y ; Y acute +\x1 ? ; Thorn +\0 B ; german double s / beta +\0 a ; a grave +\0 a ; a acute +\0 a ; a circumflex +\0 a ; a tilde +a e ; a dieresis +\0 a ; a ring +a e ; ae +\0 c ; c cedilla +\0 e ; e grave +\0 e ; e acute +\0 e ; e circumflex +e e ; e dieresis +\0 i ; i grave +\0 i ; i acute +\0 i ; i circumflex +i e ; i dieresis +\x1 ? ; eth +\0 n ; n tilde +\0 o ; o grave +\0 o ; o acute +\0 o ; o circumflex +\0 o ; o tilde +o e ; o dieresis +\0 / ; division +\0 o ; o slash +\0 u ; u grave +\0 u ; u acute +\0 u ; u circumflex +u e ; u dieresis +y e ; y acute +\x1 ? ; thorn +y e ; y dieresis +END diff --git a/cfgs/charset/iso_ibm.chs b/cfgs/charset/iso_ibm.chs new file mode 100644 index 0000000..f8b6731 --- /dev/null +++ b/cfgs/charset/iso_ibm.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO_8859-1 extended characters to IBM-PC characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN-1 ; from set +IBMPC ; to set (actually CP865) +; +\0 \d128 ; 128 80 (missing) These codes are unused in the LATIN-1 set. +\0 \d129 ; 129 81 (missing) For transparency, these are not mapped. +\0 \d130 ; 130 82 (missing) +\0 \d131 ; 131 83 (missing) 4 +\0 \d132 ; 132 84 (missing) +\0 \d133 ; 133 85 (missing) +\0 \d134 ; 134 86 (missing) +\0 \d135 ; 135 87 (missing) 8 +\0 \d136 ; 136 88 (missing) +\0 \d137 ; 137 89 (missing) +\0 \d138 ; 138 8A (missing) +\0 \d139 ; 139 8B (missing) 12 +\0 \d140 ; 140 8C (missing) +\0 \d141 ; 141 8D (missing) +\0 \d142 ; 142 8E (missing) +\0 \d143 ; 143 8F (missing) 16 +\0 \d144 ; 144 90 (missing) +\0 \d145 ; 145 91 (missing) +\0 \d146 ; 146 92 (missing) +\0 \d147 ; 147 93 (missing) 20 +\0 \d148 ; 148 94 (missing) +\0 \d149 ; 149 95 (missing) +\0 \d150 ; 150 96 (missing) +\0 \d151 ; 151 97 (missing) 24 +\0 \d152 ; 152 98 (missing) +\0 \d153 ; 153 99 (missing) +\0 \d154 ; 154 9A (missing) +\0 \d155 ; 155 9B (missing) 28 +\0 \d156 ; 156 9C (missing) +\0 \d157 ; 157 9D (missing) +\0 \d158 ; 158 9E (missing) +\0 \d159 ; 159 9F (missing) 32 +\0 \xFF ; 160 A0 no-break space +\0 \xAD ; 161 A1 inverted exclamation mark +\0 \x9B ; 162 A2 cent sign +\0 \x9C ; 163 A3 pound sign +\0 \x0F ; 164 A4 currency sign +\0 \x9D ; 165 A5 yen sign +\0 | ; 166 A6 broken bar +\0 \x15 ; 167 A7 section sign +\0 " ; 168 A8 diaeresis +\0 c ; 169 A9 copyright sign +\0 \xA6 ; 170 AA feminine ordinal indicator +\0 \xAE ; 171 AB left-pointing double angle quotation mark +\0 \xAA ; 172 AC not sign +\0 - ; 173 AD soft hyphen +\0 R ; 174 AE registered sign +\0 - ; 175 AF overline +\0 \xF8 ; 176 B0 degree sign +\0 \xF1 ; 177 B1 plus-minus sign +\0 \xFD ; 178 B2 superscript two +^ 3 ; 179 B3 superscript three +\0 ' ; 180 B4 acute accent +\0 \xE6 ; 181 B5 micro sign +\0 \x14 ; 182 B6 pilcrow sign +\0 \xFE ; 183 B7 middle dot +\0 , ; 184 B8 cedilla +^ 1 ; 185 B9 superscript one +\0 \xA7 ; 186 BA masculine ordinal indicator +\0 \xAF ; 187 BB right-pointing double angle quotation mark +\0 \xAC ; 188 BC vulgar fraction one quarter +\0 \xAB ; 189 BD vulgar fraction one half +3 / 4 ; 190 BE vulgar fraction three quarters +\0 \xA8 ; 191 BF inverted question mark +\0 A ; 192 C0 latin capital letter a with grave +\0 A ; 193 C1 latin capital letter a with acute +\0 A ; 194 C2 latin capital letter a with circumflex +\0 A ; 195 C3 latin capital letter a with tilde +\0 \x8E ; 196 C4 latin capital letter a with diaeresis +\0 \x8F ; 197 C5 latin capital letter a with ring above +\0 \x92 ; 198 C6 latin capital letter ae +\0 \x80 ; 199 C7 latin capital letter c with cedilla +\0 E ; 200 C8 latin capital letter e with grave +\0 \x90 ; 201 C9 latin capital letter e with acute +\0 E ; 202 CA latin capital letter e with circumflex +E e ; 203 CB latin capital letter e with diaeresis +\0 I ; 204 CC latin capital letter i with grave +\0 I ; 205 CD latin capital letter i with acute +\0 I ; 206 CE latin capital letter i with circumflex +I e ; 207 CF latin capital letter i with diaeresis +\0 D ; 208 D0 latin capital letter eth (icelandic) +\0 \xA5 ; 209 D1 latin capital letter n with tilde +\0 O ; 210 D2 latin capital letter o with grave +\0 O ; 211 D3 latin capital letter o with acute +\0 O ; 212 D4 latin capital letter o with circumflex +\0 O ; 213 D5 latin capital letter o with tilde +\0 \x99 ; 214 D6 latin capital letter o with diaeresis +\0 x ; 215 D7 multiplication sign +\0 \x9D ; 216 D8 latin capital letter o with stroke (CP865 mapping) +\0 U ; 217 D9 latin capital letter u with grave +\0 U ; 218 DA latin capital letter u with acute +\0 U ; 219 DB latin capital letter u with circumflex +\0 \x9A ; 220 DC latin capital letter u with diaeresis +\0 Y ; 221 DD latin capital letter y with acute +T h ; 222 DE latin capital letter thorn (icelandic) +\0 \xE1 ; 223 DF latin small letter sharp s (german) +\0 \x85 ; 224 E0 latin small letter a with grave +\0 \xA0 ; 225 E1 latin small letter a with acute +\0 \x83 ; 226 E2 latin small letter a with circumflex +\0 a ; 227 E3 latin small letter a with tilde +\0 \x84 ; 228 E4 latin small letter a with diaeresis +\0 \x86 ; 229 E5 latin small letter a with ring above +\0 \x91 ; 230 E6 latin small letter ae +\0 \x87 ; 231 E7 latin small letter c with cedilla +\0 \x8A ; 232 E8 latin small letter e with grave +\0 \x82 ; 233 E9 latin small letter e with acute +\0 \x88 ; 234 EA latin small letter e with circumflex +\0 \x89 ; 235 EB latin small letter e with diaeresis +\0 \x8D ; 236 EC latin small letter i with grave +\0 \xA1 ; 237 ED latin small letter i with acute +\0 \x8C ; 238 EE latin small letter i with circumflex +\0 \x8B ; 239 EF latin small letter i with diaeresis +\0 \xE7 ; 240 F0 latin small letter eth (icelandic) +\0 \xA4 ; 241 F1 latin small letter n with tilde +\0 \x95 ; 242 F2 latin small letter o with grave +\0 \xA2 ; 243 F3 latin small letter o with acute +\0 \x93 ; 244 F4 latin small letter o with circumflex +\0 o ; 245 F5 latin small letter o with tilde +\0 \x94 ; 246 F6 latin small letter o with diaeresis +\0 \xF6 ; 247 F7 division sign +\0 \x9B ; 248 F8 latin small letter o with stroke (CP865 mapping) +\0 \x97 ; 249 F9 latin small letter u with grave +\0 \xA3 ; 250 FA latin small letter u with acute +\0 \x96 ; 251 FB latin small letter u with circumflex +\0 \x81 ; 252 FC latin small letter u with diaeresis +y e ; 253 FD latin small letter y with acute +t h ; 254 FE latin small letter thorn (icelandic) +\0 \x98 ; 255 FF latin small letter y with diaeresis +END diff --git a/cfgs/charset/iso_iso.chs b/cfgs/charset/iso_iso.chs new file mode 100644 index 0000000..0cc9d0b --- /dev/null +++ b/cfgs/charset/iso_iso.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts LATIN-1 to LATIN-1. (no conversion) +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +LATIN-1 ; from set +LATIN-1 ; to set +; +\0 \d128 +\0 \d129 +\0 \d130 +\0 \d131 +\0 \d132 +\0 \d133 +\0 \d134 +\0 \d135 +\0 \d136 +\0 \d137 +\0 \d138 +\0 \d139 +\0 \d140 +\0 \d141 +\0 \d142 +\0 \d143 +\0 \d144 +\0 \d145 +\0 \d146 +\0 \d147 +\0 \d148 +\0 \d149 +\0 \d150 +\0 \d151 +\0 \d152 +\0 \d153 +\0 \d154 +\0 \d155 +\0 \d156 +\0 \d157 +\0 \d158 +\0 \d159 +\0 \d160 +\0 \d161 +\0 \d162 +\0 \d163 +\0 \d164 +\0 \d165 +\0 \d166 +\0 \d167 +\0 \d168 +\0 \d169 +\0 \d170 +\0 \d171 +\0 \d172 +\0 \d173 +\0 \d174 +\0 \d175 +\0 \d176 +\0 \d177 +\0 \d178 +\0 \d179 +\0 \d180 +\0 \d181 +\0 \d182 +\0 \d183 +\0 \d184 +\0 \d185 +\0 \d186 +\0 \d187 +\0 \d188 +\0 \d189 +\0 \d190 +\0 \d191 +\0 \d192 +\0 \d193 +\0 \d194 +\0 \d195 +\0 \d196 +\0 \d197 +\0 \d198 +\0 \d199 +\0 \d200 +\0 \d201 +\0 \d202 +\0 \d203 +\0 \d204 +\0 \d205 +\0 \d206 +\0 \d207 +\0 \d208 +\0 \d209 +\0 \d210 +\0 \d211 +\0 \d212 +\0 \d213 +\0 \d214 +\0 \d215 +\0 \d216 +\0 \d217 +\0 \d218 +\0 \d219 +\0 \d220 +\0 \d221 +\0 \d222 +\0 \d223 +\0 \d224 +\0 \d225 +\0 \d226 +\0 \d227 +\0 \d228 +\0 \d229 +\0 \d230 +\0 \d231 +\0 \d232 +\0 \d233 +\0 \d234 +\0 \d235 +\0 \d236 +\0 \d237 +\0 \d238 +\0 \d239 +\0 \d240 +\0 \d241 +\0 \d242 +\0 \d243 +\0 \d244 +\0 \d245 +\0 \d246 +\0 \d247 +\0 \d248 +\0 \d249 +\0 \d250 +\0 \d251 +\0 \d252 +\0 \d253 +\0 \d254 +\0 \d255 +END diff --git a/cfgs/charset/iso_mac.chs b/cfgs/charset/iso_mac.chs new file mode 100644 index 0000000..edd6a91 --- /dev/null +++ b/cfgs/charset/iso_mac.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO_8859-1 extended characters to Macintosh characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +Latin-1 ; from set +MAC ; to set +; +\0 ? ; (missing) these codes are unused +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 4 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 8 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 12 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 16 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 20 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 24 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 28 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 32 +\0 \xca ; non-breaking space +\0 \xc1 ; exclam downwards +\0 \xa2 ; cent +\0 \xa3 ; pound sterling +\x1 ? ; currency +\0 \xb4 ; Yen +\0 | ; broken bar +\0 \xa4 ; section +\0 \xac ; dieresis +\0 \xa9 ; copyright +\0 \xbb ; ord feminine +\0 \xc7 ; guillemot left +\0 \xc2 ; logical not +\0 \xd1 ; soft hyphen (or em dash) +\0 \xa8 ; registered trademark +\x1 ? ; overbar (macron) +\0 \xa1 ; ring / degree +\0 \xb1 ; plusminus +^ 2 ; superscript two (squared) +^ 3 ; superscript three (cubed) +\0 \xab ; acute +\0 \xb5 ; mu +\0 \xa6 ; paragraph +\0 \xa5 ; bullet +\0 , ; cedilla +^ 1 ; superscript one +\0 \xbc ; ord masculine +\0 \xc8 ; guillemot right +\x1 ? ; one quarter +. 5 ; half +\x1 ? ; three quarters +\0 \xc0 ; question downwards +\0 A ; A grave +\0 A ; A acute +\0 A ; A circumflex +\0 A ; A tilde +\0 \x80 ; A dieresis +\0 \x81 ; A ring +\0 \xae ; AE +\0 \x82 ; C cedilla +\0 E ; E grave +\0 \x83 ; E acute +\0 E ; E circumflex +E e ; E dieresis +\0 I ; I grave +\0 I ; I acute +\0 I ; I circumflex +I e ; I dieresis +\0 D ; Eth +\0 \x84 ; N tilde +\0 O ; O grave +\0 O ; O acute +\0 O ; O circumflex +\0 O ; O tilde +\0 \x85 ; O dieresis +\0 x ; multiplication +\0 \xaf ; O slash +\0 U ; U grave +\0 U ; U acute +\0 U ; U circumflex +\0 \x86 ; U dieresis +\0 Y ; Y acute +\x1 ? ; Thorn +\0 \xa7 ; german double s / beta +\0 \x88 ; a grave +\0 \x87 ; a acute +\0 \x89 ; a circumflex +\0 \x8b ; a tilde +\0 \x8a ; a dieresis +\0 \x8c ; a ring +\0 \xbe ; ae +\0 \x8d ; c cedilla +\0 \x8f ; e grave +\0 \x8e ; e acute +\0 \x90 ; e circumflex +\0 \x91 ; e dieresis +\0 \x93 ; i grave +\0 \x92 ; i acute +\0 \x94 ; i circumflex +\0 \x95 ; i dieresis +\x1 ? ; eth +\0 \x96 ; n tilde +\0 \x98 ; o grave +\0 \x97 ; o acute +\0 \x99 ; o circumflex +\0 \x9b ; o tilde +\0 \x9a ; o dieresis +\0 \xd6 ; division +\0 \xbf ; o slash +\0 \x9d ; u grave +\0 \x9c ; u acute +\0 \x9e ; u circumflex +\0 \x9f ; u dieresis +y e ; y acute +\x1 ? ; thorn +\0 \xd7 ; y dieresis +END diff --git a/cfgs/charset/iso_vt1.chs b/cfgs/charset/iso_vt1.chs new file mode 100644 index 0000000..aecae3a --- /dev/null +++ b/cfgs/charset/iso_vt1.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts ISO_8859-1 extended characters to VT100 characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number, is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +Latin-1 ; from set +VT100 ; to set +; +\0 ? ; (missing) these codes are unused +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 4 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 8 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 12 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 16 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 20 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 24 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 28 +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) +\0 ? ; (missing) 32 +\0 \d32 ; non-breaking space +\0 ! ; exclam downwards +\0 c ; cent +\d125 \0 ; pound sterling +\x1 ? ; currency +\0 Y ; Yen +\0 | ; broken bar +\0 S ; section +\x1 ? ; dieresis +\0 c ; copyright +\0 a ; ord feminine +< < ; guillemot left +\0 ! ; logical not +\0 - ; soft hyphen (or em dash) +\0 R ; registered trademark +\d111 \0 ; overbar (macron) +\d102 \0 ; ring / degree +\d103 \0 ; plusminus +^ 2 ; superscript two (squared) +^ 3 ; superscript three (cubed) +\0 ' ; acute +m u ; mu +\x1 ? ; paragraph +\0 o ; bullet +\0 , ; cedilla +^ 1 ; superscript one +\0 o ; ord masculine +> > ; guillemot right +\x1 ? ; one quarter +. 5 ; half +\x1 ? ; three quarters +\0 ? ; question downwards +\0 A ; A grave +\0 A ; A acute +\0 A ; A circumflex +\0 A ; A tilde +A e ; A dieresis +\0 A ; A ring +A E ; AE +\0 C ; C cedilla +\0 E ; E grave +\0 E ; E acute +\0 E ; E circumflex +E e ; E dieresis +\0 I ; I grave +\0 I ; I acute +\0 I ; I circumflex +I e ; I dieresis +\0 D ; Eth +\0 N ; N tilde +\0 O ; O grave +\0 O ; O acute +\0 O ; O circumflex +\0 O ; O tilde +O e ; O dieresis +\0 x ; multiplication +\0 0 ; O slash +\0 U ; U grave +\0 U ; U acute +\0 U ; U circumflex +U e ; U dieresis +\0 Y ; Y acute +\x1 ? ; Thorn +\0 B ; german double s / beta +\0 a ; a grave +\0 a ; a acute +\0 a ; a circumflex +\0 a ; a tilde +a e ; a dieresis +\0 a ; a ring +a e ; ae +\0 c ; c cedilla +\0 e ; e grave +\0 e ; e acute +\0 e ; e circumflex +e e ; e dieresis +\0 i ; i grave +\0 i ; i acute +\0 i ; i circumflex +i e ; i dieresis +\x1 ? ; eth +\0 n ; n tilde +\0 o ; o grave +\0 o ; o acute +\0 o ; o circumflex +\0 o ; o tilde +o e ; o dieresis +\0 / ; division +\0 o ; o slash +\0 u ; u grave +\0 u ; u acute +\0 u ; u circumflex +u e ; u dieresis +y e ; y acute +\x1 ? ; thorn +y e ; y dieresis +END diff --git a/cfgs/charset/ita_asc.chs b/cfgs/charset/ita_asc.chs new file mode 100644 index 0000000..95ec436 --- /dev/null +++ b/cfgs/charset/ita_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Italian set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +ITALIAN ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 S ; at -> section +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 o ; bracket left -> ring / degree +\0 c ; backslash -> c cedilla +\0 e ; bracket right -> e acute +\0 ^ ; circum +\0 _ ; underscore +\0 u ; quote left -> u grave +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a grave +\0 o ; bar -> o grave +\0 e ; brace right -> e grave +\0 i ; tilde -> i grave +\0 \x7F ; DEL +END diff --git a/cfgs/charset/itl_ibm.chs b/cfgs/charset/itl_ibm.chs new file mode 100644 index 0000000..35c2de2 --- /dev/null +++ b/cfgs/charset/itl_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Italian set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +ITALIAN ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 \x9C ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x15 ; at -> section +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \xF8 ; bracket left -> ring / degree +\0 \x87 ; backslash -> c cedilla +\0 \x82 ; bracket right -> e acute +\0 ^ ; circum +\0 _ ; underscore +\0 \x97 ; quote left -> u grave +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x85 ; brace left -> a grave +\0 \x95 ; bar -> o grave +\0 \x8A ; brace right -> e grave +\0 \x8D ; tilde -> i grave +\0 \x7F ; DEL +END diff --git a/cfgs/charset/mac_850.chs b/cfgs/charset/mac_850.chs new file mode 100644 index 0000000..054b21f --- /dev/null +++ b/cfgs/charset/mac_850.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts Macintosh extended characters to IBM CP850 characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +MAC ; from set +CP850 ; to set +; +\0 \x8E ; 128 80 latin capital letter a with diaeresis +\0 \x8F ; 129 81 latin capital letter a with ring above +\0 \x80 ; 130 82 latin capital letter c with cedilla +\0 \x90 ; 131 83 latin capital letter e with acute +\0 \xA5 ; 132 84 latin capital letter n with tilde +\0 \x94 ; 133 85 latin capital letter o with diaeresis +\0 \x9A ; 134 86 latin capital letter u with diaeresis +\0 \xA0 ; 135 87 latin small letter a with acute +\0 \x85 ; 136 88 latin small letter a with grave +\0 \x83 ; 137 89 latin small letter a with circumflex +\0 \x84 ; 138 8A latin small letter a with diaeresis +\0 \xC6 ; 139 8B latin small letter a with tilde +\0 \x86 ; 140 8C latin small letter a with ring above +\0 \x87 ; 141 8D latin small letter c with cedilla +\0 \x82 ; 142 8E latin small letter e with acute +\0 \x8A ; 143 8F latin small letter e with grave +\0 \x88 ; 144 90 latin small letter e with circumflex +\0 \x89 ; 145 91 latin small letter e with diaeresis +\0 \xA1 ; 146 92 latin small letter i with acute +\0 \x8D ; 147 93 latin small letter i with grave +\0 \x8C ; 148 94 latin small letter i with circumflex +\0 \x8B ; 149 95 latin small letter i with diaeresis +\0 \xA4 ; 150 96 latin small letter n with tilde +\0 \xA2 ; 151 97 latin small letter o with acute +\0 \x95 ; 152 98 latin small letter o with grave +\0 \x96 ; 153 99 latin small letter o with circumflex +\0 \x94 ; 154 9A latin small letter o with diaeresis +\0 \xE4 ; 155 9B latin small letter o with tilde +\0 \xA3 ; 156 9C latin small letter u with acute +\0 \x97 ; 157 9D latin small letter u with grave +\0 \x96 ; 158 9E latin small letter u with circumflex +\0 \x81 ; 159 9F latin small letter u with diaeresis +\0 + ; 160 A0 dagger +\0 \xF8 ; 161 A1 degree sign +\0 \x9B ; 162 A2 cent sign +\0 \x9C ; 163 A3 pound sign +\0 \x15 ; 164 A4 section sign +\0 \xFE ; 165 A5 bullet operator +\0 \x14 ; 166 A6 pilcrow sign +\0 \xE1 ; 167 A7 latin small letter sharp s (german) +\0 \xA9 ; 168 A8 registered sign +\0 \xB8 ; 169 A9 copyright sign +t m ; 170 AA trade mark sign +\0 \xEF ; 171 AB acute accent +\0 \xF9 ; 172 AC diaeresis +< > ; 173 AD not equal to +\0 \x92 ; 174 AE latin capital letter ae +\0 \x9D ; 175 AF latin capital letter o with stroke +\0 \xEC ; 176 B0 infinity +\0 \xF1 ; 177 B1 plus-minus sign +\0 \xF3 ; 178 B2 less-than or equal to +\0 \xF2 ; 179 B3 greater-than or equal to +\0 \x9D ; 180 B4 yen sign +\0 \xE6 ; 181 B5 micro sign +\0 \xEB ; 182 B6 partial differential +\0 \xE4 ; 183 B7 n-ary summation +\0 x ; 184 B8 n-ary product +\0 \xE3 ; 185 B9 greek small letter pi +I n ; 186 BA integral +\0 \xA6 ; 187 BB feminine ordinal indicator +\0 \xA7 ; 188 BC masculine ordinal indicator +\0 \xEA ; 189 BD greek capital letter omega +\0 \x91 ; 190 BE latin small letter ae +\0 \x9b ; 191 BF latin small letter o with stroke +\0 \xA8 ; 192 C0 inverted question mark +\0 \xAD ; 193 C1 inverted exclamation mark +\0 \xAA ; 194 C2 not sign +\0 \xFB ; 195 C3 square root +\0 \x9F ; 196 C4 dutch guilder sign (ibm437 159) +\0 \xF7 ; 197 C5 almost equal to +\0 \x7F ; 198 C6 greek capital letter delta +\0 \xAF ; 199 C7 left-pointing double angle quotation mark +\0 \xAE ; 200 C8 right-pointing double angle quotation mark +. . ; 201 C9 midline horizontal ellipsis +\0 \d32 ; 202 CA no-break space +\0 \xB7 ; 203 CB latin capital letter a with grave +\0 \xC7 ; 204 CC latin capital letter a with tilde +\0 \xE5 ; 205 CD latin capital letter o with tilde +O E ; 206 CE latin capital ligature oe +o e ; 207 CF latin small ligature oe +\0 \xFA ; 208 D0 em dash +\0 - ; 209 D1 en dash +\0 " ; 210 D2 left double quotation mark +\0 " ; 211 D3 right double quotation mark +\0 ` ; 212 D4 left single quotation mark +\0 ' ; 213 D5 right single quotation mark +\0 \xF6 ; 214 D6 division sign +\0 \x04 ; 215 D7 black diamond +\0 \x98 ; 216 D8 latin small letter y with diaeresis +\0 \x98 ; 217 D9 latin capital letter y with diaeresis +\0 / ; 218 DA fraction slash +C u ; 219 DB currency sign +\0 < ; 220 DC single left-pointing angle quotation mark +\0 > ; 221 DD single right-pointing angle quotation mark +f i ; 222 DE latin small ligature fi +f l ; 223 DF latin small ligature fl ++ + ; 224 E0 double dagger +\0 . ; 225 E1 middle dot +\0 ' ; 226 E2 single low-9 quotation mark +\0 " ; 227 E3 double low-9 quotation mark +% . ; 228 E4 per mille sign +\0 \xB6 ; 229 E5 latin capital letter a with circumflex +\0 \xD2 ; 230 E6 latin capital letter e with circumflex +\0 \xB5 ; 231 E7 latin capital letter a with acute +\0 \xD3 ; 232 E8 latin capital letter e with diaeresis +\0 \xD4 ; 233 E9 latin capital letter e with grave +\0 \xD6 ; 234 EA latin capital letter i with acute +\0 \xD7 ; 235 EB latin capital letter i with circumflex +\0 \xD8 ; 236 EC latin capital letter i with diaeresis +\0 \xDE ; 237 ED latin capital letter i with grave +\0 \xE0 ; 238 EE latin capital letter o with acute +\0 \xE2 ; 239 EF latin capital letter o with circumflex +\x1 ? ; 240 F0 ??? +\0 \xE3 ; 241 F1 latin capital letter o with grave +\0 \xE9 ; 242 F2 latin capital letter u with acute +\0 \xEA ; 243 F3 latin capital letter u with circumflex +\0 \xEB ; 244 F4 latin capital letter u with grave +\0 i ; 245 F5 latin small letter i dotless +\x1 ? ; 246 F6 ??? +\x1 ? ; 247 F7 ??? +\0 \xEE ; 248 F8 overline +\0 u ; 249 F9 breve +\0 \xFA ; 250 FA dot above +\0 o ; 251 FB ring above +\0 , ; 252 FC cedilla +\0 " ; 253 FD double acute accent +\0 \xF7 ; 254 FE ogonek +\0 v ; 255 FF caron +END diff --git a/cfgs/charset/mac_asc.chs b/cfgs/charset/mac_asc.chs new file mode 100644 index 0000000..d4909fe --- /dev/null +++ b/cfgs/charset/mac_asc.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts Macintosh extended characters to IBM PC characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +MAC ; from set +ASCII ; to set +; +A e ; A dieresis +\0 A ; A ring +\0 C ; C cedilla +\0 E ; E acute +\0 N ; N tilde +O e ; O dieresis +U e ; U dieresis +\0 a ; a acute +\0 a ; a grave +\0 a ; a circumflex +a e ; a dieresis +\0 a ; a tilde +\0 a ; a ring +\0 c ; c cedilla +\0 e ; e acute +\0 e ; e grave +\0 e ; e circumflex +e e ; e dieresis +\0 i ; i acute +\0 i ; i grave +\0 i ; i circumflex +i e ; i dieresis +\0 n ; n tilde +\0 o ; o acute +\0 o ; o grave +\0 o ; o circumflex +o e ; o dieresis +\0 o ; o tilde +\0 u ; u grave +\0 u ; u acute +\0 u ; u circumflex +u e ; u dieresis +\0 + ; dagger +\0 o ; ring / degree +\0 c ; cent +\0 # ; pound sterling +\0 S ; section +\0 o ; bullet +\x1 ? ; paragraph +\0 B ; german double s +\0 R ; registered trademark +\0 c ; copyright +T M ; trademark +\0 ' ; acute +\x1 ? ; dieresis +< > ; not equal +A E ; AE +\0 0 ; O slash +\x1 ? ; infinity ++ - ; plusminus +< = ; smaller equals +> = ; greater equals +\0 Y ; Yen +m u ; mu +\0 d ; delta +\x1 ? ; Sigma (summation) +\x1 ? ; Pi +p i ; pi +\x1 ? ; integral +\0 a ; ord feminine +\0 o ; ord masculine +\0 O ; Omega +a e ; ae +\0 o ; o slash +\0 ? ; question downwards +\0 ! ; exclam downwards +\0 ! ; logical not +\x1 ? ; radical +\0 f ; florin +~ = ; approx. +\x1 ? ; Delta +> > ; guillemot right +< < ; guillemot left +. . ; ellipsis +\0 \d32 ; non breaking space +\0 A ; A acute +\0 A ; A tilde +\0 O ; O tilde +O E ; OE +o e ; oe +\0 - ; en dash +\0 - ; em dash +\0 " ; double quote left +\0 " ; double quote right +\0 ` ; quote left +\0 ' ; quote right +\0 / ; divide +\x1 ? ; lozenge +y e ; y dieresis +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +END diff --git a/cfgs/charset/mac_ibm.chs b/cfgs/charset/mac_ibm.chs new file mode 100644 index 0000000..1d0cfac --- /dev/null +++ b/cfgs/charset/mac_ibm.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts Macintosh extended characters to IBM-PC characters. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +MAC ; from set +IBMPC ; to set (actually CP865) +; +\0 \x8E ; 128 80 latin capital letter a with diaeresis +\0 \x8F ; 129 81 latin capital letter a with ring above +\0 \x80 ; 130 82 latin capital letter c with cedilla +\0 \x90 ; 131 83 latin capital letter e with acute +\0 \xA5 ; 132 84 latin capital letter n with tilde +\0 \x94 ; 133 85 latin capital letter o with diaeresis +\0 \x9A ; 134 86 latin capital letter u with diaeresis +\0 \xA0 ; 135 87 latin small letter a with acute +\0 \x85 ; 136 88 latin small letter a with grave +\0 \x83 ; 137 89 latin small letter a with circumflex +\0 \x84 ; 138 8A latin small letter a with diaeresis +\0 a ; 139 8B latin small letter a with tilde +\0 \x86 ; 140 8C latin small letter a with ring above +\0 \x87 ; 141 8D latin small letter c with cedilla +\0 \x82 ; 142 8E latin small letter e with acute +\0 \x8A ; 143 8F latin small letter e with grave +\0 \x88 ; 144 90 latin small letter e with circumflex +\0 \x89 ; 145 91 latin small letter e with diaeresis +\0 \xA1 ; 146 92 latin small letter i with acute +\0 \x8D ; 147 93 latin small letter i with grave +\0 \x8C ; 148 94 latin small letter i with circumflex +\0 \x8B ; 149 95 latin small letter i with diaeresis +\0 \xA4 ; 150 96 latin small letter n with tilde +\0 \xA2 ; 151 97 latin small letter o with acute +\0 \x95 ; 152 98 latin small letter o with grave +\0 \x96 ; 153 99 latin small letter o with circumflex +\0 \x94 ; 154 9A latin small letter o with diaeresis +\0 o ; 155 9B latin small letter o with tilde +\0 \xA3 ; 156 9C latin small letter u with acute +\0 \x97 ; 157 9D latin small letter u with grave +\0 \x96 ; 158 9E latin small letter u with circumflex +\0 \x81 ; 159 9F latin small letter u with diaeresis +\0 + ; 160 A0 dagger +\0 \xF8 ; 161 A1 degree sign +\0 \x9B ; 162 A2 cent sign +\0 \x9C ; 163 A3 pound sign +\0 \x15 ; 164 A4 section sign +\0 \xFE ; 165 A5 bullet operator +\0 \x14 ; 166 A6 pilcrow sign +\0 \xE1 ; 167 A7 latin small letter sharp s (german) +( R ) ; 168 A8 registered sign +( C ) ; 169 A9 copyright sign +t m ; 170 AA trade mark sign +\0 ' ; 171 AB acute accent +\x1 ? ; 172 AC diaeresis +< > ; 173 AD not equal to +\0 \x92 ; 174 AE latin capital letter ae +\0 \x9D ; 175 AF latin capital letter o with stroke (mapping for CP865) +\0 \xEC ; 176 B0 infinity +\0 \xF1 ; 177 B1 plus-minus sign +\0 \xF3 ; 178 B2 less-than or equal to +\0 \xF2 ; 179 B3 greater-than or equal to +\0 \x9D ; 180 B4 yen sign +\0 \xE6 ; 181 B5 micro sign +\0 \xEB ; 182 B6 partial differential +\0 \xE4 ; 183 B7 n-ary summation +\x1 ? ; 184 B8 n-ary product +\0 \xE3 ; 185 B9 greek small letter pi +\x1 ? ; 186 BA integral +\0 \xA6 ; 187 BB feminine ordinal indicator +\0 \xA7 ; 188 BC masculine ordinal indicator +\0 \xEA ; 189 BD greek capital letter omega +\0 \x91 ; 190 BE latin small letter ae +\0 \x9B ; 191 BF latin small letter o with stroke (mapping for CP865) +\0 \xA8 ; 192 C0 inverted question mark +\0 \xAD ; 193 C1 inverted exclamation mark +\0 \xAA ; 194 C2 not sign +\0 \xFB ; 195 C3 square root +\0 \x9F ; 196 C4 dutch guilder sign (ibm437 159) +\0 \xF7 ; 197 C5 almost equal to +\0 \x7F ; 198 C6 greek capital letter delta +\0 \xAF ; 199 C7 left-pointing double angle quotation mark +\0 \xAE ; 200 C8 right-pointing double angle quotation mark +. . ; 201 C9 midline horizontal ellipsis +\0 \d32 ; 202 CA no-break space +\0 A ; 203 CB latin capital letter a with grave +\0 A ; 204 CC latin capital letter a with tilde +\0 O ; 205 CD latin capital letter o with tilde +O E ; 206 CE latin capital ligature oe +o e ; 207 CF latin small ligature oe +\0 \xFA ; 208 D0 em dash +\0 - ; 209 D1 en dash +\0 " ; 210 D2 left double quotation mark +\0 " ; 211 D3 right double quotation mark +\0 ` ; 212 D4 left single quotation mark +\0 ' ; 213 D5 right single quotation mark +\0 \xF6 ; 214 D6 division sign +\0 \x04 ; 215 D7 black diamond +\0 \x98 ; 216 D8 latin small letter y with diaeresis +\0 Y ; 217 D9 latin capital letter y with diaeresis +\0 / ; 218 DA fraction slash +C u ; 219 DB currency sign +\0 < ; 220 DC single left-pointing angle quotation mark +\0 > ; 221 DD single right-pointing angle quotation mark +f i ; 222 DE latin small ligature fi +f l ; 223 DF latin small ligature fl ++ + ; 224 E0 double dagger +\0 . ; 225 E1 middle dot +\0 ' ; 226 E2 single low-9 quotation mark +\0 " ; 227 E3 double low-9 quotation mark +% . ; 228 E4 per mille sign +\0 A ; 229 E5 latin capital letter a with circumflex +\0 E ; 230 E6 latin capital letter e with circumflex +\0 A ; 231 E7 latin capital letter a with acute +\0 E ; 232 E8 latin capital letter e with diaeresis +\0 E ; 233 E9 latin capital letter e with grave +\0 I ; 234 EA latin capital letter i with acute +\0 I ; 235 EB latin capital letter i with circumflex +\0 I ; 236 EC latin capital letter i with diaeresis +\0 I ; 237 ED latin capital letter i with grave +\0 O ; 238 EE latin capital letter o with acute +\0 O ; 239 EF latin capital letter o with circumflex +\x1 ? ; 240 F0 ??? +\0 O ; 241 F1 latin capital letter o with grave +\0 U ; 242 F2 latin capital letter u with acute +\0 U ; 243 F3 latin capital letter u with circumflex +\0 U ; 244 F4 latin capital letter u with grave +\0 i ; 245 F5 latin small letter i dotless +\x1 ? ; 246 F6 ??? +\x1 ? ; 247 F7 ??? +\0 - ; 248 F8 overline +\0 u ; 249 F9 breve +\0 . ; 250 FA dot above +\0 o ; 251 FB ring above +\0 , ; 252 FC cedilla +\0 " ; 253 FD double acute accent +\0 , ; 254 FE ogonek +\0 v ; 255 FF caron +END diff --git a/cfgs/charset/mac_iso.chs b/cfgs/charset/mac_iso.chs new file mode 100644 index 0000000..2f79497 --- /dev/null +++ b/cfgs/charset/mac_iso.chs @@ -0,0 +1,161 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts Macintosh extended characters to ISO 8859-1. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +MAC ; from set +LATIN-1 ; to set +; +\0 \xc4 ; A dieresis +\0 \xc5 ; A ring +\0 \xc7 ; C cedilla +\0 \xc9 ; E acute +\0 \xd1 ; N tilde +\0 \xd6 ; O dieresis +\0 \xdc ; U dieresis +\0 \xe1 ; a acute +\0 \xe0 ; a grave +\0 \xe2 ; a circumflex +\0 \xe4 ; a dieresis +\0 \xe3 ; a tilde +\0 \xe5 ; a ring +\0 \xe7 ; c cedilla +\0 \xe9 ; e acute +\0 \xe8 ; e grave +\0 \xea ; e circumflex +\0 \xeb ; e dieresis +\0 \xed ; i acute +\0 \xec ; i grave +\0 \xee ; i circumflex +\0 \xef ; i dieresis +\0 \xf1 ; n tilde +\0 \xf3 ; o acute +\0 \xf2 ; o grave +\0 \xf4 ; o circumflex +\0 \xf6 ; o dieresis +\0 \xf5 ; o tilde +\0 \xfa ; u acute +\0 \xf9 ; u grave +\0 \xfb ; u circumflex +\0 \xfc ; u dieresis +\0 + ; dagger +\0 \xb0 ; ring / degree +\0 \xa2 ; cent +\0 \xa3 ; pound sterling +\0 \xa7 ; section +\0 \xb7 ; bullet +\0 \xb6 ; paragraph +\0 \xdf ; german double s +\0 \xae ; registered trademark +\0 \xa9 ; copyright +T M ; trademark +\0 \xb4 ; acute +\0 \xa8 ; dieresis +< > ; not equal +\0 \xc6 ; AE +\0 \xd8 ; O slash +\x1 ? ; infinity +\0 \xb1 ; plusminus +< = ; smaller equals +> = ; greater equals +\0 \xa5 ; Yen +\0 \xb5 ; mu +\0 \xf0 ; delta +\x1 ? ; Sigma (summation) +\x1 ? ; Pi +p i ; pi +\x1 ? ; integral +\0 \xaa ; ord feminine +\0 \xba ; ord masculine +\x1 ? ; Omega +\0 \xe6 ; ae +\0 \xf8 ; o slash +\0 \xbf ; question downwards +\0 \xa1 ; exclam downwards +\0 \xac ; logical not +\x1 ? ; radical +f l ; florin +~ = ; approx. +\x1 ? ; Delta +\0 \xbb ; guillemot right +\0 \xab ; guillemot left +. . ; ellipsis +\0 \xa0 ; non breaking space +\0 \xc1 ; A acute +\0 \xc3 ; A tilde +\0 \xd5 ; O tilde +O E ; OE +o e ; oe +\0 - ; en dash +\0 \xad ; em dash +\0 " ; double quote left +\0 " ; double quote right +\0 ` ; quote left +\0 \xb4 ; quote right +\0 \xf7 ; divide +\0 o ; lozenge +\0 \xff ; y dieresis +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +END diff --git a/cfgs/charset/mac_vt1.chs b/cfgs/charset/mac_vt1.chs new file mode 100644 index 0000000..bc12ab4 --- /dev/null +++ b/cfgs/charset/mac_vt1.chs @@ -0,0 +1,164 @@ +; +; This file is a charset conversion module in text form. +; +; This module Converts Macintosh extended characters to VT100. +; +; NOTE: this file uses an implementation dependant feature! +; a 0 as the second character means "use DEC graphic set" +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \d32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +2 ; level number +; +MAC ; from set +VT100 ; to set (change to UK for UK map file) +; +A e ; A dieresis +\0 A ; A ring +\0 C ; C cedilla +\0 E ; E acute +\0 N ; N tilde +O e ; O dieresis +U e ; U dieresis +\0 a ; a acute +\0 a ; a grave +\0 a ; a circumflex +a e ; a dieresis +\0 a ; a tilde +\0 a ; a ring +\0 c ; c cedilla +\0 e ; e acute +\0 e ; e grave +\0 e ; e circumflex +e e ; e dieresis +\0 i ; i acute +\0 i ; i grave +\0 i ; i circumflex +i e ; i dieresis +\0 n ; n tilde +\0 o ; o acute +\0 o ; o grave +\0 o ; o circumflex +o e ; o dieresis +\0 o ; o tilde +\0 u ; u grave +\0 u ; u acute +\0 u ; u circumflex +u e ; u dieresis +\0 + ; dagger +\d102 \0 ; ring / degree +\0 c ; cent +\d125 \0 ; pound sterling +\0 S ; section +\0 o ; bullet +\x1 ? ; paragraph +\0 B ; german double s +\0 R ; registered trademark +\0 c ; copyright +T M ; trademark +\0 ' ; acute +\x1 ? ; dieresis +\d124 \0 ; not equal +A E ; AE +\0 0 ; O slash +\x1 ? ; infinity +\d103 \0 ; plusminus +\d121 \0 ; smaller equals +\d122 \0 ; greater equals +\0 Y ; Yen +m u ; mu +\0 d ; delta +\x1 ? ; Sigma (summation) +\x1 ? ; Pi +\d123 \0 ; pi +\x1 ? ; integral +\0 a ; ord feminine +\0 o ; ord masculine +\0 O ; Omega +a e ; ae +\0 o ; o slash +\0 ? ; question downwards +\0 ! ; exclam downwards +\0 ! ; logical not +\x1 ? ; radical +\0 f ; florin +~ = ; approx. +\x1 ? ; Delta +> > ; guillemot right +< < ; guillemot left +. . ; ellipsis +\0 \d32 ; non breaking space +\0 A ; A acute +\0 A ; A tilde +\0 O ; O tilde +O E ; OE +o e ; oe +\0 - ; en dash +\0 - ; em dash +\0 " ; double quote left +\0 " ; double quote right +\0 ` ; quote left +\0 ' ; quote right +\0 / ; divide +\d96 \0 ; lozenge +y e ; y dieresis +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +\0 ? ; +END diff --git a/cfgs/charset/mne_850.esc b/cfgs/charset/mne_850.esc new file mode 100644 index 0000000..c8058fd --- /dev/null +++ b/cfgs/charset/mne_850.esc @@ -0,0 +1,182 @@ +; -------------------------------------------------------------------- +; Escaped Characters Table for GoldED. +; -------------------------------------------------------------------- +; Character Mnemonics & Character Sets, K. Simonsen. +; -------------------------------------------------------------------- +CP850 ; Map codes to charset. +; -------------------------------------------------------------------- +NU \d0 +SH \d1 +SX \d2 +EX \d3 +ET \d4 +EQ \d5 +AK \d6 +BL \d7 +BS \d8 +HT \d9 +LF \d10 +VT \d11 +FF \d12 +CR \d13 +SO \d14 +SI \d15 +DL \d16 +D1 \d17 +D2 \d18 +D3 \d19 +D4 \d20 +NK \d21 +SY \d22 +EB \d23 +CN \d24 +EM \d25 +SB \d26 +EC \d27 +FS \d28 +GS \d29 +RS \d30 +US \d31 +SP \d32 +Nb \d35 +DO \d36 +At \d64 +<( \d91 +// \d92 +)> \d93 +'> \d94 +'! \d96 +(! \d123 +!! \d124 +!) \d125 +'? \d126 +DT \d127 +C, \d128 +u: \d129 +e' \d130 +a> \d131 +a: \d132 +a! \d133 +aa \d134 +c, \d135 +e> \d136 +e: \d137 +e! \d138 +i: \d139 +i> \d140 +i! \d141 +A: \d142 +AA \d143 +E' \d144 +ae \d145 +AE \d146 +o> \d147 +o: \d148 +o! \d149 +u> \d150 +u! \d151 +y: \d152 +O: \d153 +U: \d154 +o/ \d155 +Pd \d156 +O/ \d157 +*X \d158 +Fl \d159 +a' \d160 +i' \d161 +o' \d162 +u' \d163 +n? \d164 +N? \d165 +-a \d166 +-o \d167 +?I \d168 +Rg \d169 +NO \d170 +12 \d171 +14 \d172 +!I \d173 +<< \d174 +>> \d175 +.S \d176 +:S \d177 +?S \d178 +vv \d179 +vl \d180 +A' \d181 +A> \d182 +A! \d183 +Co \d184 +VL \d185 +VV \d186 +LD \d187 +UL \d188 +Ct \d189 +Ye \d190 +dl \d191 +ur \d192 +uh \d193 +dh \d194 +vr \d195 +hh \d196 +vh \d197 +a? \d198 +A? \d199 +UR \d200 +DR \d201 +UH \d202 +DH \d203 +VR \d204 +HH \d205 +VH \d206 +Cu \d207 +d- \d208 +D- \d209 +E> \d210 +E: \d211 +E! \d212 +i. \d213 +I' \d214 +I> \d215 +I: \d216 +ul \d217 +dr \d218 +FB \d219 +LB \d220 +BB \d221 +I! \d222 +TB \d223 +O' \d224 +ss \d225 +O> \d226 +O! \d227 +o? \d228 +O? \d229 +m* \d230 +TH \d231 +th \d232 +U' \d233 +U> \d234 +U! \d235 +y' \d236 +Y' \d237 +-M \d238 +'' \d239 +-- \d240 ++- \d241 +== \d242 +34 \d243 +PI \d244 +SE \d245 +-: \d246 +'; \d247 +DG \d248 +': \d249 +'. \d250 +1S \d251 +3S \d252 +2S \d253 +fS \d254 +NS \d255 +; -------------------------------------------------------------------- diff --git a/cfgs/charset/mne_ibm.esc b/cfgs/charset/mne_ibm.esc new file mode 100644 index 0000000..bc28ddf --- /dev/null +++ b/cfgs/charset/mne_ibm.esc @@ -0,0 +1,185 @@ +; -------------------------------------------------------------------- +; Escaped Characters Table for GoldED. +; Based on IBM Code Page 437 with additions for CP865. +; -------------------------------------------------------------------- +; Character Mnemonics & Character Sets, K. Simonsen. +; -------------------------------------------------------------------- +IBMPC ; Map codes to charset. +; -------------------------------------------------------------------- +NU \d0 +SH \d1 +SX \d2 +EX \d3 +ET \d4 +EQ \d5 +AK \d6 +BL \d7 +BS \d8 +HT \d9 +LF \d10 +VT \d11 +FF \d12 +CR \d13 +SO \d14 +SI \d15 +DL \d16 +D1 \d17 +D2 \d18 +D3 \d19 +D4 \d20 +NK \d21 +SY \d22 +EB \d23 +CN \d24 +EM \d25 +SB \d26 +EC \d27 +FS \d28 +GS \d29 +RS \d30 +US \d31 +SP \d32 +Nb \d35 +DO \d36 +At \d64 +<( \d91 +// \d92 +)> \d93 +'> \d94 +'! \d96 +(! \d123 +!! \d124 +!) \d125 +'? \d126 +DT \d127 +C, \d128 +u: \d129 +e' \d130 +a> \d131 +a: \d132 +a! \d133 +aa \d134 +c, \d135 +e> \d136 +e: \d137 +e! \d138 +i: \d139 +i> \d140 +i! \d141 +A: \d142 +AA \d143 +E' \d144 +ae \d145 +AE \d146 +o> \d147 +o: \d148 +o! \d149 +u> \d150 +u! \d151 +y: \d152 +O: \d153 +U: \d154 +Ct \d155 ; CP437 +o/ \d155 ; CP865 +Pd \d156 +Ye \d157 ; CP437 +O/ \d157 ; CP865 +Pt \d158 +Fl \d159 +a' \d160 +i' \d161 +o' \d162 +u' \d163 +n? \d164 +N? \d165 +-a \d166 +-o \d167 +?I \d168 +NI \d169 +NO \d170 +12 \d171 +14 \d172 +!I \d173 +<< \d174 +>> \d175 +.S \d176 +:S \d177 +?S \d178 +vv \d179 +vl \d180 +vL \d181 +Vl \d182 +Dl \d183 +dL \d184 +VL \d185 +VV \d186 +LD \d187 +UL \d188 +Ul \d189 +uL \d190 +dl \d191 +ur \d192 +uh \d193 +dh \d194 +vr \d195 +hh \d196 +vh \d197 +vR \d198 +Vr \d199 +UR \d200 +DR \d201 +UH \d202 +DH \d203 +VR \d204 +HH \d205 +VH \d206 +uH \d207 +Uh \d208 +dH \d209 +Dh \d210 +Ur \d211 +uR \d212 +dR \d213 +Dr \d214 +Vh \d215 +vH \d216 +ul \d217 +dr \d218 +FB \d219 +LB \d220 +lB \d221 +RB \d222 +TB \d223 +a* \d224 +b* \d225 +G* \d226 +p* \d227 +S* \d228 +s* \d229 +m* \d230 +t* \d231 +F* \d232 +H* \d233 +W* \d234 +d* \d235 +00 \d236 +/0 \d237 +e* \d238 +(U \d239 +=3 \d240 ++- \d241 +>= \d242 +=< \d243 +Iu \d244 +Il \d245 +-: \d246 +?2 \d247 +Ob \d248 +.M \d249 +Sb \d250 +RT \d251 +nS \d252 +2S \d253 +fS \d254 +NS \d255 +; -------------------------------------------------------------------- diff --git a/cfgs/charset/nor_asc.chs b/cfgs/charset/nor_asc.chs new file mode 100644 index 0000000..a478873 --- /dev/null +++ b/cfgs/charset/nor_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Norwegian set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +NORWEG ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +A E ; bracket left -> AE +\0 O ; backslash -> O slash +\0 A ; bracket right -> A ring +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +a e ; brace left -> ae +\0 o ; bar -> o slash +\0 a ; brace right -> a ring +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/nor_ibm.chs b/cfgs/charset/nor_ibm.chs new file mode 100644 index 0000000..2949745 --- /dev/null +++ b/cfgs/charset/nor_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Norwegian set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +NORWEG ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x92 ; bracket left -> AE +\0 \x9D ; backslash -> O slash +\0 \x8F ; bracket right -> A ring +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x91 ; brace left -> ae +\0 \x9B ; bar -> o slash +\0 \x86 ; brace right -> a ring +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/prt_asc.chs b/cfgs/charset/prt_asc.chs new file mode 100644 index 0000000..ce9163d --- /dev/null +++ b/cfgs/charset/prt_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Portugese set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +PORTU ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 A ; bracket left -> A tilde +\0 C ; backslash -> C cedilla +\0 O ; bracket right -> O tilde +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a tilde +\0 c ; bar -> c cedilla +\0 o ; brace right -> o tilde +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/prt_ibm.chs b/cfgs/charset/prt_ibm.chs new file mode 100644 index 0000000..13450ed --- /dev/null +++ b/cfgs/charset/prt_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Portugese set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +PORTU ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 A ; bracket left -> A tilde +\0 \x80 ; backslash -> C cedilla +\0 O ; bracket right -> O tilde +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a tilde +\0 \x87 ; bar -> c cedilla +\0 o ; brace right -> o tilde +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/spn_asc.chs b/cfgs/charset/spn_asc.chs new file mode 100644 index 0000000..dbcb02d --- /dev/null +++ b/cfgs/charset/spn_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Spanish set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +SPANISH ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 S ; at -> section +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 ! ; bracket left -> exclam downwards +\0 N ; backslash -> N tilde +\0 ? ; bracket right -> question downwards +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 o ; brace left -> ring / degree +\0 n ; bar -> n tilde +\0 c ; brace right -> c cedilla +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/spn_ibm.chs b/cfgs/charset/spn_ibm.chs new file mode 100644 index 0000000..45aae24 --- /dev/null +++ b/cfgs/charset/spn_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Spanish set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +SPANISH ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 \x9C ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x15 ; at -> section +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \xAD ; bracket left -> exclam downwards +\0 \xA5 ; backslash -> N tilde +\0 \xA8 ; bracket right -> question downwards +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \xF8 ; brace left -> ring / degree +\0 \xA4 ; bar -> n tilde +\0 \x87 ; brace right -> c cedilla +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/swe_asc.chs b/cfgs/charset/swe_asc.chs new file mode 100644 index 0000000..1965203 --- /dev/null +++ b/cfgs/charset/swe_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Swedish set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +SWEDISH ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 E ; at -> E acute +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 A ; bracket left -> A dieresis +\0 O ; backslash -> O dieresis +\0 A ; bracket right -> A ring +\0 U ; circum -> U dieresis +\0 _ ; underscore +\0 e ; quote left -> e acute +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a dieresis +\0 o ; bar -> o dieresis +\0 a ; brace right -> a ring +\0 u ; tilde -> u dieresis +\0 \x7F ; DEL +END diff --git a/cfgs/charset/swe_ibm.chs b/cfgs/charset/swe_ibm.chs new file mode 100644 index 0000000..80a89b0 --- /dev/null +++ b/cfgs/charset/swe_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Swedish set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +SWEDISH ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x90 ; Jag tror att det var h„r jag „ndrade. Tidigare ”versattes +\0 A ; tecknet h„r till ett men ”vers„tts nu till en @. +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x8E ; bracket left -> A dieresis +\0 \x99 ; backslash -> O dieresis +\0 \x8F ; bracket right -> A ring +\0 \x9A ; circum -> U dieresis +\0 _ ; underscore +\0 \x82 ; quote left -> e acute +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x84 ; brace left -> a dieresis +\0 \x94 ; bar -> o dieresis +\0 \x86 ; brace right -> a ring +\0 \x81 ; tilde -> u dieresis +\0 \x7F ; DEL +END diff --git a/cfgs/charset/swi_asc.chs b/cfgs/charset/swi_asc.chs new file mode 100644 index 0000000..b6d1077 --- /dev/null +++ b/cfgs/charset/swi_asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Swiss set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +SWISS ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 u ; pound / number -> u grave +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 a ; at -> a grave +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 e ; bracket left -> e acute +\0 c ; backslash -> c cedilla +\0 e ; bracket right -> e circumflex +\0 i ; circum -> i circumflex +\0 e ; underscore -> e grave +\0 o ; quote left -> o circumflex +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 a ; brace left -> a dieresis +\0 o ; bar -> o dieresis +\0 u ; brace right -> u dieresis +\0 u ; tilde -> u circumflex +\0 \x7F ; DEL +END diff --git a/cfgs/charset/swi_ibm.chs b/cfgs/charset/swi_ibm.chs new file mode 100644 index 0000000..cc09253 --- /dev/null +++ b/cfgs/charset/swi_ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the Swiss set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +SWISS ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 \x97 ; pound / number -> u grave +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 \x85 ; at -> a grave +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 \x82 ; bracket left -> e acute +\0 \x87 ; backslash -> c cedilla +\0 \x88 ; bracket right -> e circumflex +\0 \x8C ; circum -> i circumflex +\0 \x8A ; underscore -> e grave +\0 \x93 ; quote left -> o circumflex +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 \x84 ; brace left -> a dieresis +\0 \x94 ; bar -> o dieresis +\0 \x81 ; brace right -> u dieresis +\0 \x96 ; tilde -> u circumflex +\0 \x7F ; DEL +END diff --git a/cfgs/charset/uk__asc.chs b/cfgs/charset/uk__asc.chs new file mode 100644 index 0000000..6494b4f --- /dev/null +++ b/cfgs/charset/uk__asc.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the UK set to ASCII. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +UK ; from set +ASCII ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 # ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 [ ; bracket left +\0 \\ ; backslash +\0 ] ; bracket right +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 { ; brace left +\0 | ; bar +\0 } ; brace right +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/charset/uk__ibm.chs b/cfgs/charset/uk__ibm.chs new file mode 100644 index 0000000..199fbdf --- /dev/null +++ b/cfgs/charset/uk__ibm.chs @@ -0,0 +1,162 @@ +; +; This file is a charset conversion module in text form. +; +; This module converts the UK set to IBMPC. +; You can use it as a basis for a level 1 converter. +; +; Format: ID, version, level, +; from charset, to charset, +; 128 entries: first & second byte +; "END" +; Lines beginning with a ";" or a ";" after the entries are comments +; +; Unknown characters are mapped to the "?" character. +; +; cedilla = , ; dieresis = .. ; acute = ' +; grave = ` ; circumflex = ^ ; ring = o +; tilde = ~ ; caron = v +; All of these are above the character, apart from the cedilla which is below. +; +; \ is the escape character: \0 means decimal zero, +; \dnnn where nnn is a decimal number is the ordinal value of the character +; \xnn where nn is a hexadecimal number +; e.g.: \x32 is the ASCII space character +; Two \\ is the character "\" itself. +; +0 ; ID number +0 ; version number +; +1 ; level number +; +UK ; from set +IBMPC ; to set +; +\0 \0 ; NUL +\0 \x1 ; SOH +\0 \x2 ; STX +\0 \x3 ; ETX +\0 \x4 ; EOT +\0 \x5 ; ENQ +\0 \x6 ; ACK +\0 \x7 ; BEL +\0 \x8 ; BS +\0 \x9 ; HT +\0 \xA ; LF +\0 \xB ; VT +\0 \xC ; FF +\0 \xD ; CR +\0 \xE ; SO +\0 \xF ; SI +\0 \x10 ; DLE +\0 \x11 ; DC1 +\0 \x12 ; DC2 +\0 \x13 ; DC3 +\0 \x14 ; DC4 +\0 \x15 ; NAK +\0 \x16 ; SYN +\0 \x17 ; ETB +\0 \x18 ; CAN +\0 \x19 ; EM +\0 \x1a ; SUB +\0 \x1b ; ESC +\0 \x1c ; FS +\0 \x1d ; GS +\0 \x1e ; RS +\0 \x1f ; US +\0 \x20 ; space +\0 ! ; exclam +\0 " ; double quotes +\0 \x9C ; pound / number -> pound sterling +\0 $ ; dollar +\0 % ; percent +\0 & ; ampersand +\0 ' ; quote right +\0 ( ; parenthesis left +\0 ) ; parenthesis right +\0 * ; asterisk +\0 + ; plus +\0 , ; comma +\0 - ; minus +\0 . ; period +\0 / ; slash +\0 0 ; zero +\0 1 ; one +\0 2 ; two +\0 3 ; three +\0 4 ; four +\0 5 ; five +\0 6 ; six +\0 7 ; seven +\0 8 ; eight +\0 9 ; nine +\0 : ; colon +\0 \d59 ; semicolon +\0 < ; less than +\0 = ; equals +\0 > ; greater than +\0 ? ; question +\0 @ ; at +\0 A ; +\0 B ; +\0 C ; +\0 D ; +\0 E ; +\0 F ; +\0 G ; +\0 H ; +\0 I ; +\0 J ; +\0 K ; +\0 L ; +\0 M ; +\0 N ; +\0 O ; +\0 P ; +\0 Q ; +\0 R ; +\0 S ; +\0 T ; +\0 U ; +\0 V ; +\0 W ; +\0 X ; +\0 Y ; +\0 Z ; +\0 [ ; bracket left +\0 \\ ; backslash +\0 ] ; bracket right +\0 ^ ; circum +\0 _ ; underscore +\0 ` ; quote left +\0 a ; +\0 b ; +\0 c ; +\0 d ; +\0 e ; +\0 f ; +\0 g ; +\0 h ; +\0 i ; +\0 j ; +\0 k ; +\0 l ; +\0 m ; +\0 n ; +\0 o ; +\0 p ; +\0 q ; +\0 r ; +\0 s ; +\0 t ; +\0 u ; +\0 v ; +\0 w ; +\0 x ; +\0 y ; +\0 z ; +\0 { ; brace left +\0 | ; bar +\0 } ; brace right +\0 ~ ; tilde +\0 \x7F ; DEL +END diff --git a/cfgs/colorset/gedcol00.cfg b/cfgs/colorset/gedcol00.cfg new file mode 100644 index 0000000..bdb0639 --- /dev/null +++ b/cfgs/colorset/gedcol00.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Odinn Sorensen. + +COLOR AREA BORDER Blue on Cyan +COLOR AREA HIGHLIGHT White on Cyan +COLOR AREA SELECTOR Yellow on Black +COLOR AREA TITLE White on Cyan +COLOR AREA WINDOW Blue on Cyan +COLOR ASK BORDER Red on LGrey +COLOR ASK HIGHLIGHT Cyan on LGrey +COLOR ASK NOSELECT DGrey on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE Blue on LGrey +COLOR ASK WINDOW Black on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW Yellow on Black +COLOR HEADER BORDER Cyan on Blue +COLOR HEADER EDIT White on Blue +COLOR HEADER HIGHLIGHT White on Blue +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE White on Blue +COLOR HEADER WINDOW Lgrey on Blue +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Cyan +COLOR MENU HIGHLIGHT White on Cyan +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE White on Cyan +COLOR MENU WINDOW Blue on Cyan +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD LMagenta on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG LMagenta on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol01.cfg b/cfgs/colorset/gedcol01.cfg new file mode 100644 index 0000000..5cf13a5 --- /dev/null +++ b/cfgs/colorset/gedcol01.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Marco Van den Bovenkamp. + +COLOR AREA BORDER Yellow on Black +COLOR AREA HIGHLIGHT White on Black +COLOR AREA SELECTOR Yellow on Red +COLOR AREA TITLE White on Black +COLOR AREA WINDOW LGrey on Black +COLOR ASK BORDER Red on LGrey +COLOR ASK HIGHLIGHT Cyan on LGrey +COLOR ASK NOSELECT DGrey on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE Blue on LGrey +COLOR ASK WINDOW Black on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Blue +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER Cyan on Black +COLOR HEADER EDIT White on Black +COLOR HEADER HIGHLIGHT White on Black +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE White on Black +COLOR HEADER WINDOW Lgrey on Black +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Cyan +COLOR MENU HIGHLIGHT White on Cyan +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE White on Cyan +COLOR MENU WINDOW Blue on Cyan +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD Cyan on Black +COLOR READER QUOTE Green on Black +COLOR READER TEARORIG LGrey on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol02.cfg b/cfgs/colorset/gedcol02.cfg new file mode 100644 index 0000000..5309ced --- /dev/null +++ b/cfgs/colorset/gedcol02.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Steve Shapiro. + +COLOR AREA BORDER Yellow on Black +COLOR AREA HIGHLIGHT Red on Black +COLOR AREA SELECTOR White on Red +COLOR AREA TITLE White on Black +COLOR AREA WINDOW LGrey on Black +COLOR ASK BORDER Red on LGrey +COLOR ASK HIGHLIGHT Red on LGrey +COLOR ASK NOSELECT DGrey on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE Blue on LGrey +COLOR ASK WINDOW Black on LGrey +COLOR BACKGROUND WINDOW Black on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Green on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW Green on Black +COLOR HEADER BORDER Cyan on Black +COLOR HEADER EDIT Yellow on Black +COLOR HEADER HIGHLIGHT Red on Black +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE Green on Black +COLOR HEADER WINDOW Green on Black +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Black +COLOR MENU HIGHLIGHT Red on Black +COLOR MENU NOSELECT DGrey on Black +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE White on Black +COLOR MENU WINDOW Green on Black +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD Cyan on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG Cyan on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Black on Green diff --git a/cfgs/colorset/gedcol03.cfg b/cfgs/colorset/gedcol03.cfg new file mode 100644 index 0000000..c44d287 --- /dev/null +++ b/cfgs/colorset/gedcol03.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Teddy Winstead. + +COLOR AREA BORDER Green on Black +COLOR AREA HIGHLIGHT Yellow on Black +COLOR AREA SELECTOR Yellow on Blue +COLOR AREA TITLE White on Black +COLOR AREA WINDOW Yellow on Black +COLOR ASK BORDER Green on Black +COLOR ASK HIGHLIGHT White on Black +COLOR ASK NOSELECT Green on Yellow +COLOR ASK SELECTOR Yellow on Blue +COLOR ASK TITLE White on Black +COLOR ASK WINDOW Yellow on Black +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Blue +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER Green on Black +COLOR HEADER EDIT Yellow on Blue +COLOR HEADER HIGHLIGHT Yellow on LGrey +COLOR HEADER INPUT Yellow on Blue +COLOR HEADER TITLE White on Black +COLOR HEADER WINDOW Yellow on Black +COLOR HELP BORDER Green on Black +COLOR HELP HIGHLIGHT White on Black +COLOR HELP SELECTOR Yellow on Blue +COLOR HELP WINDOW Yellow on Black +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Green on Black +COLOR MENU HIGHLIGHT White on Black +COLOR MENU NOSELECT Green on Black +COLOR MENU SELECTOR Yellow on Blue +COLOR MENU TITLE White on Black +COLOR MENU WINDOW Yellow on Black +COLOR READER BLOCK Yellow on Blue +COLOR READER BORDER Black on Black +COLOR READER CURSOR LGrey on Black +COLOR READER KLUDHIDD Green on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG Green on Black +COLOR READER WINDOW Green on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol04.cfg b/cfgs/colorset/gedcol04.cfg new file mode 100644 index 0000000..d723fed --- /dev/null +++ b/cfgs/colorset/gedcol04.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Richard Merit. + +COLOR AREA BORDER Blue on LGrey +COLOR AREA HIGHLIGHT Red on LGrey +COLOR AREA SELECTOR Black on Cyan +COLOR AREA TITLE Red on LGrey +COLOR AREA WINDOW Black on LGrey +COLOR ASK BORDER LGrey on Blue +COLOR ASK HIGHLIGHT Yellow on Blue +COLOR ASK NOSELECT LGrey on Blue +COLOR ASK SELECTOR Black on LGrey +COLOR ASK TITLE Yellow on Blue +COLOR ASK WINDOW White on Blue +COLOR BACKGROUND WINDOW Black on LGrey +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Blue +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER Red on LGrey +COLOR HEADER EDIT White on LGrey +COLOR HEADER HIGHLIGHT Yellow on LGrey +COLOR HEADER INPUT Black on Cyan +COLOR HEADER TITLE Red on LGrey +COLOR HEADER WINDOW Blue on LGrey +COLOR HELP BORDER Blue on Cyan +COLOR HELP HIGHLIGHT Yellow on Cyan +COLOR HELP SELECTOR Black on LGrey +COLOR HELP WINDOW Black on Cyan +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Cyan +COLOR MENU HIGHLIGHT Yellow on Cyan +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR Black on LGrey +COLOR MENU TITLE White on Cyan +COLOR MENU WINDOW Black on Cyan +COLOR READER BLOCK Black on Cyan +COLOR READER BORDER DGrey on Cyan +COLOR READER CURSOR LGrey on Black +COLOR READER KLUDHIDD Magenta on LGrey +COLOR READER QUOTE Brown on LGrey +COLOR READER TEARORIG Red on LGrey +COLOR READER WINDOW Black on LGrey +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Yellow on Blue diff --git a/cfgs/colorset/gedcol05.cfg b/cfgs/colorset/gedcol05.cfg new file mode 100644 index 0000000..98ffcb0 --- /dev/null +++ b/cfgs/colorset/gedcol05.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Thomas Kraft. + +COLOR AREA BORDER LGrey on Blue +COLOR AREA HIGHLIGHT White on Blue +COLOR AREA SELECTOR White on Blue +COLOR AREA TITLE White on Blue +COLOR AREA WINDOW LGrey on Blue +COLOR ASK BORDER Red on Lgrey +COLOR ASK HIGHLIGHT Red on Lgrey +COLOR ASK NOSELECT Lgrey on Lgrey +COLOR ASK SELECTOR Yellow on Blue +COLOR ASK TITLE Black on Lgrey +COLOR ASK WINDOW Blue on Lgrey +COLOR BACKGROUND WINDOW Cyan on Blue +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Lgrey on Blue +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER LGrey on Blue +COLOR HEADER EDIT LGrey on Blue +COLOR HEADER HIGHLIGHT Yellow on Blue +COLOR HEADER INPUT Red on Blue +COLOR HEADER TITLE White on Blue +COLOR HEADER WINDOW White on Blue +COLOR HELP BORDER Yellow on Green +COLOR HELP HIGHLIGHT White on Green +COLOR HELP SELECTOR Yellow on Blue +COLOR HELP WINDOW Black on Green +COLOR INFO BORDER Green on Black +COLOR INFO TITLE White on Black +COLOR INFO WINDOW Yellow on Black +COLOR MENU BORDER Lgrey on Blue +COLOR MENU HIGHLIGHT White on Blue +COLOR MENU NOSELECT Blue on Blue +COLOR MENU SELECTOR Yellow on Blue +COLOR MENU TITLE White on Blue +COLOR MENU WINDOW Lgrey on Blue +COLOR READER BLOCK White on Red +COLOR READER BORDER Lgrey on Blue +COLOR READER CURSOR White on Blue +COLOR READER KLUDHIDD Yellow on Blue +COLOR READER QUOTE Cyan on Blue +COLOR READER TEARORIG Lgrey on Blue +COLOR READER WINDOW Lgrey on Blue +COLOR SHADOW White on Black +COLOR STATUS WINDOW White on Black diff --git a/cfgs/colorset/gedcol06.cfg b/cfgs/colorset/gedcol06.cfg new file mode 100644 index 0000000..62dbfb2 --- /dev/null +++ b/cfgs/colorset/gedcol06.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Magnus Jacobsen. + +COLOR AREA BORDER Cyan on Blue +COLOR AREA HIGHLIGHT White on Blue +COLOR AREA SELECTOR White on LGrey +COLOR AREA TITLE White on Blue +COLOR AREA WINDOW LGrey on Blue +COLOR ASK BORDER Blue on LGrey +COLOR ASK HIGHLIGHT White on LGrey +COLOR ASK NOSELECT DGrey on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE White on LGrey +COLOR ASK WINDOW Blue on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Blue +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER Cyan on Blue +COLOR HEADER EDIT White on Blue +COLOR HEADER HIGHLIGHT White on Blue +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE White on Blue +COLOR HEADER WINDOW Lgrey on Blue +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Cyan +COLOR MENU HIGHLIGHT LCyan on Cyan +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR White on Blue +COLOR MENU TITLE White on Cyan +COLOR MENU WINDOW Blue on Cyan +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD LMagenta on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG LMagenta on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol07.cfg b/cfgs/colorset/gedcol07.cfg new file mode 100644 index 0000000..0278ee1 --- /dev/null +++ b/cfgs/colorset/gedcol07.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Lars Pehrsson. + +COLOR AREA BORDER Cyan on Blue +COLOR AREA HIGHLIGHT White on Blue +COLOR AREA SELECTOR White on LGrey +COLOR AREA TITLE White on Blue +COLOR AREA WINDOW LGrey on Blue +COLOR ASK BORDER Blue on LGrey +COLOR ASK HIGHLIGHT White on LGrey +COLOR ASK NOSELECT DGrey on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE White on LGrey +COLOR ASK WINDOW Blue on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Blue +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER Cyan on Blue +COLOR HEADER EDIT White on Blue +COLOR HEADER HIGHLIGHT White on Blue +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE White on Blue +COLOR HEADER WINDOW Lgrey on Blue +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Cyan +COLOR MENU HIGHLIGHT LCyan on Cyan +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR White on Blue +COLOR MENU TITLE White on Cyan +COLOR MENU WINDOW Blue on Cyan +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD LMagenta on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG LMagenta on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol08.cfg b/cfgs/colorset/gedcol08.cfg new file mode 100644 index 0000000..f7272ed --- /dev/null +++ b/cfgs/colorset/gedcol08.cfg @@ -0,0 +1,98 @@ + +; GoldED Example Color Configuration. +; =================================================================== +; By Tony Van den Bogaert 2:292/843 (tonyvdb@glo.be) + +; =================================================================== +; COLOR CONFIGURATION +; =================================================================== +; General screen color setup +; ========================== +COLOR BACKGROUND WINDOW Black on Black +COLOR STATUS WINDOW White on Red +COLOR SHADOW Black on Black +; Startup screen / logo window +; ============================ +COLOR BRAG WINDOW Black on Black +COLOR BRAG BORDER Black on Black +COLOR BRAG TITLE Black on Black +COLOR BRAG HIGHLIGHT Black on Black +COLOR BRAG BLOCK Black on Black +COLOR BRAG BTYPE 0 +; Area Selection Menu +; =================== +COLOR AREA WINDOW White on Blue +COLOR AREA BORDER White on Red +COLOR AREA TITLE White on Red +COLOR AREA SELECTOR Yellow on Green +COLOR AREA HIGHLIGHT White on Blue +COLOR AREA PAGEBAR Black on Black +COLOR AREA BTYPE 0 +; Message Header +; ============== +COLOR HEADER WINDOW Lgrey on Black +COLOR HEADER BORDER Green on Black +COLOR HEADER TITLE White on Red +COLOR HEADER INPUT Blue on Lgrey +COLOR HEADER EDIT Yellow on Black +COLOR HEADER HIGHLIGHT Green on Black +COLOR HEADER FROM Green on Black +COLOR HEADER TO Lgrey on Black +COLOR HEADER SUBJECT Lgrey on Black +COLOR HEADER BTYPE 0 +; Message Text +; ============ +COLOR READER WINDOW Lgrey on Black +COLOR READER BORDER Green on Black +COLOR READER QUOTE LBlue on Black +COLOR READER QUOTE2 Green on Black +COLOR READER CURSOR Lgrey on Black +COLOR READER TEARORIG Lgrey on Black +COLOR READER BLOCK Yellow on Red +COLOR READER HIGHLIGHT Yellow on Black +COLOR READER KLUDGE Lgrey on Black +COLOR READER HIDDEN Green on Black +COLOR READER TAGLINE Lgrey on Black +COLOR READER TEARLINE Lgrey on Black +COLOR READER ORIGIN Lgrey on Black +COLOR READER PAGEBAR Black on Black +COLOR READER SIGNATURE Lgrey on Black +COLOR READER BTYPE 0 +; Miscellaneous Smaller Menus +; =========================== +COLOR ASK WINDOW White on Blue +COLOR ASK BORDER White on Red +COLOR ASK TITLE White on Red +COLOR ASK SELECTOR Yellow on Green +COLOR ASK NOSELECT White on Blue +COLOR ASK HIGHLIGHT Yellow on Blue +COLOR ASK BTYPE 0 +; Miscellaneous Larger Menus (Browser Windows) +; ============================================ +COLOR MENU UNREAD Green on Black +COLOR MENU UNREADHIGH White on Black +COLOR MENU UNSENT LGrey on Black +COLOR MENU UNSENTHIGH LRed on Black +COLOR MENU WINDOW White on Blue +COLOR MENU BORDER White on Red +COLOR MENU TITLE White on Red +COLOR MENU SELECTOR Yellow on Green +COLOR MENU NOSELECT White on Blue +COLOR MENU HIGHLIGHT Yellow on Blue +COLOR MENU PAGEBAR Black on Black +COLOR MENU BTYPE 0 +; Help Screens +; ============ +COLOR HELP WINDOW White on Blue +COLOR HELP BORDER White on Blue +COLOR HELP SELECTOR Yellow on Green +COLOR HELP HIGHLIGHT Yellow on Blue +COLOR HELP BTYPE 0 +; Pop Up Information Windows +; ========================== +COLOR INFO WINDOW White on Blue +COLOR INFO BORDER White on Red +COLOR INFO TITLE White on Red +COLOR INFO BTYPE 0 +; ================================================================== + diff --git a/cfgs/colorset/gedcol09.cfg b/cfgs/colorset/gedcol09.cfg new file mode 100644 index 0000000..9366e44 --- /dev/null +++ b/cfgs/colorset/gedcol09.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Karsten Palmvig. + +COLOR AREA BORDER Green on Black +COLOR AREA HIGHLIGHT LRed on Black +COLOR AREA SELECTOR Black om LGrey +COLOR AREA TITLE Yellow on Black +COLOR AREA WINDOW Yellow on Black +COLOR ASK BORDER Green on Black +COLOR ASK HIGHLIGHT Yellow on Black +COLOR ASK NOSELECT LGrey on Black +COLOR ASK SELECTOR Black on LGrey +COLOR ASK TITLE Yellow on Black +COLOR ASK WINDOW Green on Black +COLOR BACKGROUND WINDOW Green on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Black on LGrey +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE Yellow on Black +COLOR BRAG WINDOW Black on LGrey +COLOR HEADER BORDER Green on Black +COLOR HEADER EDIT Black on LGrey +COLOR HEADER HIGHLIGHT Yellow on Black +COLOR HEADER INPUT Black on LGrey +COLOR HEADER TITLE Yellow on Black +COLOR HEADER WINDOW Yellow on Black +COLOR HELP BORDER Black on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER Black on LGrey +COLOR INFO TITLE Black on LGrey +COLOR INFO WINDOW Black on LGrey +COLOR MENU BORDER Green on Black +COLOR MENU HIGHLIGHT Yellow on Black +COLOR MENU NOSELECT LGrey on Black +COLOR MENU SELECTOR Black on LGrey +COLOR MENU TITLE Yellow on Black +COLOR MENU WINDOW Green on Black +COLOR READER BLOCK White on Red +COLOR READER BORDER Green on Black +COLOR READER CURSOR Yellow on Black +COLOR READER KLUDHIDD Cyan on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG Green on Black +COLOR READER WINDOW Green on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Black on LGrey diff --git a/cfgs/colorset/gedcol10.cfg b/cfgs/colorset/gedcol10.cfg new file mode 100644 index 0000000..3277246 --- /dev/null +++ b/cfgs/colorset/gedcol10.cfg @@ -0,0 +1,51 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Odinn Sorensen. + +COLOR AREA BORDER LBlue on Black +COLOR AREA HIGHLIGHT White on Black +COLOR AREA SELECTOR White on Blue +COLOR AREA TITLE Yellow on Black +COLOR AREA WINDOW LGrey on Black +COLOR ASK BORDER LRed on Black +COLOR ASK HIGHLIGHT White on Black +COLOR ASK NOSELECT DGrey on Black +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE Yellow on Black +COLOR ASK WINDOW LGrey on Black +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BACKGROUND BORDER Black on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Yellow on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE Yellow on Black +COLOR BRAG WINDOW White on Black +COLOR HEADER BORDER LBlue on Black +COLOR HEADER EDIT White on Black +COLOR HEADER HIGHLIGHT White on Black +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE Yellow on Black +COLOR HEADER WINDOW LGrey on Black +COLOR HELP BORDER Yellow on Black +COLOR HELP HIGHLIGHT White on Black +COLOR HELP SELECTOR White on Red +COLOR HELP WINDOW LGrey on Black +COLOR INFO BORDER LRed on Black +COLOR INFO TITLE Yellow on Black +COLOR INFO WINDOW White on Black +COLOR MENU BORDER LRed on Black +COLOR MENU HIGHLIGHT White on Black +COLOR MENU NOSELECT DGrey on Black +COLOR MENU SELECTOR White on Blue +COLOR MENU TITLE Yellow on Black +COLOR MENU WINDOW LGrey on Black +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD DGrey on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG White on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol11.cfg b/cfgs/colorset/gedcol11.cfg new file mode 100644 index 0000000..ff66f53 --- /dev/null +++ b/cfgs/colorset/gedcol11.cfg @@ -0,0 +1,54 @@ + +; GoldED Example Color Configuration. (Example of intense color setup) +; ----------------------------------------------------------------------------- +; By Odinn Sorensen. + +; Turn on intense colors for this setup! +INTENSECOLORS Yes + +COLOR AREA BORDER Blue on White +COLOR AREA HIGHLIGHT Red on White +COLOR AREA SELECTOR White on DGrey +COLOR AREA TITLE Red on White +COLOR AREA WINDOW Black on White +COLOR ASK BORDER Brown on Yellow +COLOR ASK HIGHLIGHT Red on Yellow +COLOR ASK NOSELECT LGrey on Yellow +COLOR ASK SELECTOR White on DGrey +COLOR ASK TITLE DGrey on Yellow +COLOR ASK WINDOW Black on Yellow +COLOR BACKGROUND WINDOW Black on White +COLOR BACKGROUND BORDER White on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Yellow on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE Yellow on Black +COLOR BRAG WINDOW White on Black +COLOR HEADER BORDER Yellow on DGrey +COLOR HEADER EDIT White on DGrey +COLOR HEADER HIGHLIGHT White on DGrey +COLOR HEADER INPUT Black on Red +COLOR HEADER TITLE Yellow on DGrey +COLOR HEADER WINDOW LGrey on DGrey +COLOR HELP BORDER Yellow on DGrey +COLOR HELP HIGHLIGHT White on DGrey +COLOR HELP SELECTOR Red on Yellow +COLOR HELP WINDOW LGrey on DGrey +COLOR INFO BORDER LRed on Black +COLOR INFO TITLE Yellow on Black +COLOR INFO WINDOW White on Black +COLOR MENU BORDER Yellow on LGrey +COLOR MENU HIGHLIGHT Yellow on LGrey +COLOR MENU NOSELECT DGrey on LGrey +COLOR MENU SELECTOR White on DGrey +COLOR MENU TITLE Red on LGrey +COLOR MENU WINDOW Black on LGrey +COLOR READER BLOCK Black on Red +COLOR READER BORDER Black on White +COLOR READER CURSOR Green on White +COLOR READER KLUDHIDD DGrey on White +COLOR READER QUOTE Red on White +COLOR READER TEARORIG Black on White +COLOR READER WINDOW Blue on White +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on DGrey diff --git a/cfgs/colorset/gedcol12.cfg b/cfgs/colorset/gedcol12.cfg new file mode 100644 index 0000000..14d146b --- /dev/null +++ b/cfgs/colorset/gedcol12.cfg @@ -0,0 +1,52 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Michael Hembo + +INTENSECOLORS YES + +COLOR AREA BORDER Blue on Lgray +COLOR AREA HIGHLIGHT Lgreen on lgray +COLOR AREA SELECTOR White on Blue +COLOR AREA TITLE yellow on lgray +COLOR AREA WINDOW black on lgray +COLOR ASK BORDER lblue on LGrey +COLOR ASK HIGHLIGHT yellow on lgray +COLOR ASK NOSELECT black on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE yellow on LGrey +COLOR ASK WINDOW Black on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW Yellow on Black +COLOR HEADER BORDER blue on dgray +COLOR HEADER EDIT white on lgray +COLOR HEADER HIGHLIGHT yellow on dgray +COLOR HEADER INPUT lgray on black +COLOR HEADER TITLE lred on dgray +COLOR HEADER WINDOW green on dgray +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT yellow on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER blue on lgrey +COLOR INFO TITLE yellow on lgrey +COLOR INFO WINDOW black on lgrey +COLOR MENU BORDER Blue on lgrey +COLOR MENU HIGHLIGHT yellow on lgrey +COLOR MENU NOSELECT black on lgrey +COLOR MENU SELECTOR white on Blue +COLOR MENU TITLE yellow on lgrey +COLOR MENU WINDOW black on lgrey +COLOR READER BLOCK black on brown +COLOR READER BORDER lgrey on blue +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD green on Black +COLOR READER QUOTE lgreen on Black +COLOR READER TEARORIG Lblue on Black +COLOR READER WINDOW yellow on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol13.cfg b/cfgs/colorset/gedcol13.cfg new file mode 100644 index 0000000..a60b5c8 --- /dev/null +++ b/cfgs/colorset/gedcol13.cfg @@ -0,0 +1,62 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Karsten Palmvig. + +INTENSECOLORS Yes + +COLOR AREA BORDER Green on Black +COLOR AREA HIGHLIGHT LRed on Black +COLOR AREA SELECTOR Black om LGrey +COLOR AREA TITLE Yellow on Black +COLOR AREA WINDOW Yellow on Black + +COLOR ASK BORDER Green on Black +COLOR ASK HIGHLIGHT Yellow on Black +COLOR ASK NOSELECT LGrey on Black +COLOR ASK SELECTOR Black on LGrey +COLOR ASK TITLE Yellow on Black +COLOR ASK WINDOW Green on Black + +COLOR BACKGROUND BORDER Black on Black +COLOR BACKGROUND WINDOW Green on Black + +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Black on LGrey +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE Yellow on Black +COLOR BRAG WINDOW Black on LGrey + +COLOR HEADER BORDER Green on Black +COLOR HEADER EDIT Black on LGrey +COLOR HEADER HIGHLIGHT Yellow on Black +COLOR HEADER INPUT Black on LGrey +COLOR HEADER TITLE Yellow on Black +COLOR HEADER WINDOW Yellow on Black + +COLOR HELP BORDER Black on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey + +COLOR INFO BORDER Black on Yellow +COLOR INFO TITLE Black on Yellow +COLOR INFO WINDOW LRed on Yellow + +COLOR MENU BORDER Green on Black +COLOR MENU HIGHLIGHT Yellow on Black +COLOR MENU NOSELECT LGrey on Black +COLOR MENU SELECTOR Black on LGrey +COLOR MENU TITLE Yellow on Black +COLOR MENU WINDOW Green on Black + +COLOR READER BLOCK White on Red +COLOR READER BORDER Green on Black +COLOR READER CURSOR Yellow on Black +COLOR READER KLUDHIDD Cyan on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG Green on Black +COLOR READER WINDOW Green on Black + +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Black on LGrey diff --git a/cfgs/colorset/gedcol14.cfg b/cfgs/colorset/gedcol14.cfg new file mode 100644 index 0000000..5af669c --- /dev/null +++ b/cfgs/colorset/gedcol14.cfg @@ -0,0 +1,50 @@ +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Thomas Endres + +COLOR AREA BORDER Blue on Black +COLOR AREA HIGHLIGHT Yellow on Black +COLOR AREA SELECTOR Yellow on Blue +COLOR AREA TITLE Yellow on Black +COLOR AREA WINDOW Cyan on Black +COLOR ASK BORDER Red on LGrey +COLOR ASK HIGHLIGHT White on LGrey +COLOR ASK NOSELECT Blue on LGrey +COLOR ASK SELECTOR Yellow on Black +COLOR ASK TITLE Red on LGrey +COLOR ASK WINDOW Red on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BACKGROUND BORDER Black on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Yellow on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE Yellow on Black +COLOR BRAG WINDOW White on Black +COLOR HEADER BORDER LBlue on Black +COLOR HEADER EDIT White on Black +COLOR HEADER HIGHLIGHT White on Black +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE Yellow on Black +COLOR HEADER WINDOW LGrey on Black +COLOR HELP BORDER Red on LGrey +COLOR HELP HIGHLIGHT White on LGrey +COLOR HELP SELECTOR Yellow on Black +COLOR HELP WINDOW Blue on LGrey +COLOR INFO BORDER Red on LGrey +COLOR INFO TITLE Yellow on LGrey +COLOR INFO WINDOW Blue on LGrey +COLOR MENU BORDER Red on LGrey +COLOR MENU HIGHLIGHT White on LGrey +COLOR MENU NOSELECT Red on LGrey +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE Red on LGrey +COLOR MENU WINDOW Red on LGrey +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD LRed on Black +COLOR READER QUOTE Green on Black +COLOR READER TEARORIG White on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Red on LGrey diff --git a/cfgs/colorset/gedcol15.cfg b/cfgs/colorset/gedcol15.cfg new file mode 100644 index 0000000..a08091d --- /dev/null +++ b/cfgs/colorset/gedcol15.cfg @@ -0,0 +1,51 @@ + +; GoldED Color Configuration. +; ----------------------------------------------------------------------------- +; By Nathan Moschkin. + +COLOR AREA BORDER LCyan on Black +COLOR AREA HIGHLIGHT Yellow on Black +COLOR AREA SELECTOR Blue on LGrey +COLOR AREA TITLE LGreen on Black +COLOR AREA WINDOW LGrey on Black +COLOR ASK BORDER LCyan on Blue +COLOR ASK HIGHLIGHT Yellow on Blue +COLOR ASK NOSELECT DGrey on Blue +COLOR ASK SELECTOR Blue on LGrey +COLOR ASK TITLE Black on Cyan +COLOR ASK WINDOW LGrey on Blue +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW Yellow on Black +COLOR HEADER BORDER Cyan on Blue +COLOR HEADER EDIT Blue on Green +COLOR HEADER HIGHLIGHT Yellow on Blue +COLOR HEADER INPUT Blue on Green +COLOR HEADER TITLE LGreen on Blue +COLOR HEADER WINDOW White on Blue +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on Cyan +COLOR MENU HIGHLIGHT White on Cyan +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE White on Cyan +COLOR MENU WINDOW Blue on Cyan +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD LGreen on Black +COLOR READER QUOTE LCyan on Black +COLOR READER TEARORIG Yellow on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue + diff --git a/cfgs/colorset/gedcol16.cfg b/cfgs/colorset/gedcol16.cfg new file mode 100644 index 0000000..0fcf891 --- /dev/null +++ b/cfgs/colorset/gedcol16.cfg @@ -0,0 +1,49 @@ +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Micheal Dunnagan + +COLOR AREA BORDER Red on Blue +COLOR AREA HIGHLIGHT White on Blue +COLOR AREA SELECTOR LRed on Black +COLOR AREA TITLE White on Blue +COLOR AREA WINDOW White on DGrey +COLOR ASK BORDER Blue on LGrey +COLOR ASK HIGHLIGHT White on LGrey +COLOR ASK NOSELECT DGrey on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE Red on LGrey +COLOR ASK WINDOW Blue on LGrey +COLOR BACKGROUND WINDOW White on DGrey +COLOR BRAG BLOCK Yellow on Blue +COLOR BRAG BORDER Red on Blue +COLOR BRAG HIGHLIGHT LRed on Blue +COLOR BRAG TITLE Yellow on Blue +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER Red on Black +COLOR HEADER EDIT White on Blue +COLOR HEADER HIGHLIGHT Yellow on Blue +COLOR HEADER INPUT White on Blue +COLOR HEADER TITLE Blue on LGrey +COLOR HEADER WINDOW White on Blue +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT Red on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Blue on LGrey +COLOR INFO BORDER White on Blue +COLOR INFO TITLE White on Blue +COLOR INFO WINDOW White on Blue +COLOR MENU BORDER Blue on LGrey +COLOR MENU HIGHLIGHT White on Blue +COLOR MENU NOSELECT DGrey on Cyan +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE White on Blue +COLOR MENU WINDOW Blue on LGrey +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD Cyan on Black +COLOR READER QUOTE Yellow on Black +COLOR READER TEARORIG LMagenta on Black +COLOR READER WINDOW LGreen on Black +COLOR SHADOW Blue on Black +COLOR STATUS WINDOW Blue on LGrey diff --git a/cfgs/colorset/gedcol17.cfg b/cfgs/colorset/gedcol17.cfg new file mode 100644 index 0000000..a8c2acd --- /dev/null +++ b/cfgs/colorset/gedcol17.cfg @@ -0,0 +1,62 @@ +; GoldED Example Color Configuration. +; ------------------------------------------------------------- +; By Joseph Carnage + +IntenseColors Yes + +Color Area Border Green on Black +Color Area Highlight LRed on Black +Color Area Selector Black om LGrey +Color Area Title Yellow on Black +Color Area Window Yellow on Black + +Color Ask Border White on Blue +Color Ask Highlight LRed on Blue +Color Ask Noselect Dgrey on Blue +Color Ask Selector LCyan on LRed +Color Ask Title White on Blue +Color Ask Window White on Blue + +Color Background Border Black on Black +Color Background Window Green on Black + +Color Brag Block LBlue on Black +Color Brag Border Black on LGrey +Color Brag Highlight LRed on Black +Color Brag Title Yellow on Black +Color Brag Window Black on LGrey + +Color Header border LRed on Black +Color Header edit Black on LGrey +Color Header highlight LCyan on Black +Color Header input Black on LGrey +Color Header title White on Black +Color Header window LGrey on Black + +Color Help border Black on White +Color Help highlight Red on White +Color Help selector White on Blue +Color Help window Black on White + +Color Info Border Black on Yellow +Color Info Title Black on Yellow +Color Info Window LRed on Yellow + +Color Menu Border Yellow on LGrey +Color Menu Highlight Yellow on LGrey +Color Menu Noselect Dgrey on LGrey +Color Menu Selector White on DGrey +Color Menu Title Red on LGrey +Color Menu Window Black on LGrey + +Color Reader Block White on Red +Color Reader Border Green on Black +Color Reader Cursor Yellow on Black +Color Reader Kludhidd Lcyan on Black +Color Reader Quote Yellow on Black +Color Reader Tearorig White on Black +Color Reader Window Green on Black + +Color Shadow DGrey on Black +Color Status Window Black on LGrey + diff --git a/cfgs/colorset/gedcol18.cfg b/cfgs/colorset/gedcol18.cfg new file mode 100644 index 0000000..d1df6af --- /dev/null +++ b/cfgs/colorset/gedcol18.cfg @@ -0,0 +1,50 @@ +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Thomas Endres + +COLOR AREA BORDER Blue on Black +COLOR AREA HIGHLIGHT Yellow on Black +COLOR AREA SELECTOR Yellow on Blue +COLOR AREA TITLE Yellow on Black +COLOR AREA WINDOW Cyan on Black +COLOR ASK BORDER Red on LGrey +COLOR ASK HIGHLIGHT White on LGrey +COLOR ASK NOSELECT Blue on LGrey +COLOR ASK SELECTOR Yellow on Black +COLOR ASK TITLE Red on LGrey +COLOR ASK WINDOW Red on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BACKGROUND BORDER Black on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER Yellow on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE Yellow on Black +COLOR BRAG WINDOW White on Black +COLOR HEADER BORDER LBlue on Black +COLOR HEADER EDIT White on Black +COLOR HEADER HIGHLIGHT White on Black +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE Yellow on Black +COLOR HEADER WINDOW LGrey on Black +COLOR HELP BORDER Red on LGrey +COLOR HELP HIGHLIGHT White on LGrey +COLOR HELP SELECTOR Yellow on Black +COLOR HELP WINDOW Blue on LGrey +COLOR INFO BORDER Red on LGrey +COLOR INFO TITLE Yellow on LGrey +COLOR INFO WINDOW Blue on LGrey +COLOR MENU BORDER Red on LGrey +COLOR MENU HIGHLIGHT White on LGrey +COLOR MENU NOSELECT Red on LGrey +COLOR MENU SELECTOR Yellow on Black +COLOR MENU TITLE Red on LGrey +COLOR MENU WINDOW Red on LGrey +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Black +COLOR READER CURSOR White on Black +COLOR READER KLUDHIDD LRed on Black +COLOR READER QUOTE Green on Black +COLOR READER TEARORIG Yellow on Black +COLOR READER WINDOW LGrey on Black +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Red on LGrey diff --git a/cfgs/colorset/gedcol19.cfg b/cfgs/colorset/gedcol19.cfg new file mode 100644 index 0000000..926c0ec --- /dev/null +++ b/cfgs/colorset/gedcol19.cfg @@ -0,0 +1,50 @@ +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By ??? + +COLOR AREA BORDER LBlue on Blue +COLOR AREA HIGHLIGHT White on Blue +COLOR AREA SELECTOR Yellow on Black +COLOR AREA TITLE Yellow on Blue +COLOR AREA WINDOW LGrey on Blue +COLOR ASK BORDER White on Red +COLOR ASK HIGHLIGHT White on Red +COLOR ASK NOSELECT DGrey on Red +COLOR ASK SELECTOR White on Black +COLOR ASK TITLE Yellow on Red +COLOR ASK WINDOW Black on Red +COLOR BACKGROUND WINDOW LGrey on Blue +COLOR BACKGROUND BORDER Black on Blue +COLOR BRAG BLOCK LBlue on Blue +COLOR BRAG BORDER Yellow on Blue +COLOR BRAG HIGHLIGHT LRed on Blue +COLOR BRAG TITLE Yellow on Blue +COLOR BRAG WINDOW White on Blue +COLOR HEADER BORDER White on LBlue +COLOR HEADER EDIT White on LBlue +COLOR HEADER HIGHLIGHT White on LBlue +COLOR HEADER INPUT Blue on LBlue +COLOR HEADER TITLE LGreen on LBlue +COLOR HEADER WINDOW Yellow on LBlue +COLOR HELP BORDER White on Red +COLOR HELP HIGHLIGHT Yellow on Black +COLOR HELP SELECTOR White on Red +COLOR HELP WINDOW Black on Red +COLOR INFO BORDER Black on Magenta +COLOR INFO TITLE Yellow on Magenta +COLOR INFO WINDOW White on Magenta +COLOR MENU BORDER White on Red +COLOR MENU HIGHLIGHT White on Red +COLOR MENU NOSELECT DGrey on Red +COLOR MENU SELECTOR White on Black +COLOR MENU TITLE Yellow on Red +COLOR MENU WINDOW Black on Red +COLOR READER BLOCK White on Red +COLOR READER BORDER LGrey on Blue +COLOR READER CURSOR White on Blue +COLOR READER KLUDHIDD White on Blue +COLOR READER QUOTE LGrey on Blue +COLOR READER TEARORIG LRed on Blue +COLOR READER WINDOW Yellow on Blue +COLOR SHADOW DGrey on Grey +COLOR STATUS WINDOW White on LBlue diff --git a/cfgs/colorset/gedcol20.cfg b/cfgs/colorset/gedcol20.cfg new file mode 100644 index 0000000..6e5d5b5 --- /dev/null +++ b/cfgs/colorset/gedcol20.cfg @@ -0,0 +1,53 @@ + +; GoldED Example Color Configuration. +; ----------------------------------------------------------------------------- +; By Niels Axelsson 2:231/78.11 +; To be enhanced indefinitely ... + +INTENSECOLORS YES + +COLOR AREA BORDER Blue on Lgray +COLOR AREA HIGHLIGHT Lgreen on lgray +COLOR AREA SELECTOR White on Blue +COLOR AREA TITLE yellow on lgray +COLOR AREA WINDOW black on lgray +COLOR ASK BORDER lblue on LGrey +COLOR ASK HIGHLIGHT yellow on lgray +COLOR ASK NOSELECT black on LGrey +COLOR ASK SELECTOR White on Blue +COLOR ASK TITLE yellow on LGrey +COLOR ASK WINDOW Black on LGrey +COLOR BACKGROUND WINDOW LGrey on Black +COLOR BRAG BLOCK LBlue on Black +COLOR BRAG BORDER White on Black +COLOR BRAG HIGHLIGHT LRed on Black +COLOR BRAG TITLE White on Black +COLOR BRAG WINDOW Yellow on Black +COLOR HEADER BORDER blue on lgrey +COLOR HEADER EDIT white on Red +COLOR HEADER HIGHLIGHT yellow on lgray +COLOR HEADER INPUT lgray on black +COLOR HEADER TITLE white on lgrey +COLOR HEADER WINDOW LBlue on lgrey +COLOR HELP BORDER Blue on LGrey +COLOR HELP HIGHLIGHT yellow on LGrey +COLOR HELP SELECTOR White on Blue +COLOR HELP WINDOW Black on LGrey +COLOR INFO BORDER blue on lgrey +COLOR INFO TITLE yellow on lgrey +COLOR INFO WINDOW black on lgrey +COLOR MENU BORDER Blue on lgrey +COLOR MENU HIGHLIGHT yellow on lgrey +COLOR MENU NOSELECT black on lgrey +COLOR MENU SELECTOR white on Blue +COLOR MENU TITLE yellow on lgrey +COLOR MENU WINDOW black on lgrey +COLOR READER BLOCK black on brown +COLOR READER BORDER blue on blue +COLOR READER CURSOR White on DGrey +COLOR READER KLUDHIDD green on DGrey +COLOR READER QUOTE lgreen on DGrey +COLOR READER TEARORIG LRed on DGrey +COLOR READER WINDOW yellow on DGrey +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW White on Blue diff --git a/cfgs/colorset/gedcol21.cfg b/cfgs/colorset/gedcol21.cfg new file mode 100644 index 0000000..2af6213 --- /dev/null +++ b/cfgs/colorset/gedcol21.cfg @@ -0,0 +1,67 @@ + +; GoldED Example Color Configuration. +; Norton Commander Color Style. +; ----------------------------------------------------------------------------- +; By Gustav Brock. + +COLOR AREA BORDER LCyan on Blue +COLOR AREA HIGHLIGHT Yellow on Blue +COLOR AREA SELECTOR Black on Cyan +COLOR AREA TITLE Yellow on Blue +COLOR AREA WINDOW LCyan on Blue + +COLOR ASK BORDER Black on LGrey +COLOR ASK HIGHLIGHT Yellow on LGrey +COLOR ASK NOSELECT Black on Lgrey +COLOR ASK SELECTOR Black on Cyan +COLOR ASK TITLE Black on LGrey +COLOR ASK WINDOW Black on LGrey + +COLOR BACKGROUND WINDOW Blue on LGrey + +; ----------------------------------------------------------------------------- +; Original Logotype by Odinn Sorensen +; ----------------------------------------------------------------------------- +;COLOR BRAG BLOCK LBlue on Black +;COLOR BRAG HIGHLIGHT LRed on Black +;COLOR BRAG TITLE White on Black +; ----------------------------------------------------------------------------- +COLOR BRAG BLOCK LCyan on Blue ; Logotype +COLOR BRAG BORDER LCyan on Blue ; Box +COLOR BRAG HIGHLIGHT LMagenta on Blue ; Logotype +COLOR BRAG TITLE Yellow on Blue ; Logotype +COLOR BRAG WINDOW Yellow on Blue ; Box + +COLOR HEADER BORDER Black on Cyan +COLOR HEADER EDIT White on Black +COLOR HEADER HIGHLIGHT Yellow on Cyan +COLOR HEADER INPUT Blue on LGrey +COLOR HEADER TITLE White on Cyan +COLOR HEADER WINDOW Black on Cyan + +COLOR HELP BORDER Black on Cyan +COLOR HELP HIGHLIGHT Yellow on Cyan +COLOR HELP SELECTOR White on Black +COLOR HELP WINDOW Black on Cyan + +COLOR INFO BORDER White on Red +COLOR INFO TITLE White on Red +COLOR INFO WINDOW White on Red + +COLOR MENU BORDER Black on LGrey +COLOR MENU HIGHLIGHT Yellow on LGrey +COLOR MENU NOSELECT Black on LGrey +COLOR MENU SELECTOR Black on Cyan +COLOR MENU TITLE Black on LGrey +COLOR MENU WINDOW Black on LGrey + +COLOR READER BLOCK White on Black +COLOR READER BORDER LGrey on Blue +COLOR READER CURSOR LCyan on Blue +COLOR READER KLUDHIDD LGrey on Black +COLOR READER QUOTE White on Blue +COLOR READER TEARORIG Yellow on Blue +COLOR READER WINDOW LCyan on Blue + +COLOR SHADOW DGrey on Black +COLOR STATUS WINDOW Black on Cyan diff --git a/cfgs/colorset/gedcol22.cfg b/cfgs/colorset/gedcol22.cfg new file mode 100644 index 0000000..8629f1e --- /dev/null +++ b/cfgs/colorset/gedcol22.cfg @@ -0,0 +1,58 @@ +;---------------------------GOLDED COLOR CONFIGURATION---------------------- +; DESCRIPTION: New By Odinn Sorensen +; MADE WITH GEDCOLOR 1.00 BY MICHAEL REILER +;--------------------------------------------------------------------------- +COLOR AREA WINDOW BLACK ON LGREY +COLOR AREA BORDER BLUE ON LGREY +COLOR AREA TITLE RED ON LGREY +COLOR AREA SELECTOR WHITE ON BLUE +COLOR AREA HIGHLIGHT LBLUE ON LGREY +COLOR AREA BTYPE 0 +COLOR STATUS WINDOW WHITE ON BLUE +COLOR BACKGROUND WINDOW LBLUE ON LGREY +COLOR BRAG WINDOW WHITE ON BLUE +COLOR BRAG BORDER BLACK ON BLUE +COLOR BRAG TITLE YELLOW ON BLACK +COLOR BRAG HIGHLIGHT LRED ON BLACK +COLOR BRAG BLOCK LBLUE ON BLACK +COLOR BRAG BTYPE 0 +COLOR HEADER EDIT LRED ON LGREY +COLOR HEADER WINDOW BLUE ON LGREY +COLOR HEADER BORDER RED ON LGREY +COLOR HEADER TITLE RED ON LGREY +COLOR HEADER INPUT WHITE ON BLUE +COLOR HEADER HIGHLIGHT LRED ON LGREY +COLOR HEADER BTYPE 0 +COLOR READER WINDOW BLACK ON LGREY +COLOR READER BORDER DGREY ON CYAN +COLOR READER QUOTE RED ON LGREY +COLOR READER CURSOR LBLUE ON LGREY +COLOR READER KLUDHIDD DGREY ON LGREY +COLOR READER BTYPE 0 +COLOR READER TEARORIG BLUE ON LGREY +COLOR READER BLOCK BLACK ON CYAN +COLOR ASK WINDOW WHITE ON BLUE +COLOR ASK BORDER BLACK ON BLUE +COLOR ASK TITLE WHITE ON BLUE +COLOR ASK SELECTOR BLACK ON LGREY +COLOR ASK HIGHLIGHT LCYAN ON BLUE +COLOR ASK BTYPE 0 +COLOR ASK NOSELECT LGREY ON BLUE +COLOR MENU WINDOW BLACK ON LGREY +COLOR MENU BORDER BLUE ON LGREY +COLOR MENU TITLE WHITE ON RED +COLOR MENU SELECTOR WHITE ON BLUE +COLOR MENU HIGHLIGHT WHITE ON RED +COLOR MENU NOSELECT DGREY ON CYAN +COLOR HELP WINDOW WHITE ON GREEN +COLOR HELP BORDER YELLOW ON GREEN +COLOR HELP SELECTOR BLACK ON LGREY +COLOR HELP HIGHLIGHT YELLOW ON CYAN +COLOR HELP BTYPE 0 +COLOR INFO WINDOW WHITE ON RED +COLOR INFO BORDER WHITE ON RED +COLOR INFO BTYPE 0 +COLOR SHADOW DGREY ON BLACK +COLOR MENU BTYPE BLACK ON BLACK +COLOR INFO TITLE WHITE ON RED +;---------------------------THATS IT---------------------------------------- diff --git a/cfgs/colorset/gedcol23.cfg b/cfgs/colorset/gedcol23.cfg new file mode 100644 index 0000000..11b8b91 --- /dev/null +++ b/cfgs/colorset/gedcol23.cfg @@ -0,0 +1,68 @@ +;---------------------------GOLDED COLOR CONFIGURATION---------------------- +; DESCRIPTION: OS/2 Friendly 2 +; MADE WITH GEDCOLOR 1.00 BY MICHAEL REILER +;--------------------------------------------------------------------------- +COLOR AREA WINDOW BLACK ON LGREY +COLOR AREA BORDER BLUE ON LGREY +COLOR AREA TITLE BLUE ON LGREY +COLOR AREA SELECTOR WHITE ON BLUE +COLOR AREA HIGHLIGHT RED ON LGREY +COLOR AREA BTYPE 0 +COLOR STATUS WINDOW WHITE ON BLUE +COLOR BACKGROUND WINDOW BLACK ON LGREY +COLOR BACKGROUND BORDER LGREY ON LGREY +COLOR BRAG WINDOW WHITE ON BLUE +COLOR BRAG BORDER LBLUE ON BLUE +COLOR BRAG TITLE YELLOW ON BLUE +COLOR BRAG HIGHLIGHT WHITE ON BLUE +COLOR BRAG BLOCK LBLUE ON BLUE +COLOR BRAG BTYPE 0 +COLOR HEADER EDIT RED ON LGREY +COLOR HEADER WINDOW BLUE ON LGREY +COLOR HEADER BORDER YELLOW ON LGREY +COLOR HEADER TITLE RED ON LGREY +COLOR HEADER INPUT WHITE ON BLUE +COLOR HEADER HIGHLIGHT RED ON LGREY +COLOR HEADER BTYPE 2 +COLOR READER WINDOW BLACK ON LGREY +COLOR READER BORDER DGREY ON LGREY +COLOR READER QUOTE BLUE ON LGREY +COLOR READER KLUDHIDD DGREY ON LGREY +COLOR READER BTYPE 0 +COLOR READER TEARORIG BLUE ON LGREY +COLOR READER BLOCK BLACK ON CYAN +COLOR READER HIGHLIGHT BLINKING WHITE ON RED +COLOR READER CURSOR RED ON LGREY +COLOR ASK WINDOW LGREY ON BLUE +COLOR ASK BORDER LBLUE ON BLUE +COLOR ASK TITLE YELLOW ON BLUE +COLOR ASK SELECTOR WHITE ON RED +COLOR ASK HIGHLIGHT YELLOW ON BLUE +COLOR ASK BTYPE 0 +COLOR ASK NOSELECT LGREY ON BLUE +COLOR MENU WINDOW BLACK ON LGREY +COLOR MENU BORDER BLUE ON LGREY +COLOR MENU TITLE RED ON LGREY +COLOR MENU SELECTOR WHITE ON BLUE +COLOR MENU HIGHLIGHT RED ON LGREY +COLOR MENU NOSELECT DGREY ON LGREY +COLOR HELP WINDOW BLACK ON LGREY +COLOR HELP BORDER BLUE ON LGREY +COLOR HELP SELECTOR WHITE ON RED +COLOR HELP HIGHLIGHT RED ON LGREY +COLOR HELP BTYPE 0 +COLOR INFO WINDOW WHITE ON BLUE +COLOR INFO BORDER LBLUE ON BLUE +COLOR INFO BTYPE 0 +COLOR SHADOW DGREY ON BLACK +COLOR MENU BTYPE BLACK ON BLACK +COLOR INFO TITLE YELLOW ON BLUE + +COLOR HEADER FROM BLUE ON LGREY +COLOR HEADER TO BLUE ON LGREY +COLOR HEADER SUBJECT BLUE ON LGREY +COLOR READER TAGLINE BLUE ON LGREY +COLOR READER TEARLINE BLUE ON LGREY +COLOR READER ORIGIN BLUE ON LGREY + +;---------------------------THATS IT---------------------------------------- diff --git a/cfgs/colorset/gedmon00.cfg b/cfgs/colorset/gedmon00.cfg new file mode 100644 index 0000000..1b391b5 --- /dev/null +++ b/cfgs/colorset/gedmon00.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. (Monocrome) +; ----------------------------------------------------------------------------- +; By Odinn Sorensen. + +COLOR AREA BORDER Reverse +COLOR AREA HIGHLIGHT Highlight +COLOR AREA SELECTOR Normal +COLOR AREA TITLE Reverse +COLOR AREA WINDOW Reverse +COLOR ASK BORDER Normal +COLOR ASK HIGHLIGHT Reverse +COLOR ASK NOSELECT Normal +COLOR ASK SELECTOR Reverse +COLOR ASK TITLE Highlight +COLOR ASK WINDOW Normal +COLOR BACKGROUND WINDOW Highlight +COLOR BRAG BLOCK Normal +COLOR BRAG BORDER Normal +COLOR BRAG HIGHLIGHT Highlight +COLOR BRAG TITLE Highlight +COLOR BRAG WINDOW Highlight +COLOR HEADER BORDER Reverse +COLOR HEADER EDIT Reverse +COLOR HEADER HIGHLIGHT Reverse +COLOR HEADER INPUT Reverse +COLOR HEADER TITLE Reverse +COLOR HEADER WINDOW Reverse +COLOR HELP BORDER Highlight +COLOR HELP HIGHLIGHT Highlight +COLOR HELP SELECTOR Reverse +COLOR HELP WINDOW Normal +COLOR INFO BORDER Highlight +COLOR INFO TITLE Highlight +COLOR INFO WINDOW Highlight +COLOR MENU BORDER Reverse +COLOR MENU HIGHLIGHT Reverse +COLOR MENU NOSELECT Reverse +COLOR MENU SELECTOR Highlight +COLOR MENU TITLE Highlight +COLOR MENU WINDOW Reverse +COLOR READER BLOCK Reverse +COLOR READER BORDER Normal +COLOR READER CURSOR Normal +COLOR READER KLUDHIDD Highlight +COLOR READER QUOTE Highlight +COLOR READER TEARORIG Normal +COLOR READER WINDOW Normal +COLOR SHADOW Normal +COLOR STATUS WINDOW Reverse diff --git a/cfgs/colorset/gedmon01.cfg b/cfgs/colorset/gedmon01.cfg new file mode 100644 index 0000000..e465124 --- /dev/null +++ b/cfgs/colorset/gedmon01.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. (Monocrome) +; ----------------------------------------------------------------------------- +; By Stig Jacobsen. + +COLOR AREA BORDER Normal +COLOR AREA HIGHLIGHT Highlight +COLOR AREA SELECTOR Reverse +COLOR AREA TITLE Highlight +COLOR AREA WINDOW Normal +COLOR ASK BORDER Reverse +COLOR ASK HIGHLIGHT Highlight +COLOR ASK NOSELECT Normal +COLOR ASK SELECTOR Highlight +COLOR ASK TITLE Reverse +COLOR ASK WINDOW Reverse +COLOR BACKGROUND WINDOW Highlight +COLOR BRAG BLOCK Normal +COLOR BRAG BORDER Normal +COLOR BRAG HIGHLIGHT Highlight +COLOR BRAG TITLE Highlight +COLOR BRAG WINDOW Highlight +COLOR HEADER BORDER Normal +COLOR HEADER EDIT Reverse +COLOR HEADER HIGHLIGHT Highlight +COLOR HEADER INPUT Highlight +COLOR HEADER TITLE Highlight +COLOR HEADER WINDOW Normal +COLOR HELP BORDER Reverse +COLOR HELP HIGHLIGHT Reverse +COLOR HELP SELECTOR Highlight +COLOR HELP WINDOW Reverse +COLOR INFO BORDER Normal +COLOR INFO TITLE Normal +COLOR INFO WINDOW Highlight +COLOR MENU BORDER Normal +COLOR MENU HIGHLIGHT Highlight +COLOR MENU NOSELECT Normal +COLOR MENU SELECTOR Reverse +COLOR MENU TITLE Reverse +COLOR MENU WINDOW Normal +COLOR READER BLOCK Normal +COLOR READER BORDER Normal +COLOR READER CURSOR Highlight +COLOR READER KLUDHIDD Highlight +COLOR READER QUOTE Highlight +COLOR READER TEARORIG Normal +COLOR READER WINDOW Normal +COLOR SHADOW Normal +COLOR STATUS WINDOW Reverse diff --git a/cfgs/colorset/gedmon02.cfg b/cfgs/colorset/gedmon02.cfg new file mode 100644 index 0000000..a9aec07 --- /dev/null +++ b/cfgs/colorset/gedmon02.cfg @@ -0,0 +1,50 @@ + +; GoldED Example Color Configuration. (Monocrome) +; ----------------------------------------------------------------------------- +; By Erik Wachtmeester. + +COLOR AREA BORDER Highlight +COLOR AREA HIGHLIGHT Highlight +COLOR AREA SELECTOR Reverse +COLOR AREA TITLE Highlight +COLOR AREA WINDOW Normal +COLOR ASK BORDER Reverse +COLOR ASK HIGHLIGHT Reverse +COLOR ASK NOSELECT Normal +COLOR ASK SELECTOR Highlight +COLOR ASK TITLE Reverse +COLOR ASK WINDOW Reverse +COLOR BACKGROUND WINDOW Normal +COLOR BRAG BLOCK Normal +COLOR BRAG BORDER Normal +COLOR BRAG HIGHLIGHT Highlight +COLOR BRAG TITLE Highlight +COLOR BRAG WINDOW Highlight +COLOR HEADER BORDER Highlight +COLOR HEADER EDIT Reverse +COLOR HEADER HIGHLIGHT Highlight +COLOR HEADER INPUT Reverse +COLOR HEADER TITLE Highlight +COLOR HEADER WINDOW Normal +COLOR HELP BORDER Highlight +COLOR HELP HIGHLIGHT Highlight +COLOR HELP SELECTOR Reverse +COLOR HELP WINDOW Normal +COLOR INFO BORDER Reverse +COLOR INFO TITLE Reverse +COLOR INFO WINDOW Reverse +COLOR MENU BORDER Reverse +COLOR MENU HIGHLIGHT Reverse +COLOR MENU NOSELECT Normal +COLOR MENU SELECTOR Highlight +COLOR MENU TITLE Reverse +COLOR MENU WINDOW Reverse +COLOR READER BLOCK Reverse +COLOR READER BORDER Normal +COLOR READER CURSOR Normal +COLOR READER KLUDHIDD Highlight +COLOR READER QUOTE Highlight +COLOR READER TEARORIG Normal +COLOR READER WINDOW Normal +COLOR SHADOW Normal +COLOR STATUS WINDOW Reverse diff --git a/cfgs/config/advanced.cfg b/cfgs/config/advanced.cfg new file mode 100644 index 0000000..9035105 --- /dev/null +++ b/cfgs/config/advanced.cfg @@ -0,0 +1,1811 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.00 * Example Configuration File, Advanced Edition. +// +// This configuration file demonstrates just about all configuration +// keywords available in GoldED 3.00. +// +// A number of keywords are location dependent and must be placed in +// a particular order to ensure correct operation. The exact list of +// location dependent keywords can be found in a chapter in the +// manual. This example configuration file shows the location +// dependent keywords in the recommended places. +// +// WARNING! YOU MUST EDIT THIS FILE FOR YOUR SETUP BEFORE USING IT! +// +// PLEASE NOTE: It is NOT advisable to use this configuration file +// with older versions! There are many new keywords and certain bugs +// in older versions may surface if this configuration file is used. +// +// ------------------------------------------------------------------ +// last update on 98/07/28 (DAM) +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- REGISTRATION + +// Put your old GoldED 2.xx style key here or in a file named +// GOLDED.KEY. Note that you better place it into GOLDED.KEY, which is +// also automatically read by GoldED. + +;SERIALNO +;REGISTERNAME +;REGISTERKEY + + +---------------------------------------------------------------------- +-- NAME AND ADDRESSES (for internet addresses, see a later section) + +// Your name and aliases and (misspellings). +USERNAME Odinn Sorensen +USERNAME Odinn S›rensen +USERNAME Odinn Sorenson +USERNAME Odinn Soerenson +USERNAME Odinn +USERNAME Odin Sorensen +USERNAME Odin S›rensen +USERNAME Odin Sorenson +USERNAME Odin Soerenson +USERNAME Odin + +// Your FTN-style address and akas. +ADDRESS 2:236/77 ; A main node address. +AKA 2:236/77.1 ; A sysop point. +AKA 2:236/77.2@fidonet.org ; A point address with domain ("5D"). +AKA 2:236/77.999, 16077 ; A point address with fakenet ("3D"). +AKA 27:1345/118 ; An aka in another zone. + + +---------------------------------------------------------------------- +-- AKA MATCHING + +// Setup special aka matching for OtherNets that span several zones. +// A default aka matching like +// AKAMATCH 27:* 27:1345/118 +// is automatically done by GoldED. + +AKAMATCH 25:* 27:1345/118 +AKAMATCH 26:* 27:1345/118 +AKAMATCH 28:* 27:1345/118 +AKAMATCH 29:* 27:1345/118 +AKAMATCH 30:* 27:1345/118 + +// Where to enable or disable aka matching. +AKAMATCHNET YES ; Enable aka matching in netmail. +AKAMATCHECHO NO ; No aka matching in echomail. +AKAMATCHLOCAL NO ; No aka matching in local areas. + + +---------------------------------------------------------------------- +-- NODELISTS AND USERLISTS + +// The path to your nodelists. +NODEPATH R:\NODELIST\ + +// Filenames of your nodelists. +// If extention is ".*" or ".999", the newest is used automatically. +NODELIST FDNET.PVT +NODELIST FDPOINT.PVT +NODELIST NODELIST.999 +;NODELIST 117LIST.999 117 +;NODELIST DBRIDGE.PVT 2:236/77 + +// Filenames of your userlists (FIDOUSER.LST format). +;USERLIST FIDOUSER.LST +;USERLIST GOLDED.LST +;USERLIST DK-POINT.NAM + +// Uncomment this to use FrontDoor nodelist indexes. +;NODEPATHFD R:\NODELIST\ + +// Uncomment this to use InterMail nodelist indexes. +;NODEPATHIM R:\NODELIST\ + +// Uncomment this to use Version 7 nodelist indexes. +;NODEPATHV7 R:\NODELIST\ + +// Uncomment this to use a raw FIDOUSER.LST file. +;FIDOUSERLIST R:\NODELIST\FIDOUSER.LST + +// Define nodes to be excluded from the GoldED nodelist index. +// This can be used to save disk space or nodelist compile time. +;EXCLUDENODES 4:*/*.* +;EXCLUDENODES 5:*/*.* +;EXCLUDENODES 6:*/*.* + +// Define nodes to be included, even if excluded before. +;INCLUDENODES 4:4/*.0 +;INCLUDENODES 5:5/*.0 +;INCLUDENODES 6:6/*.0 + + +---------------------------------------------------------------------- +-- NODELIST LOOKUP + +// Where to allow nodelist lookup when entering messages. +LOOKUPNET YES +LOOKUPECHO NO +LOOKUPLOCAL NO + + +---------------------------------------------------------------------- +-- ADDRESS MACROS + +// Shorthand names for easy addressing. +ADDRESSMACRO odin,Odinn Sorensen,2:236/77,Hi there! :-) +ADDRESSMACRO af512,AreaFix,2:236/512,"PASSWORD -q -l",CRA +ADDRESSMACRO ff512,AllFix,2:236/512,"PASSWORD -q -l",CRA +ADDRESSMACRO odinwb,@odinn@winboss.dk,1:105/42 +ADDRESSMACRO odinibm,@odinn@ibm.net,1:105/42 + +// Additional address macros can be placed in an external file. +// Supports the format used by FrontDoor, Maximus etc. +NAMESFILE R:\FD\NAMES.FD + + +---------------------------------------------------------------------- +-- MESSAGE READER (HEADER) + +// Display the size of the current message in the bottom left side. +DISPMSGSIZE BYTES +;DISPMSGSIZE KBYTES +;DISPMSGSIZE LINES +;DISPMSGSIZE NO + +// Display the size of attached file(s) below the subject line. +;DISPATTACHSIZE BYTES +DISPATTACHSIZE KBYTES +;DISPATTACHSIZE NO + +// Display the board number in []'s in the top left side. +DISPAREANO YES ; Only shows it if available. +;DISPAREANO ALWAYS ; Will show 0 if there is no board number. + +// Positions and lengths of name/node/date fields in header display. +// These are the default values. +;DISPHDRNAMESET 8 36 +;DISPHDRNODESET 44 16 +;DISPHDRDATESET -20 20 + +// GoldED can display either the real message numbers or automatically +// calculated relative numbers. Can be toggled with Alt-Y. +;DISPREALMSGNO YES + +// Highlight the FROM name in msgs with the LOC attribute set? +// Also highlights in the msglist. +DISPLOCALHIGH Yes + + +---------------------------------------------------------------------- +-- MESSAGE READER (MESSAGES) + +// GoldED jumps to the first message after the lastread when entering +// an area. You can disable that behaviour here. +;DISPAUTONEXT NO + +// Margin for displayed messages. +;DISPMARGIN 0 ; Margin set to screen width (default). +;DISPMARGIN -1 ; Margin set to screen width minus one. +;DISPMARGIN 70 ; Margin fixed at column 70. + +// Enable a "pagebar" (scrollbar) for messages. The pagebar shows what +// part and how much of the message that is being shown. It looks like +// a mousable scrollbar, but unfortunately there is currently no mouse +// support in GoldED. +DISPPAGEBAR Yes + +// The number of spaces to display when a tab character is found or +// when the Tab key is pressed in the internal editor. +DISPTABSIZE 4 + +// Display hidden lines (kludges not on the "known" list). +VIEWHIDDEN YES + +// Display known kludges. This includes those defined with KLUDGE. +VIEWKLUDGE NO + +// How to display quotes in messages. +VIEWQUOTE YES ; Show all quotes. +;VIEWQUOTE NO ; Show only the first line of each paragraph. + +// Treat the soft-cr (ASCII 141) as any other character. +// The soft-cr is a special case in FidoNet and is often stripped. +;DISPSOFTCR YES + + +---------------------------------------------------------------------- +-- MESSAGE READER (WRITE TO FILE) + +// Default output file for the Alt-W command. +;OUTPUTFILE GOLDED.OUT + +// File aliases. Shorthand names for filenames you write often. +;FILEALIAS DKB R:\DKBBS\DKBBS +;FILEALIAS DKP R:\DKPOINT\POINTS +;FILEALIAS VOTE R:\VOTES\VOTE.LST + + +---------------------------------------------------------------------- +-- MESSAGE READER (MISCELLANEOUS) + +// Name of a FIDOUSER.LST-style file where the names of participants +// of a conference can be placed, using the Ctrl-L function. +USERLISTFILE GOLDED.LST + +// Path where GoldED can create files decoded from uuencoded messages. +UUDECODEPATH R:\FILE\ + +// Automatically add users when replying to their mails to the +// addressbook +;ADDRESSBOOKADD NO ; No, never automatically add an user +ADDRESSBOOKADD YES ; Add only if it's a netmail +;ADDRESSBOOKADD ALWAYS ; Yes, add them always. + + +---------------------------------------------------------------------- +-- CONFIRMATION RECEIPTS + +// Message attributes to set on confirmation receipt messages. +ATTRIBSCFM PVT RRC K/S + +// Confirmation receipt template. +CONFIRMFILE GOLDED.CFM + +// Define how GoldED should respond when you read a message with the +// confirmation request attribute set. +CONFIRMRESPONSE ASK ; Pop up a menu for your choice. +;CONFIRMRESPONSE YES ; Generate receipt automatically. +;CONFIRMRESPONSE NO ; Never generate a receipt. + + +---------------------------------------------------------------------- +-- FILE REQUESTING (see also INBOUND AND OUTBOUND) + +// Message attributes to set automatically on file request messages. +ATTRIBSFRQ PVT CRA K/S + +// Known file extensions +FRQEXT .A?? +FRQEXT .L?? +FRQEXT .Z?? +;FRQEXT .* + +// Map certain nodenumbers in announcements to another. Useful if you +// always want to request at the ISDN line, regardless of the origin +// aka of the announcement. +// change-to: from: +FRQNODEMAP 2:236/99 2:236/100 +FRQNODEMAP 2:2468/9909 2:2468/9909.9 + +// Options for the file request function. See the manual for details. +;FRQOPTIONS FAST ; Bypass the header edit. +;FRQOPTIONS NOFILES ; Don't list the file "FILES". +;FRQOPTIONS FROMTOP, SORT ; Get all files in the msg. Sort the list. + +// Enable this if you want GoldED to use WaZOO-style file requests. +;FRQWAZOO YES + +// Bypass the area selection list when file requesting. +;AREAFREQDIRECT YES + +// Set the destination area for file requests. +// Defaults to the first netmail area if not specified. +;AREAFREQTO NETMAIL + + +---------------------------------------------------------------------- +-- INBOUND AND OUTBOUND + +// Path to FILES.BBS for descriptions of requested files. +INBOUNDPATH R:\FILE\ + +// Default path for attached files without a path. +ATTACHPATH R:\FILE\ + +// Binkley-style outbound path. Currently only used for WaZOO .REQ +// file requests. This should be the name of your primary outbound +// without extension. +;OUTBOUNDPATH R:\BINKLEY\OUTBOUND + + +---------------------------------------------------------------------- +-- COPY/MOVE/REPLIES + +// Set the default area for replies/forwards to other areas. +// If not specified, the first netmail area is used. +AREAREPLYTO NETMAIL + +// Enable this to bypass the area selection list, for a "seamless" +// reply or forward to another area. This keyword should not be used +// globally. Use it in a Random System group for specific areas. +;AREAREPLYDIRECT YES + +// Set the default area for the Copy/Move function. +AREACOPYTO THE_SAFE + +// Enable this to bypass the area selection list, for a "seamless" +// copy/move to another area. This keyword should not be used +// globally. Use it in a Random System group for specific areas. +;AREACOPYDIRECT YES + +// If enabled, GoldED will insert the control line "AREA:" +// at the top of each message that is copied or moved. Use with care! +;AREACOPYADDID YES + + +// If enabled, GoldED will copy all self-written mails to this area. +// +;AREAYOUWROTETO MY_MAILS + +---------------------------------------------------------------------- +-- STATUSLINE + +// By default GoldED puts its logo (name and version) in the left side +// of the statusline. You can change it to a small help text or +// eliminate the logo entirely for a wider statusline message field. +;STATUSLINEHELP YES +;STATUSLINEHELP NOLOGO + +// Put a real-time clock in the statusline. +// The format of the clock can be changed with the language +// configuration keyword ST_STATUSLINETIMEFMT in GOLDLANG.CFG. +// NOTE: The clock will only run continuously if KEYBMODE is set to "POLL". +STATUSLINECLOCK YES + + +---------------------------------------------------------------------- +-- MESSAGE EDITOR + +// Chars to display instead of CR and space in the internal editor. +EDITCHARPARA '' +EDITCHARSPACE 'ú' + +// Positions and lengths of name/node/date fields in header edit +// These are the default values. +;EDITHDRNAMESET 8 36 +;EDITHDRNODESET 44 36 + +// Enable or disable the internal editor. +EDITINTERNAL YES +;EDITINTERNAL NO + +// Define commandline for an external editor. +IF DOS + EDITOR U:\QE3\DOS\Q.EXE @file -N@line +ELSEIF OS/2 + EDITOR U:\QE3\Q.EXE @file -N@line +ENDIF + +// How to execute an external editor via batchfiles. +;EDITOR C:\COMMAND.COM /C C:\BAT\MYEDITOR.BAT +;EDITOR C:\4DOS\4DOS.COM /C C:\BAT\Q.BTM @file -N@line + +// External editor message file and internal editor backup file. +EDITORFILE GOLDED.MSG + +// Enable the hardline feature when using the external editor. +EDITHARDLINES YES + +// Hardline string for the external editor, if used. +EDITHARDLINE << + +// Enable this to set the file attach attribute automatically when +// entering a filename with drive (like C:) in the subject line. +EDITAUTOATTACH YES + +// Message attributes to set automatically on file attach messages. +ATTRIBSATTACH CRA + +// Internal editor automatic message backup interval in seconds. +// Set this to zero if you don't want automatic backups. +EDITAUTOSAVE 30 + +// When to change the "date written" when changing a message. +;EDITCHANGEDATE ALWAYS ; On all messages. +EDITCHANGEDATE YES ; Only on messages written by yourself. +;EDITCHANGEDATE NO ; Never change the date. + +// Editor comments. Try typing these in the internal editor :-) +EDITCOMMENT ":-(" "Don't worry, be happy!" +EDITCOMMENT ":-)" "Are we having fun yet?" +EDITCOMMENT ";-)" "Wink wink, nudge nugde..." +EDITCOMMENT "!!!" "Flame Warning!" +EDITCOMMENT "GoldED" "Great program, ain't it?" +EDITCOMMENT "Odin" "One more 'n' please." +EDITCOMMENT "Odinn" "That's right :-)" +EDITCOMMENT "Odinnn" "Oops! One 'n' too many! :-)" + +// Define strings that will be expanded automatically when typed in the +// internal editor. Choose your string with care or you might get +// unexpected results! +EDITCOMPLETION "/GE" "GoldED" +EDITCOMPLETION "/FD" "FrontDoor" +EDITCOMPLETION "/V7" "Version 7" + +// How to terminate text paragraphs and quoted lines. +;EDITCRLFTERM YES ; With both CR and LF. +EDITCRLFTERM NO ; Only with CR. + +// Termination of lines or paragraphs. +;EDITHARDTERM YES ; Terminate all lines at the display margin. +EDITHARDTERM NO ; Terminate only at the end of paragraphs. + +// Clear edit-fields when first pressing a non-editing key? +EDITFIELDCLEAR Yes + +// Enable the "Edit menu" (pops up after header edit)? +EDITMENU YES + +// Enable the "Save menu" (pops up after ext./int. editor)? +EDITSAVEMENU YES + +// Automatically mix letter case when entering names in the header? +// Example: "oDiNn sOrEnSeN" would be mixcased to "Odinn Sorensen". +;EDITMIXCASE YES + +// Limit the size of messages GoldED can load. +;EDITMSGSIZE 64000 ; Default for the DOS version. +;EDITMSGSIZE 512000 ; Default for the 386 and OS/2 versions. + +// Define the commandline for a spell checker. +IF DOS + EDITSPELLCHECK C:\SPELL\SS.EXE @file +ELSEIF OS/2 + EDITSPELLCHECK C:\OS2\CMD.EXE /C C:\SPELL\SS.EXE @file +ENDIF + +// How to handle the "Re:" string in the subject when replying. +;EDITREPLYRE YES ; Add "Re:" if there isn't one. +;EDITREPLYRE NUMERIC ; Add "Re^2:" if there's already one. +EDITREPLYRE NO ; Remove the "Re:" if there is one. + +// How many lines to keep in the undelete buffer. +EDITUNDELETE 50 + +// When importing text into the internal editor, GoldED can translate +// the soft-cr (ASCII 141) character to another. +;EDITSOFTCRXLAT H ; Example for Russians. + +// Right margin for editing quotes in the internal editor. +EDITQUOTEMARGIN 75 + +// "Robot" names. Writing a msg to one of these tells GoldED to use a +// special minimal template, definable with the MS_ROBOTMSG language +// keyword in GOLDLANG.CFG. +ROBOTNAME AreaFix +ROBOTNAME AreaMgr +ROBOTNAME AreaLink +ROBOTNAME FileFix +ROBOTNAME ImlaList +ROBOTNAME Raid +ROBOTNAME GEcho +ROBOTNAME Allfix + +// What to do when writing a message to another zone. +ZONEGATING ASK ; Pop up a menu for your decision. +;ZONEGATING YES ; Send it via the zonegate. +;ZONEGATING NO ; Never use zonegating. + +// Default destination name for new echomail/localmail messages. +WHOTO All + +// Default filename for the internal editor import text prompt. +;INPUTFILE myfile + +// Text to put before and after an imported file in the i.e. +;IMPORTBEGIN === Begin @file === +;IMPORTEND === End @file === + +// Use this if you don't want any text (default is "=== Cut ==="). +;IMPORTBEGIN "" + +// Turn on or off the large attributes window during header edit. +;EDITHEADERATTRS YES + +// This keyword controls which circumstances that will make GoldED +// present you with the header editor first of all. +;EDITHEADERFIRST YES ; Always +;EDITHEADERFIRST NEW, CHANGES ; Only for new or changed msgs. + + +---------------------------------------------------------------------- +-- MESSAGE TEMPLATES + +// Path to the template files. Defaults to the GOLDPATH. +;TEMPLATEPATH R:\GOLDED\TPLS\ + +// Select template based on the address of the message you want to +// reply to. +TEMPLATEMATCH YES + +// Message template filenames and descriptions. +TEMPLATE GOLDED.TPL "Default template" +TEMPLATE EMAIL.TPL "E-mail template" +TEMPLATE NEWSGRPS.TPL "Newsgroups template" +TEMPLATE DANSK.TPL "Dansk skabelon" 2:23/* ; +TEMPLATE DANSK.TPL "Dansk skabelon" 2:234/* ; Used for +TEMPLATE DANSK.TPL "Dansk skabelon" 2:235/* ; template +TEMPLATE DANSK.TPL "Dansk skabelon" 2:236/* ; matching +TEMPLATE DANSK.TPL "Dansk skabelon" 2:237/* ; +TEMPLATE DANSK.TPL "Dansk skabelon" 2:238/* ; + + +---------------------------------------------------------------------- +-- QUOTING + +// Enable this to put the QUOTESTRING on quoted blank lines. +;QUOTEBLANK YES + +// The margin for quotes in a reply. +QUOTEMARGIN 70 + +// Add blank lines before and after blocks of quotes in messages? +;QUOTESPACING YES + +// Your quote prefix string. Must contain a '>' character! +QUOTESTRING " FL> " + + +---------------------------------------------------------------------- +-- REPLYLINKING + +// How to do replylinking when replying. +;REPLYLINK Chain ; Link to last msg in a subject-based reply chain. +REPLYLINK Direct ; Link directly to the original message. + +// How to build the replylink selection menu in JAM and Squish areas. +REPLYLINKLIST FAST ; Use only header/subfield data. +;REPLYLINKLIST FULL ; Use full msgbody, parsing kludges, origin etc. + + +---------------------------------------------------------------------- +-- PERSONAL MAIL + +// Personal mail scan options. +PERSONALMAIL ALLNAMES ; Scan with all your USERNAME's. +;PERSONALMAIL STARTUP ; Scan for personal mail at startup. +;PERSONALMAIL STARTUP, ALLNAMES ; Both. + + +---------------------------------------------------------------------- +-- CARBON COPY AND CROSSPOSTING + +// Message attributes to set on carbon copy messages. +ATTRIBSCC PVT K/S + +// Format of the Carbon Copy list. +;CARBONCOPYLIST KEEP ; Keep list as entered. +CARBONCOPYLIST NAMES ; Rewrite as a list of names. +;CARBONCOPYLIST VISIBLE ; Rewrite list with names and addresses. +;CARBONCOPYLIST HIDDEN ; Rewrite list in CC: kludges. +;CARBONCOPYLIST REMOVE ; Remove the carbon copy list entirely. + +// Format of the crossposting list. +CROSSPOSTLIST VERBOSE ; Expand crosspost list verbosely. +;CROSSPOSTLIST RAW ; Keep list as entered. +;CROSSPOSTLIST NONE ; Remove the crosspost list. + + +---------------------------------------------------------------------- +-- INTERNET FEATURES Please read the manual for details. + +// Your primary internet address. +INTERNETADDRESS odinn@winboss.dk + +// The organization information to put in the "Organization:" RFC header. +ORGANIZATION Goldware International + +// Defines the name and FTN address of your local Internet gate. +;INTERNETGATE UUCP, 1:105/42 ; Standard, with a specific gate name. +INTERNETGATE 2:230/9316 ; For uplinks running GIGO software. + +// Use a Message-ID compatible MSGID in areas marked as e-mail and newsgroups? +;INTERNETMSGID YES + +// What to do with Internet addresses when replying. +INTERNETREPLY YES ; Always use the FSC-35 method. +;INTERNETREPLY NO ; Only use FSC-35 if the address is too long. + +// Check the nodelist system name for an Internet address. +INTERNETLOOKUP Yes + +// Specify characters in addition to ">" to be recognized as quote characters. +// This keyword should not be used globally. Use it in Internet GROUP's. +;QUOTECHARS "|:;" + +// Path where unpacked SOUP format packets can be found. +SOUPIMPORTPATH M:\SOUP\ + +// Path where SOUP reply packets can be created. +SOUPEXPORTPATH M:\SOUP\ + +// Margin for SOUP style areas (76 chars is default). +;SOUPEXPORTMARGIN 76 + +// Filename of your .newsrc file, listing the active newsgroups. +// Newsgroups listed in this file are marked as newsgroups in GoldED. +SOUPNEWSRCFILE M:\SOUP\NEWSRC + +// Name of an area where articles for unknown newsgroups can be placed +// when importing SOUP packets. +SOUPBADMSGS BAD_MSGS + +// Name of an area for Internet e-mails. This must be a netmail area. +// E-mails imported from SOUP packets are placed here. +SOUPEMAIL NET_EMAIL + +// GoldED will put the echoid of imported newsgroups in this file. +// This is for use with an external replylinker. +SOUPTOSSLOG R:\GECHO\IMPORT.JAM + +// Commandline for an external replylinker to call automatically +// after importing a SOUP packet. +IF DOS + SOUPREPLYLINKER R:\GECHO\MBUTIL Link +ELSEIF OS/2 + SOUPREPLYLINKER E:\OS2\CMD.EXE /C R:\GECHO\MBUTIL Link +ENDIF + +// Mark this area as e-mail. +;AREAISEMAIL NET_EMAIL + +// Mark these areas as newsgroups. +;AREAISNEWS ALT.*, COMP.*, MISC.*, NEWS.* +;AREAISNEWS REC.*, SOC.*, SCI.*, TALK.* + +// Don't use tearline and origin in e-mail +CTRLINFOEMAIL NO + +// Don't use tearline and origin in newsgroups +CTRLINFONEWS NO + +// Define some mailing lists. +// When importing from SOUP packets, GoldED will toss e-mails to these areas +// if the "Sender:" RFC header matches the Internet address. +// +; EchoID Sender address Address for mail to "all" +;MAILINGLIST LIST.EMX emx-list@eb.ele.tue.nl +;MAILINGLIST LIST.GIGO gigo-owner@gigo.com gigo@gigo.com +;MAILINGLIST LIST.HELP-NET help-net@templevm.bitnet + +// Timezone for the "Date:" RFC header. +// PLEASE read the manual about this keyword before using it!!! +;TIMEZONEOFFSET -1000 ; Alaska-Hawaii Standard Time +;TIMEZONEOFFSET -0900 ; Hawaii Daylight Time +;TIMEZONEOFFSET -0800 ; Pacific Standard Time +;TIMEZONEOFFSET -0700 ; Pacific Daylight Time +;TIMEZONEOFFSET -0700 ; Mountain Standard Time +;TIMEZONEOFFSET -0600 ; Mountain Daylight Time +;TIMEZONEOFFSET -0600 ; Central Standard Time +;TIMEZONEOFFSET -0500 ; Central Daylight Time +;TIMEZONEOFFSET -0500 ; Eastern Standard Time +;TIMEZONEOFFSET -0400 ; Eastern Daylight Time +;TIMEZONEOFFSET -0100 ; West Africa Time +;TIMEZONEOFFSET +0000 ; Greenwich Mean Time +;TIMEZONEOFFSET +0100 ; Central European Time +;TIMEZONEOFFSET +0100 ; British Summer Time +;TIMEZONEOFFSET +0200 ; Central European Summer Time +;TIMEZONEOFFSET +0200 ; Eastern European Time +;TIMEZONEOFFSET +0700 ; West Australian Time +;TIMEZONEOFFSET +0800 ; West Australian Daylight Time +;TIMEZONEOFFSET +0800 ; China Coast Time +;TIMEZONEOFFSET +0900 ; Japan Standard Time +;TIMEZONEOFFSET +0900 ; Central Australian Standard Time +;TIMEZONEOFFSET +1000 ; East Australian Standard Time +;TIMEZONEOFFSET +1000 ; Central Australian Daylight Time +;TIMEZONEOFFSET +1100 ; East Australian Daylight Time +;TIMEZONEOFFSET +1200 ; New Zealand Standard Time +;TIMEZONEOFFSET +1300 ; New Zealand Daylight Time + + +---------------------------------------------------------------------- +-- QWK FEATURES + +// Basic QWK setup +;QWKIMPORTPATH C:\QWK\ +;QWKEXPORTPATH C:\QWK\ +;QWKBADMSGS BAD_QWK + +// Replylinking when using GEcho and Hudson areas: +;QWKTOSSLOG C:\GECHO\IMPORT.HMB +;QWKREPLYLINKER C:\GECHO\MBUTIL Link + +// Replylinking when using GEcho and JAM areas: +;QWKTOSSLOG C:\GECHO\IMPORT.JAM +;QWKREPLYLINKER C:\GECHO\MBUTIL Link + +// Replylinking when using Squish and Squish areas: +;QWKTOSSLOG C:\SQUISH\QWKTOSS.LOG +;QWKREPLYLINKER C:\SQUISH\SQUISH LINK -fC:\SQUISH\QWKTOSS.LOG + +// QWK conference mapping +;QWKCONFMAP GOLDWARE GoldED GOLDED +;QWKCONFMAP GOLDWARE "GoldED Beta" GOLDED.BETA +;QWKCONFMAP GOLDWARE "BBS Users" BBS.USERS +;QWKCONFMAP WHOKNOWS EMail EMAIL +;QWKCONFMAP WHOKNOWS dk.chat DK.CHAT +;QWKCONFMAP WHOKNOWS dk.test DK.TEST +;QWKCONFMAP XYZ_BBS "XYZ Usr2Usr" XYZ.USERS + + +---------------------------------------------------------------------- +-- TWIT SETUP A "Twit" is the name of an annoying user or subject. + +// What to do when a Twit message is found. +;TWITMODE SHOW ; Show the message as normal. +TWITMODE BLANK ; Blank the message text. Press a key to view it. +;TWITMODE SKIP ; Skip the message unless it is for you. +;TWITMODE IGNORE ; Skip the message always. +;TWITMODE KILL ; Erase the message if found. + +// Define Twit names and/or addresses. +;TWITNAME John Doe +;TWITNAME 7:654/321.* + +// Define Twit subjects. +;TWITSUBJ "Incredibly boring discussion" +;TWITSUBJ "Yet another flame-fest" + +// What to do when a msg _to_ a TWITNAME is found. +;TWITTO YES ; Msgs to a TWITNAME are also Twit messages +TWITTO NO ; Msgs to a TWITNAME are normal messages + + +---------------------------------------------------------------------- +-- MISCELLANEOUS + +// Path to "cookie" files. Cookie files are a collection of small +// multiline texts separated by empty lines. GoldED can use cookie +// files in the templates using the "@random" template token. +;COOKIEPATH R:\GOLDED\COOKIES\ + +// Enable this if you want the selection bar to wrap around from +// bottom to top (or vice versa) in lists. +;DISPLISTWRAP YES + +// Where to put the selection bar when entering a list. +;DISPLISTCURSOR TOP +DISPLISTCURSOR NEARTOP +;DISPLISTCURSOR MIDDLE +;DISPLISTCURSOR NEARBOTTOM +;DISPLISTCURSOR BOTTOM + +// Seconds of keyboard inactivity before GoldED automatically exits. +;TIMEOUT 600 ; Exit after 10 minutes of inactivity. +TIMEOUT 0 ; Never time out. + +// What to do if timeout happens while in the internal editor. +TIMEOUTSAVEMSG YES ; Save the message to the msgbase. +;TIMEOUTSAVEMSG NO ; Leave it as "unfinished" in GOLDED.MSG. + + +---------------------------------------------------------------------- +-- MESSAGE LIST + +// The message list can be fast or slow. +// Slow mode gets more data from each message. +MSGLISTFAST YES + +// Start directly in the message list. +MSGLISTFIRST NO + +// Show the header of the message at the selection bar. +// Slows down list scrolling noticably. +MSGLISTHEADER NO + +// Show a pagebar (scrollbar) for the list. +MSGLISTPAGEBAR YES + +// Show the full subject in the bottom border of the list window. +// Slows down list scrolling a bit. +MSGLISTVIEWSUBJ YES + +// Show a wide subject column instead of a to-name column. +MSGLISTWIDESUBJ NO + +// Change which date to show in the message list. +;MSGLISTDATE ARRIVED + +// Highlight unread/unsent messages in the lister and at several other +// places. Note that it doesn't work with all msgbases, see manual. +;HIGHLIGHTUNREAD YES ; Yes, enable this feature. +HIGHLIGHTUNREAD NO ; No, don't care (slightly faster) + + +---------------------------------------------------------------------- +-- GIF SETUP See section about EXTERNUTIL for setting up GIF viewing. + +// The name of your own GIF. Don't specify an extension. +;GIF ODINN + +// Path to your collection of personal GIF's. +GIFPATH X:\GFX_ART\ + + +---------------------------------------------------------------------- +-- KEYBOARD AND MOUSE + +// Use the built-in default keyboard layout? (default is YES) +;KEYBDEFAULTS YES + +// Clear keyboard buffer when starting GoldED? +;KEYBCLEAR YES + +// Enable or disable use of extended keycodes. +// Should only be disabled on XT's. +;KEYBEXT NO + +// Poll mode is necessary if you want a continuous clock, autosave, screenblanker and timeout. +// Block mode is recommended in multitasking environments to get 0% CPU usage. +KEYBMODE Poll +;KEYBMODE Block + +// Stack keys to "press" automatically at startup. +// WARNING: Be careful of side-effects! For example, "@S A" will mark +// all messages in the area if STARTECHO is used. +// NOTE: Commandline keystacking overrides this keyword! +;KEYBSTACK @S A ; Intended to "Scan All" areas. Not useful if you have "AREASCAN *". + +// GoldED does not have any mouse support in this release. +;MOUSE YES + + +---------------------------------------------------------------------- +-- MESSAGE KLUDGE LINES + +// Use the INTL kludge always (YES) or only for inter-zone (AUTO). +// It is highly recommended to enable it always! +USEINTL YES + +// Use the FLAGS kludge. FLAGS is used for certain msg attributes. +USEFLAGS YES + +// Use the MSGID/REPLY kludges. It is NOT recommended to disable it! +USEMSGID YES + +// Use FSC-0092 style forward kludges. +;USEFWD NO ; Disable the use of the kludges. +;USEFWD ASK ; Ask the user every time. +USEFWD YES ; Enable the use of these kludges. + +// Define kludges that you want to be "known" and not displayed. +;KLUDGE "YET:" +;KLUDGE "ANOTHER:" +;KLUDGE "SILLY:" +;KLUDGE "KLUDGE:" + + +---------------------------------------------------------------------- +-- TEARLINES AND ORIGINS + +// Specifies whether to use a tearline and/or origin in your msgs. +CTRLINFONET TEARLINE +CTRLINFOECHO TEARLINE, ORIGIN +CTRLINFOLOCAL TEARLINE, ORIGIN + +// Enable this to get a blank tearline and use a PID kludge instead. +;EMPTYTEARLINE YES + +// Here you can modify the look of your tearline. +// Note that GoldED will also add a PID kludge if the tearline does +// not contain the "@longpid" string somewhere. The "@longpid" string +// is "GoldED", "GoldED/2" or "GoldED/386", depending on the version. +;TEARLINE @longpid @version + +// The default "netname" for the origin. Not recommeded. +;NETNAME FidoNet + +// Your origin lines. +ORIGIN Living in interesting times +ORIGIN This is a message to @dfname :-) +ORIGIN Busier than a one-legged man in an ass-kicking contest + +// Invalidate (modify) quoted control information. +;INVALIDATE Seenby "SEEN-BY" "SEEN+BY" +;INVALIDATE Tearline "--- " "-+- " +;INVALIDATE Origin " * Origin: " " + Origin: " + +// TIP: Use this if you don't want to quote tearline and origin. +;INVALIDATE Tearline "" "" +;INVALIDATE Origin "" "" + + +---------------------------------------------------------------------- +-- TAGLINES + +// You should disable the internal tagline support if you are using an +// external tagline utility. +;TAGLINESUPPORT NO + +// Defines the tagline character. Don't change this. +TAGLINECHAR . + +// Define a tagline collection file. Taglines will be picked randomly. +;TAGLINE @R:\GOLDED\TAGLINE.LST + +// Define a bunch of taglines. These can be selected from a selection menu. +;TAGLINE You have the capacity to learn from mistakes. You'll learn a lot today. +;TAGLINE 10.0 times 0.10 is hardly ever 1.00. +;TAGLINE 2.000.000 Lemmings can't be wrong. +;TAGLINE A $300.00 Picture tube will protect a 10 cent fuse by blowing first. +;TAGLINE A Smith and Wesson beats four aces. + + +---------------------------------------------------------------------- +-- STYLECODES * Colors should be defined in the color section + +// Highlight words with stylecodes around them, such as *bold* etc. +STYLECODES YES + +// Characters that punctuate words for the stylecode feature. +;STYLECODEPUNCT " !?\"$%&()+,.:;<=>@[\\]{|}~\n\r\t" + +// Characters that cancel stylecode highlight in words. +;STYLECODESTOPS "" + + +---------------------------------------------------------------------- +-- DISK AND OPERATING SYSTEM CONFIGURATION + +// Path to the GoldED files. Defaults to where GOLDED.CFG was found. +// It is NOT recommended to define this keyword. It is better to rely +// on the default. +;GOLDPATH R:\GOLDED\ + +// Path where GoldNODE can place a LARGE temporary file. +// Defaults to the GOLDPATH. +;TEMPPATH C:\ + +// Path where a disk swap file can be placed (uses 3-500k). +// Defaults to the TEMPPATH. +;SWAPPATH C:\ + +// Enable this to open files using SHARE.EXE compatible modes. +// This is required for networking/multitasking setups. +SHAREMODE Yes + +// Add a logo-message to the PROMPT in DOS or OS/2 shells? +DOSPROMPT Yes + +// Swapping methods used when shelling to DOS or external editor. +// NOTE: Ignored by GoldED/386 and GoldED/2. +DOSSWAP EMS, XMS, Disk, Hide. + +// Where to put program overlays (EMS/EXT/DISK). +// NOTE: Ignored by GoldED/386 and GoldED/2. +OVERLAY EMS + + +---------------------------------------------------------------------- +-- LOGFILE + +// Name of the GoldED log file. It is NOT recommended to change it. +;LOGFILE GOLDED.LOG ; Default for GoldED for DOS +;LOGFILE GED386.LOG ; Default for GoldED for DOS/386 +;LOGFILE GED2.LOG ; Default for GoldED for OS/2 + + +---------------------------------------------------------------------- +-- NOISES AND SOUND SUPPORT + +// Enable to make a noise when the IE finds an EDITCOMMENT. +BEEPCOMMENT YES + +// Enable to make a noise when encountering a message marked Local +;BEEPLOCALMSG YES + +// Enable various beeps and noises. This is the master ON/OFF switch. +BEEPNOISES YES + +// When to beep when reading a message to you. +;BEEPYOURMAIL ALWAYS ; Beep every time. +BEEPYOURMAIL YES ; Beep only when reading it the first time. +;BEEPYOURMAIL NO ; Never beep on your mail. + +// Path where sound files can be found. +;SOUNDPATH S:\MUSIC\WAV\ + +// Specify which sound file to play for an event. +;EVENT Arealist PLAY DING.WAV +;EVENT AskYesNo PLAY CHOOSE.WAV +;EVENT Attention PLAY CHORD.WAV +;EVENT DosShell PLAY BEAM_DAF.WAV +;EVENT EditComment PLAY CHORD.WAV +;EVENT EndOfMsgs PLAY CHIMES.WAV +;EVENT ErrorFatal PLAY DETRUCT.WAV +;EVENT Exit PLAY SUMBAEHH.WAV +;EVENT JobDone PLAY DING.WAV +;EVENT JobFailed PLAY HAL.WAV +;EVENT MsgDeleting PLAY TRASH.WAV +;EVENT MsgFromYou PLAY DING.WAV +;EVENT MsgIsLocal PLAY DING.WAV +;EVENT MsgIsTwit PLAY SHOTGUN.WAV +;EVENT MsgToYou PLAY HIMAN.WAV +;EVENT SearchFailed PLAY AHHHHH.WAV +;EVENT SearchSuccess PLAY YAAHUHU.WAV +;EVENT Startup PLAY TADA.WAV + + +---------------------------------------------------------------------- +-- MENU DEFAULTS + +// Set default for the "Delete Original?" menu. Default: YES. +;ASKDELORIG NO + +// Set default for the "Drop This Msg?" menu. Default: NO. +;MENUDROPMSG YES + +// Set default for cursor on marked/current msgs menu. +// Choices are: MARKED, CURRENT, PREVIOUS or DEFAULT. +;MENUMARKED DEFAULT + + +---------------------------------------------------------------------- +-- SCREEN AND COLORS + +// Seconds of keyboard inactivity before GoldED blanks the screen. +SCREENBLANKER 300 ; Blank after 5 minutes of inactivity. +;SCREENBLANKER 180 BLACK ; Blank to a total black screen after 3 mins. +;SCREENBLANKER 0 ; Never blank + +// Use BIOS for screen writes? VERY SLOW! +;SCREENUSEBIOS YES + +// Force columns and/or rows if not autodetection fails? (unlikely) +// It is NOT recommended to use this unless absolutely necessary! +;SCREENMAXCOL 80 +;SCREENMAXROW 25 + +// Screen lines setting. +SCREENSIZE AUTO ; Autodetect. +;SCREENSIZE 25 ; Switch to 25 lines mode. +;SCREENSIZE 4350 ; Switch to 43 or 50 lines mode. + +// Set the screen size to a special video mode. +// WARNING: SELECTING THE WRONG MODE CAN DAMAGE YOUR MONITOR!!! +;SCREENSIZE MODE 54 ; Switch to video mode 54 (hexadecimal value). + +// Use shadows on windows and menus? +SCREENSHADOWS YES + +// Modify color palette. +;SCREENPALETTE 0 (0 0 0) +;SCREENPALETTE 1 (0 0 2) +;SCREENPALETTE 2 (0 2 0) +;SCREENPALETTE 3 (0 2 2) +;SCREENPALETTE 4 (2 0 0) +;SCREENPALETTE 5 (2 0 2) +;SCREENPALETTE 6 (2 2 0) +;SCREENPALETTE 7 (2 2 2) +;SCREENPALETTE 8 (1 1 1) +;SCREENPALETTE 9 (1 1 3) +;SCREENPALETTE 10 (1 3 1) +;SCREENPALETTE 11 (1 3 3) +;SCREENPALETTE 12 (3 1 1) +;SCREENPALETTE 13 (3 1 3) +;SCREENPALETTE 14 (3 3 0) +;SCREENPALETTE 15 (3 3 3) + +// Use intense background colors? (this disables blinking colors). +;INTENSECOLORS YES +INTENSECOLORS NO + +// Select default color set. +COLORSET DETECT ; Select based on screencard and intense value. +;COLORSET NORMAL ; Select standard color set. +;COLORSET INTENSE ; Select intense color set. +;COLORSET MONO ; Select standard monochrome set. + +// Include a color setup from another file. +;INCLUDE GEDCOLOR.CFG + + +---------------------------------------------------------------------- +-- EXTERNAL UTILITIES + +// Example for setting up PGP (Pretty Good Privacy). + +EXTERNOPTIONS -pause -nokeepctrl -wipe + +IF DOS + EXTERNUTIL 1 u:\pgp\pgp.exe +force -sa @tmpfile -u "@oname" -o @file ;sign + EXTERNUTIL 2 u:\pgp\pgp.exe +force -sta +clearsig=on @tmpfile -u "@oname" -o @file ;clearsign + EXTERNUTIL 3 u:\pgp\pgp.exe +force -ea @tmpfile "@dname" "@oname" -u "@oname" -o @file ;encrypt + EXTERNUTIL 4 u:\pgp\pgp.exe +force -eas @tmpfile "@dname" "@oname" -u "@oname" -o @file ;enc & sign + EXTERNUTIL 5 u:\pgp\pgp.exe +force @tmpfile -o @file -u "@dname" ;decrypt + EXTERNUTIL 6 -noreload u:\pgp\pgp.exe +force -ka @file -u "@dname" ;add key +ELSEIF OS/2 + EXTERNUTIL 1 u:\pgp\pgp2.exe +force -sa @tmpfile -u "@oname" -o @file ;sign + EXTERNUTIL 2 u:\pgp\pgp2.exe +force -sta +clearsig=on @tmpfile -u "@oname" -o @file ;clearsign + EXTERNUTIL 3 u:\pgp\pgp2.exe +force -ea @tmpfile "@dname" "@oname" -u "@oname" -o @file ;encrypt + EXTERNUTIL 4 u:\pgp\pgp2.exe +force -eas @tmpfile "@dname" "@oname" -u "@oname" -o @file ;enc & sign + EXTERNUTIL 5 u:\pgp\pgp2.exe +force @tmpfile -o @file -u "@dname" ;decrypt + EXTERNUTIL 6 -noreload u:\pgp\pgp2.exe +force -ka @file -u "@dname" ;add key +ENDIF + +EDITSAVEUTIL 1 "S PGP Sign the msg" +EDITSAVEUTIL 2 "L PGP CLear-Sign the msg" +EDITSAVEUTIL 3 "E PGP Encrypt the msg" +EDITSAVEUTIL 4 "T PGP EncrypT & Sign the msg" + +// Add these key definitions in GOLDKEYS.CFG: +// F12 ExternUtil05 ; Press F12 to decrypt the current message. +// #F12 ExternUtil06 ; Press Shift-F12 to add a key to your keyring. + + +// Example for a number of other utilities. + +EXTERNOPTIONS -nocls -nopause -nokeepctrl -nowipe -noreload + +IF DOS + EXTERNUTIL 7 r:\zfax3\zfax.com vf @subject + EXTERNUTIL 8 -cls v:\utl\vpic.exe @gif + EXTERNUTIL 9 -noswap c:\4dos\4dos.com /c echo.>r:\fd\fdxit1.98 +ELSEIF OS/2 + EXTERNUTIL 7 r:\zfax3\zfax.com vf @subject + EXTERNUTIL 8 c:\os2utl\pmview.exe @gif + EXTERNUTIL 9 c:\4os2\4os2.exe /c echo.>r:\fd\fdxit1.98 +ENDIF + +// Add these key definitions in GOLDKEYS.CFG: +// F11 ExternUtil07 ; View a fax +// @F11 ExternUtil08 ; View a GIF +// #F11 ExternUtil09 ; Touch a semaphore file + + +---------------------------------------------------------------------- +-- PRINTER SETUP + +// Name of the printing device (PRN, LPT1, etc) +PRINTDEVICE PRN + +// Add a Form Feed (12d) character after each message? +PRINTFORMFEED YES + +// Printer initialization and reset strings. +// Example for a Canon BJ-10e +;PRINTINIT #18 #27":" #27"X"#16#254 +;PRINTRESET #18 #27"X"#0#80 + +// Example for a HP LaserJet III (PCL-Mode): +;PRINTINIT #27#69 #27#38#97"10"#76 #27#40#115"12"#72 +;PRINTRESET #27#69 + +// Page length. (Number of lines to print before sending a Form Feed). +PRINTLENGTH 60 + +// Right margin for printed messages. +PRINTMARGIN 80 + + +---------------------------------------------------------------------- +-- CHARACTER TRANSLATION + +// Path where the *.ESC and *.CHS files can be found. +;XLATPATH R:\GOLDED\XLAT\ + +// Definition of escape sequence translation files. +;XLATESCSET COMPOSED IBMPC CMP_IBM.ESC +;XLATESCSET I51 IBMPC I51_IBM.ESC +;XLATESCSET MNEMONIC IBMPC MNE_IBM.ESC +;XLATESCSET MNEMONIC CP850 MNE_850.ESC + +// Import charsets (8-bit to 8-bit) +;XLATCHARSET IBMPC IBMPC IBM_IBM.CHS +;XLATCHARSET LATIN-1 IBMPC ISO_IBM.CHS +;XLATCHARSET LATIN1QP IBMPC IQP_IBM.CHS +;XLATCHARSET MAC IBMPC MAC_IBM.CHS +;XLATCHARSET I51 IBMPC ISO_IBM.CHS +;XLATCHARSET 8859 IBMPC ISO_IBM.CHS +;XLATCHARSET CP850 CP850 IBM_850.CHS +;XLATCHARSET LATIN-1 CP850 ISO_850.CHS +;XLATCHARSET LATIN1QP CP850 IQP_850.CHS +;XLATCHARSET MAC CP850 MAC_850.CHS + +// Import charsets (7-bit to 8-bit) +;XLATCHARSET CANADIAN IBMPC CAN_IBM.CHS +;XLATCHARSET DUTCH IBMPC DUT_IBM.CHS +;XLATCHARSET FINNISH IBMPC FIN_IBM.CHS +;XLATCHARSET FRENCH IBMPC FRN_IBM.CHS +;XLATCHARSET GERMAN IBMPC GRM_IBM.CHS +;XLATCHARSET ISO-11 IBMPC SWE_IBM.CHS +;XLATCHARSET ISO-15 IBMPC ITL_IBM.CHS +;XLATCHARSET ISO-17 IBMPC SPN_IBM.CHS +;XLATCHARSET ISO-21 IBMPC GRM_IBM.CHS +;XLATCHARSET ISO-4 IBMPC UK__IBM.CHS +;XLATCHARSET ISO-60 IBMPC NOR_IBM.CHS +;XLATCHARSET ISO-69 IBMPC FRN_IBM.CHS +;XLATCHARSET ITALIAN IBMPC ITL_IBM.CHS +;XLATCHARSET NORWEG IBMPC NOR_IBM.CHS +;XLATCHARSET PORTU IBMPC PRT_IBM.CHS +;XLATCHARSET SPANISH IBMPC SPN_IBM.CHS +;XLATCHARSET SWEDISH IBMPC SWE_IBM.CHS +;XLATCHARSET SWISS IBMPC SWI_IBM.CHS +;XLATCHARSET UK IBMPC UK__IBM.CHS + +// Import charsets (7-bit to 7-bit) +;XLATCHARSET CANADIAN ASCII CAN_ASC.CHS +;XLATCHARSET DUTCH ASCII DUT_ASC.CHS +;XLATCHARSET FINNISH ASCII FIN_ASC.CHS +;XLATCHARSET FRENCH ASCII FRN_ASC.CHS +;XLATCHARSET GERMAN ASCII GER_ASC.CHS +;XLATCHARSET IBMPC ASCII IBM_ASC.CHS +;XLATCHARSET LATIN-1 ASCII ISO_ASC.CHS +;XLATCHARSET ITALIAN ASCII ITA_ASC.CHS +;XLATCHARSET MAC ASCII MAC_ASC.CHS +;XLATCHARSET NORWEG ASCII NOR_ASC.CHS +;XLATCHARSET PORTU ASCII PRT_ASC.CHS +;XLATCHARSET SPANISH ASCII SPN_ASC.CHS +;XLATCHARSET SWEDISH ASCII SWE_ASC.CHS +;XLATCHARSET SWISS ASCII SWI_ASC.CHS +;XLATCHARSET UK ASCII UK__ASC.CHS + +// Export charsets (8-bit to 8-bit) +;XLATCHARSET IBMPC LATIN-1 IBM_ISO.CHS +;XLATCHARSET IBMPC LATIN1QP IBM_IQP.CHS +;XLATCHARSET IBMPC MAC IBM_MAC.CHS +;XLATCHARSET IBMPC I51 IBM_I51.CHS +;XLATCHARSET CP850 LATIN-1 850_ISO.CHS +;XLATCHARSET CP850 LATIN1QP 850_IQP.CHS + +// Export charsets (8-bit to 7-bit or escaped 8-bit) +;XLATCHARSET IBMPC ASCII IBM_ASC.CHS +;XLATCHARSET IBMPC MNEMONIC IBM_MNE.CHS +;XLATCHARSET IBMPC COMPOSED IBM_CMP.CHS +;XLATCHARSET IBMPC VT100 IBM_VT1.CHS +;XLATCHARSET CP850 ASCII 850_ASC.CHS +;XLATCHARSET CP850 MNEMONIC 850_MNE.CHS + +// The character set that incoming messages are assumed to have. +;XLATIMPORT IBMPC ; Default +;XLATIMPORT LATIN-1 + +// Default character set for messages that you write. +// If you uncomment the IBMPC line, your messages will have the kludge +// "^aCHRS: IBMPC 2". +;XLATEXPORT IBMPC +;XLATEXPORT LATIN-1 + +// The actual physical character set. +// WARNING: You should only change this from IBMPC if you have a +// complete set of .CHS and .ESC files that translate to and from your +// physical character set. In other words, if you are using codepage +// 850 and want 100% correct translation, you must be sure that you +// have 850_ISO.CHS, ISO_850.CHS, etc. etc. +;XLATLOCALSET IBMPC +;XLATLOCALSET CP850 + + +---------------------------------------------------------------------- +-- MESSAGE ATTRIBUTE DEFAULTS + +// Attributes to set on messages in netmail areas. +ATTRIBSNET LOC PVT + +// Attributes to set on messages in echomail areas. +ATTRIBSECHO LOC + +// Attributes to set on messages in local areas. +ATTRIBSLOCAL LOC + + +---------------------------------------------------------------------- +-- AdeptXBBS MSGBASE FORMAT SETUP + +// Path where you keep your AdeptXBBS +ADEPTXBBSPATH R:\ADEPT\ + +// Set lastread index position for multiuser setups. +;ADEPTXBBSUSERNO -1 ; Find your lastread index automatically. +;ADEPTXBBSUSERNO 0 ; Set your lastread to index position 0. +;ADEPTXBBSUSERNO 1 ; Set your lastread to index position 1. +;ADEPTXBBSUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- EZYCOM MSGBASE FORMAT SETUP + +// Path where the Ezycom msgbase and userbase can be found. +EZYCOMMSGBASE R:\EZY\MSGBASE\ +EZYCOMUSERBASE R:\EZY\USERBASE\ + +// Set lastread index position for multiuser setups. +;EZYCOMUSERNO -1 ; Find your lastread index in the USERS.BBS file. +;EZYCOMUSERNO 0 ; Set your lastread to index position 0. +;EZYCOMUSERNO 1 ; Set your lastread to index position 1. +;EZYCOMUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- FIDO (OPUS/FTS1) *.MSG MSGBASE FORMAT SETUP + +// What to do about "highwatermarks". +;FIDOHWMARKS YES ; Use them to determine sent/unsent status. +FIDOHWMARKS NO ; Ignore them. + +// Set the name of the lastread file. +;FIDOLASTREAD LASTREAD + +// Select format of *.MSG format message headers. +// NOTE: If you select FTS1, be sure that ALL your other software +// supports it. Otherwise you might see strange zone and point numbers +// on addresses in some messages. +;FIDOMSGTYPE FTS1 ; Use FTS-1 format (zone/point fields). +FIDOMSGTYPE OPUS ; Use Opus format (date/timestamp fields). + +// Replace NUL characters in the msgbody with LF characters. +// Only necessary when using badly buggy programs that break FTS-1 by +// putting NUL characters in the msgbody. +;FIDONULLFIX YES + +// Set lastread index position for multiuser setups. +// Each lastread index occupies 2 bytes in the LASTREAD file. +;FIDOUSERNO -1 ; Find your lastread index in the USER.BBS file. +;FIDOUSERNO 0 ; Set your lastread to index position 0. +;FIDOUSERNO 1 ; Set your lastread to index position 1. +;FIDOUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- GOLDBASE MSGBASE FORMAT SETUP + +// Path to the MSG*.DAT, LASTREAD.DAT and USERS.DAT files. +GOLDBASEPATH M:\GOLDBASE\ + +// Path to the NETMAIL.DAT and ECHOMAIL.DAT files. +GOLDBASESYSPATH M:\GOLDBASE\ + +// Set lastread index position for multiuser setups. +;GOLDBASEUSERNO -1 ; Find your lastread index in the USERS.DAT file. +;GOLDBASEUSERNO 0 ; Set your lastread to index position 0. +;GOLDBASEUSERNO 1 ; Set your lastread to index position 1. +;GOLDBASEUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- HUDSON MSGBASE FORMAT SETUP + +// Path to the MSG*.BBS, LASTREAD.BBS and USERS.BBS files. +HUDSONPATH M:\HUDSON\ + +// Path to the NETMAIL.BBS and ECHOMAIL.BBS files. +HUDSONSYSPATH M:\HUDSON\ + +// The size, in bytes, when GoldED will start warning about the size +// of the MSGTXT.BBS file. The absolute size limit on that file is +// 16777215 bytes. If exceeded, msgbase corruption is likely. +HUDSONSIZEWARN 16000000 + +// Set lastread index position for multiuser setups. +;HUDSONUSERNO -1 ; Find your lastread index in the USERS.BBS file. +;HUDSONUSERNO 0 ; Set your lastread to index position 0. +;HUDSONUSERNO 1 ; Set your lastread to index position 1. +;HUDSONUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- JAM MSGBASE FORMAT SETUP + +// Directory where NETMAIL.JAM and ECHOMAIL.JAM can be found. +JAMPATH M:\HUDSON\ + +// How to delete messages in JAM areas. +JAMHARDDELETE YES ; Delete them so that they don't show up again. +;JAMHARDDELETE NO ; Delete them so that they can be recovered. + + +---------------------------------------------------------------------- +-- PCBOARD MSGBASE FORMAT SETUP + +// Path where the PCBOARD.DAT file can be found. +PCBOARDPATH R:\PCBOARD\ + +// Set lastread index position for multiuser setups. +;PCBOARDUSERNO -1 ; Find your lastread index in the userbase files. +;PCBOARDUSERNO 0 ; Set your lastread to index position 0. +;PCBOARDUSERNO 1 ; Set your lastread to index position 1. +;PCBOARDUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- SQUISH MSGBASE FORMAT SETUP + +// Enable conversion of the DIR attribute to CRA+HLD. +// This should only be used with SquishMail in conjunction with +// Binkley or compatible mailers. +;SQUISHDIRECT YES + +// Select scanning method. The Quick method is usually reliable. +// GoldED does NOT use the Squish MSGAPI in any case. +SQUISHSCAN QUICK ; Scan only based on the *.SQI file. +;SQUISHSCAN API ; Check the *.SQD file for exact data. Slower. + +// Set lastread index position for multiuser setups. +;SQUISHUSERNO -1 ; Find your lastread index in the USER.BBS file. +;SQUISHUSERNO 0 ; Set your lastread to index position 0. +;SQUISHUSERNO 1 ; Set your lastread to index position 1. +;SQUISHUSERNO X ; Set your lastread to index position X. + +// Path where a Maximus/Opus format USER.BBS can be found. +SQUISHUSERPATH R:\MAX\ + + +---------------------------------------------------------------------- +-- WILDCAT! 4.x MSGBASE FORMAT SETUP + +// Set lastread index position for multiuser setups. +;WILDCATUSERNO -1 ; Find your lastread index in the *.LRD file. +;WILDCATUSERNO 0 ; Set your lastread to index position 0. +;WILDCATUSERNO 1 ; Set your lastread to index position 1. +;WILDCATUSERNO X ; Set your lastread to index position X. + + +---------------------------------------------------------------------- +-- SEMAPHORE FILES When no path is given, the AREAPATH is assumed. + +// FrontDoor semaphore for rescanning the netmail area. +SEMAPHORE NETSCAN R:\FD\FDRESCAN.NOW + +// These files are for D'Bridge setups. +;SEMAPHORE NETSCAN DBRIDGE.RSN +;SEMAPHORE ECHOSCAN DBRIDGE.RSE +;SEMAPHORE EXPORTLIST ECHOMAIL.CTL + +// Name of file with areas to be scanned out by the mail processor. +// GoldED updates this file when you write messages. +;SEMAPHORE EXPORTLIST R:\MAX\ECHOSCAN.LOG + +// Mark areas in the arealist if they are listed in an IMPORTLIST. +;SEMAPHORE IMPORTLIST ECHOTOSS.LOG +;SEMAPHORE IMPORTLIST IMPORTED.ARE +;SEMAPHORE IMPORTLIST CONFMAIL.OUT +;SEMAPHORE IMPORTLIST IMPORT.XYZ + +// Check the following semaphores for existence if GoldED is idle in +// the arealist screen and do certain actions. If no path is given, +// GOLDPATH is assumed. +;SEMAPHORE SCANALL RESCAN.GED ; Scan all areas +;SEMAPHORE SCANTHIS ; Scan the areas listed in the file +;SEMAPHORE PMSCANALL ; PM-scan all areas +;SEMAPHORE PMSCANTHIS ; PM-scan the areas listed in file +;SEMAPHORE SCANNETMAIL ; Scan all netmail areas. +;SEMAPHORE PMSCANNETMAIL ; PM-scan all netmail areas. +;SEMAPHORE QWKIMPORT ; Import QWK packets +;SEMAPHORE QWKEXPORT ; Export to QWK +;SEMAPHORE SOUPIMPORT ; Import SOUP packets +;SEMAPHORE SOUPEXPORT ; Export to SOUP +;SEMAPHORE EXITNOW ; Exit GoldED immediately. +// The following keyword defines the delay between the semaphore +// checks. If you set this value to zero, the feature is disabled. +;SEMAPHORE IDLETIME 30 ; Scan every 30 seconds for sema's. +SEMAPHORE IDLETIME 0 ; Disable semaphore checking. + +---------------------------------------------------------------------- +-- AREA RENAME AND EX/INCLUSION + +// How to create automatic echoids. +AREAAUTOID VERBOSE ; Make understandable echoids. +;AREAAUTOID LONG ; Sequential long echoids (NETMAILxxx etc.). +;AREAAUTOID SHORT ; Sequential short echoids (NETxxx etc.). + +// Rename areas that are given automatic echoids in AREAFILE's. +;AREARENAME NET001 NETMAIL +;AREARENAME ECHO001 BAD_MSGS + +// Exclude areas from the arealist. (Wildcards allowed). +AREAEXCL ALT.FAN.* + +// Include areas even if excluded with AREAEXCL. (Wildcards allowed). +AREAINCL ALT.FAN.SCHWARZENEGGER + + +---------------------------------------------------------------------- +-- AREA SCANNING OPTIONS + +// Scan these areas at startup. (Wildcards allowed). +AREASCAN * + +// Do not scan these areas at startup. (Wildcards allowed). +;AREASCANEXCL C_ECHO +;AREASCANEXCL ALT.* +;AREASCANEXCL REC.* + +// Scan these area even if listed with AREASCANEXCL. (Wildcards allowed). +;AREASCANINCL ALT.TASTELESS* +;AREASCANINCL REC.HUMOR* + +// Scan these areas for personal mail. (Wildcards allowed). +;AREAPMSCAN * + +// Do not scan these areas for personal mail. (Wildcards allowed). +;AREAPMSCANEXCL NET_* + +// Scan these areas even if listed with AREAPMSCANEXCL. (Wildcards allowed). +;AREAPMSCANINCL NETMAIL + +// Sort areas before scanning. The default is optimized for speed. +;AREASCANSORT XZBE + +// Start in a specific area, bypassing the arealist. +;AREASTART NETMAIL + + +---------------------------------------------------------------------- +-- AREALIST OPTIONS + +// Automatically jump to the next marked area? +AREAAUTONEXT YES + +// Also set msgs to read if catching-up an area? +// (Needs HIGHLIGHTUNREAD YES) +;AREACATCHUPREAD NO ; No, leave them unread +AREACATCHUPREAD YES ; Yes, reset the unread attribute. + +// Display the real board numbers instead of sequential area numbers? +;AREALISTNOS YES + +// Sort all areas in the area list. See the manual for sort options. +AREALISTSORT PFYTUE + +// Content of the next-to-last column in the arealist. +AREALISTTYPE New ; The number of messages after the lastread. +;AREALISTTYPE Last ; The number of the lastread message. + +// Set the width of the "EchoID" column in the arealist. +AREALISTECHOMAX 16 ; Show up to 16 characters of the echoid. +;AREALISTECHOMAX 0 ; Width of the longest echoid. +;AREALISTECHOMAX -5 ; Width of the longest echoid minus 5 chars. + +// Show a column for groupid letters or numbers on the right side? +AREALISTGROUPID YES + +// Add these menu items to the area scan menu. +// The .LST file must contain lines with the echoids (wildcards +// allowed) of the areas you want scanned. +// The optional parameter "-Delete" tells GoldED to delete the file +// after scanning. +;AREALISTSCAN "e Scan Netmail" NETMAIL.LST +;AREALISTSCAN "g Scan Newsgroups" NEWSGRPS.LST +;AREALISTSCAN "o Scan GoldED" GOLDECHO.LST +;AREALISTSCAN " Scan new mails" IMPORT.LST -Delete + +// Store arealist data between sessions? +AREAKEEPLAST YES + +// Enable a pagebar (scrollbar) for the arealist. +AREALISTPAGEBAR YES + +// What to do when trying to enter a message in a Read-Only area. +;AREAREADONLY HARD ; Don't allow it. +AREAREADONLY SOFT ; Pop up a menu and ask for permission. + +// Change the order of "type" sorting when using AREALISTSORT. +;AREATYPEORDER Net Local Echo News Email ; put inet areas at the end +AREATYPEORDER Net Email Echo News Local ; default sorting + +// Declare separation lines. This works well if T or G is one of +// your primary AREALISTSORT options. Note: The separators are +// implemented as "special" areas, so they behave more or less like +// normal areas, that means that they're also sorted by AREALISTSORT. + +// echoid description +;AREASEP !NET "Netmail areas" 0 Net +;AREASEP !EMAIL "E-Mail areas" 0 EMail +;AREASEP !ECHO "Echomail areas" 0 Echo +;AREASEP !NEWS "Newsgroup areas" 0 News +;AREASEP !LOCAL "Local areas" 0 Local + + +// Note: If "T" is one of the primary sortings (i.e. prior to "G"), +// AREASEP X "desc" 0 Net +// means that this Area-Separator is sorted in front of the first +// Netmail area, regardless which group it has. + +// Otherwise, if "G" is one of the primary sortings (prior to "T"), +// AREASEP Y "desc 2" 0 Echo +// means that this Area-Separator is sorted in front of the first area +// without group (Groupid = '0'). If "T" is one of the secondary +// sorting types, the Area-Separator is sorted in front of the first +// area with group = 0 and Type = Echo. If there's an area with +// group=0 and type=Net, the Area-Separator is sorted below that area, +// i.e.: +// AREADEF NETMAIL "..." 0 Net [...] +// AREASEP Y "..." 0 Echo +// AREADEF ECHO1 "..." 0 Echo [...] +// Most users have problems with understanding this very powerful +// feature at first, so if you have problems with it, consult one of +// the support echos. + +// Configure the arealist column layout. Please read the manual for +// more details. +;AREALISTFORMAT "AM D C4PU4N E G " ; layout "good old days" +;AREALISTFORMAT "AM E CPUN G" ; layout without descs +;AREALISTFORMAT "ME D CPUN G" ; alternative layout +;AREALISTFORMAT "AM D CPUN E G " ; layout + +---------------------------------------------------------------------- +-- DRIVE REMAPPING + +// Network drive mapping (ServerDrive -> WorkstationDrive). +// NOTE: This is MAINLY used to map drives in AREAFILE's. +// It won't remap paths given anywhere in GOLDED.CFG. +;MAPPATH C: X: +;MAPPATH D: Y: +;MAPPATH E: Z: +;IF UNIX +; MAPPATH C:\ /mnt/dos/c/ ; For GoldED/LNX reading AREAFILE's. +;ENDIF + + +---------------------------------------------------------------------- +-- EXTERNAL AREA FILE SETUP + +// Default path for AREAFILE's and semaphores. +AREAPATH R:\FD\ + +// GoldED can get area setup from many other programs. +// Uncomment and edit one of these for a quick and simple area setup. +;AREAFILE AdeptXBBS R:\ADEPT\ +;AREAFILE AreasBBS M:\HUDSON\AREAS.BBS +;AREAFILE DBridge R:\DB\ +;AREAFILE Dutchie R:\DUTCHIE\ +;AREAFILE Ezycom R:\EZY\ +;AREAFILE FastEcho R:\FASTECHO\ +;AREAFILE FidoPCB R:\FIDOPCB\ +;AREAFILE FMail R:\FMAIL\ +;AREAFILE FrontDoor R:\FD\ M:\HUDSON\AREAS.BBS +;AREAFILE GEcho R:\GECHO\ +;AREAFILE IMAIL R:\IMAIL\ +;AREAFILE InterMail R:\IM\ +;AREAFILE LoraBBS R:\LORA\ +;AREAFILE Maximus R:\MAX\ +;AREAFILE ME2 R:\ME2\AREADESC.ME2 R:\ME2\AREAS.BBS +;AREAFILE Opus R:\OPUS\ +;AREAFILE PCBoard R:\PCB\ +;AREAFILE Partoss R:\PARTOSS\ +;AREAFILE Portal R:\PORTAL\ +;AREAFILE ProBoard R:\PB\ +;AREAFILE QFront R:\QFRONT\ +;AREAFILE QuickBBS R:\QBBS\ R:\QBBS\AREAS.BBS +;AREAFILE RaEcho R:\RAECHO\ +;AREAFILE RemoteAccess R:\RA\ R:\RA\AREAS.BBS +;AREAFILE Squish R:\MAX\ +;AREAFILE SuperBBS R:\SUPER\ R:\SUPER\AREAS.BBS +;AREAFILE timEd R:\TIMED\ +;AREAFILE Termail R:\TERMINAT\TM\ +;AREAFILE TosScan R:\TS\ +;AREAFILE WaterGate R:\WG\ +;AREAFILE WMail R:\WMAIL\ +;AREAFILE xMail R:\XMAIL\ + +// Force format of the Hudson USERS.BBS file. +// Overrides AREAFILE RemoteAccess if used. +;RA2USERSBBS YES ; Use RemoteAccess 2.xx format. +;RA2USERSBBS NO ; Use original Hudson format. + + +---------------------------------------------------------------------- +-- AREA DESCRIPTIONS Add descriptions to areas that don't have any. + +// Get descriptions from an echolist. +;AREAFILE EchoList R:\INFO\UPLINK.LST + +// Manually define descriptions. See also the manual for more details. +;AREADESC C_ECHO "International C discussion" +;AREADESC NET_DEV "FidoNet Developers" + + +---------------------------------------------------------------------- +-- MANUAL AREA DEFINITIONS + +// Area definitions using the AREADEF keyword. +;Syntax: Echoid "Description" Groupid Type Format Path or board Aka (Attributes) "Origin" +;AREADEF NETMAIL "Netmails" 0 Net Opus M:\MSG\NETMAIL\ . (Loc Pvt) +;AREADEF NET_DEV "FidoNet Developers" I Echo JAM M:\JAM\INT\NET_DEV . (Loc) "If you love MSGID, set it free!" +;AREADEF C_ECHO "Int. C Discussion" I Echo Hudson 117 . (Loc) "C-king forever" +;AREADEF USR2USR "Online Users" B Local Squish M:\SQUISH\USR2USR . (Loc) "The Goldware BBS" +;AREADEF EZY_TEST "Testing Ezycom" E Echo Ezycom 711 . (Loc) "Ezycom Test Area" +;AREADEF TWILIGHT "Twilight Zone" Z Echo PCBoard R:\PCB\MAIN\TWZN7 7:77/777.7777 (Loc) + +// Area definitions using the AREA keyword. (Old format). +;Syn: Echoid "Description" FmtTyp Path or board Akano Attributes +;AREA NETMAIL "Netmails" ON M:\MSG\NETMAIL\ 0 Loc Pvt +;AREA NET_DEV "FidoNet Developers" JE M:\JAM\INT\NET_DEV 0 Loc +;AREA C_ECHO "Int. C Discussion" HE 117 0 Loc +;AREA USR2USR "Online Users" ML M:\SQUISH\USR2USR 0 Loc +;AREA EZY_TEST "Testing Ezycom" EE 711 0 Loc +;AREA TWILIGHT "Twilight Zone" PE R:\PCB\MAIN\TWZN7 7 Loc + + +---------------------------------------------------------------------- +-- RANDOM SYSTEM GROUPS + +// Allow use of group letters from AREAFILE's as group names? +AREAFILEGROUPS YES + +// A group specifically for the echo named NET_DEV. +;GROUP NET_DEV +; MSGLISTHEADER YES +; LOADLANGUAGE GEDLNGUS.CFG +; OUTPUTFILE NET_DEV.TXT +; VIEWHIDDEN YES +; VIEWKLUDGE YES +; WHOTO All +; XLATEXPORT LATIN-1 +;ENDGROUP + +// A group for some test echoes. +;GROUP Test: +; MEMBER *TEST* +; ORIGIN "Testing my day away" +;ENDGROUP + +// A group for Internet e-mail. +;GROUP E-Mail: +; MEMBER NET_EMAIL* +; ATTRIBUTES CRA PVT +; EDITHARDTERM YES +; LOADLANGUAGE GEDLNGUS.CFG +; TEMPLATE EMAIL.TPL +; USERNAME odinn@winboss.dk +; XLATIMPORT LATIN-1 +; XLATEXPORT LATIN-1 +;ENDGROUP + +// A group for Internet newsgroups. +;GROUP Newsgroups: +; MEMBER ALT.*, COMP.*, MISC.*, NEWS.* +; MEMBER REC.*, SOC.*, SCI.*, TALK.* +; MEMBER PINGNET.* +; EDITHARDTERM YES +; LOADLANGUAGE GEDLNGUS.CFG +; MSGLISTWIDESUBJ YES +; QUOTECHARS "|:;" +; USERNAME odinn@winboss.dk +; TEMPLATE NEWSGRPS.TPL +; XLATIMPORT LATIN-1 +; XLATEXPORT LATIN-1 +;ENDGROUP + +// A group for Danish (FidoNet Region 23) echoes. +;GROUP Danish: +; MEMBER *_R23.*, *.23? +; LOADLANGUAGE GEDLNGDK.CFG +; TEMPLATE DANSK.TPL +; WHOTO Alle +;ENDGROUP + +// A group for some international FidoNet echoes. +;GROUP FidoNet: +; MEMBER GOLDED*, INTERCOOK, MUSIC, 4DOS, ENET.SOFT, +; MEMBER ENET.SYSOP, FDECHO, RA_UTIL, REGCON.EUR, OS2* +; LOADLANGUAGE GEDLNGUS.CFG +; WHOTO All +;ENDGROUP + +// A group for some QWK areas. +;GROUP My-QWKs: +; MEMBER XYZ.USERS +; CTRLINFO NO ; Don't use tearline/origin in QWK +; WHOTO All +;ENDGROUP + +// A group for areas with groupid letter 'X'. +;GROUP X +; ORIGIN "This is an origin for groupid X" +;ENDGROUP + +// A group for areas with groupid number 117. +;GROUP #117 +; ORIGIN "This is an origin for groupid 117" +;ENDGROUP + +// A catch-all group for any area not matching the above. +;GROUP * +; ORIGIN "Yet another forgotten area!" +;ENDGROUP + + +---------------------------------------------------------------------- + diff --git a/cfgs/config/gedlngdk.cfg b/cfgs/config/gedlngdk.cfg new file mode 100644 index 0000000..15a0ab4 --- /dev/null +++ b/cfgs/config/gedlngdk.cfg @@ -0,0 +1,59 @@ +---------------------------------------------------------------------- +-- GoldED 2.50 * Partial Language File, Danish Version. + +WT_MSG "Brev" +WT_MSGREAL "Brev#" + +HD_From " Fra : " +HD_To " Til : " +HD_Subj " Emne : " +HD_File " Fil : " + +MS_DateTimeFmt "%a %d %b %y %H:%M" +MS_DateFmt "%A %d. %B %Y" +MS_TimeFmt "%H:%M" + +MS_SWSun "S›n" +MS_SWMon "Man" +MS_SWTue "Tir" +MS_SWWed "Ons" +MS_SWThu "Tor" +MS_SWFri "Fre" +MS_SWSat "L›r" + +MS_LWSunday "S›ndag" +MS_LWMonday "Mandag" +MS_LWTuesday "Tirsdag" +MS_LWWednesday "Onsdag" +MS_LWThursday "Torsdag" +MS_LWFriday "Fredag" +MS_LWSaturday "L›rdag" + +MS_SMJan "Jan" +MS_SMFeb "Feb" +MS_SMMar "Mar" +MS_SMApr "Apr" +MS_SMMay "Maj" +MS_SMJun "Jun" +MS_SMJul "Jul" +MS_SMAug "Aug" +MS_SMSep "Sep" +MS_SMOct "Okt" +MS_SMNov "Nov" +MS_SMDec "Dec" + +MS_LMJanuary "Januar" +MS_LMFebruary "Februar" +MS_LMMarch "Marts" +MS_LMApril "April" +MS_LMMay "Maj" +MS_LMJune "Juni" +MS_LMJuly "Juli" +MS_LMAugust "August" +MS_LMSeptember "September" +MS_LMOctober "Oktober" +MS_LMNovember "November" +MS_LMDecember "December" + +---------------------------------------------------------------------- + diff --git a/cfgs/config/gedlngit.cfg b/cfgs/config/gedlngit.cfg new file mode 100644 index 0000000..a1e837e --- /dev/null +++ b/cfgs/config/gedlngit.cfg @@ -0,0 +1,63 @@ +---------------------------------------------------------------------- +-- GoldED 3.00 * Partial Language File, Italian Version. + +WT_MSG "Msg" +WT_MSGREAL "Msg#" + +HD_FROM " From : " +HD_TO " To : " +HD_SUBJ " Subj : " +HD_FILE " File : " + +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" + +// Giorni della settimana, forma breve +MS_SWSUN "Dom" +MS_SWMON "Lun" +MS_SWTUE "Mar" +MS_SWWED "Mer" +MS_SWTHU "Gio" +MS_SWFRI "Ven" +MS_SWSAT "Sab" + +// Giorni della settimana, forma lunga +MS_LWSUNDAY "Domenica" +MS_LWMONDAY "Lunedi" +MS_LWTUESDAY "Martedi" +MS_LWWEDNESDAY "Mercoledi" +MS_LWTHURSDAY "Giovedi" +MS_LWFRIDAY "Venerdi" +MS_LWSATURDAY "Sabato" + +// Mesi, forma breve +MS_SMJAN "Gen" +MS_SMFEB "Feb" +MS_SMMAR "Mar" +MS_SMAPR "Apr" +MS_SMMAY "Mag" +MS_SMJUN "Giu" +MS_SMJUL "Lug" +MS_SMAUG "Ago" +MS_SMSEP "Set" +MS_SMOCT "Ott" +MS_SMNOV "Nov" +MS_SMDEC "Dic" + +// Mesi, forma lunga +MS_LMJANUARY "Gennaio" +MS_LMFEBRUARY "Febbraio" +MS_LMMARCH "Marzo" +MS_LMAPRIL "Aprile" +MS_LMMAY "Maggio" +MS_LMJUNE "Giugno" +MS_LMJULY "Luglio" +MS_LMAUGUST "Agosto" +MS_LMSEPTEMBER "Settembre" +MS_LMOCTOBER "Ottobre" +MS_LMNOVEMBER "Novembre" +MS_LMDECEMBER "Dicembre" + + +---------------------------------------------------------------------- diff --git a/cfgs/config/gedlngnl.cfg b/cfgs/config/gedlngnl.cfg new file mode 100644 index 0000000..3221b42 --- /dev/null +++ b/cfgs/config/gedlngnl.cfg @@ -0,0 +1,63 @@ +---------------------------------------------------------------------- +-- GoldED 3.00 * Partial Language File, Dutch Version. + +WT_MSG "Bericht" +WT_MSGREAL "Bericht#" + +HD_FROM " Van : " +HD_TO " Aan : " +HD_SUBJ " Ondw : " +HD_FILE " Bstd : " + +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" + +// Weekdays, short +MS_SWSUN "Zon" +MS_SWMON "Maa" +MS_SWTUE "Din" +MS_SWWED "Woe" +MS_SWTHU "Don" +MS_SWFRI "Vrij" +MS_SWSAT "Zat" + +// Weekdays, long +MS_LWSUNDAY "Zondag" +MS_LWMONDAY "Maandag" +MS_LWTUESDAY "Dinsdag" +MS_LWWEDNESDAY "Woensdag" +MS_LWTHURSDAY "Donderdag" +MS_LWFRIDAY "Vrijdag" +MS_LWSATURDAY "Zaterdag" + +// Months, short +MS_SMJAN "Jan" +MS_SMFEB "Feb" +MS_SMMAR "Maa" +MS_SMAPR "Apr" +MS_SMMAY "Mei" +MS_SMJUN "Jun" +MS_SMJUL "Jul" +MS_SMAUG "Aug" +MS_SMSEP "Sep" +MS_SMOCT "Okt" +MS_SMNOV "Nov" +MS_SMDEC "Dec" + +// Months, long +MS_LMJANUARY "Januari" +MS_LMFEBRUARY "Februari" +MS_LMMARCH "Maart" +MS_LMAPRIL "April" +MS_LMMAY "Mei" +MS_LMJUNE "Juni" +MS_LMJULY "Juli" +MS_LMAUGUST "Augustus" +MS_LMSEPTEMBER "September" +MS_LMOCTOBER "Oktober" +MS_LMNOVEMBER "November" +MS_LMDECEMBER "December" + +---------------------------------------------------------------------- + diff --git a/cfgs/config/gedlngus.cfg b/cfgs/config/gedlngus.cfg new file mode 100644 index 0000000..261db5c --- /dev/null +++ b/cfgs/config/gedlngus.cfg @@ -0,0 +1,59 @@ +---------------------------------------------------------------------- +-- GoldED 2.50 * Partial Language File, English Version. + +WT_MSG "Msg" +WT_MSGREAL "Msg#" + +HD_From " From : " +HD_To " To : " +HD_Subj " Subj : " +HD_File " File : " + +MS_DateTimeFmt "%a %d %b %y %H:%M" +MS_DateFmt "%A %B %d %Y" +MS_TimeFmt "%H:%M" + +MS_SWSun "Sun" +MS_SWMon "Mon" +MS_SWTue "Tue" +MS_SWWed "Wed" +MS_SWThu "Thu" +MS_SWFri "Fri" +MS_SWSat "Sat" + +MS_LWSunday "Sunday" +MS_LWMonday "Monday" +MS_LWTuesday "Tuesday" +MS_LWWednesday "Wednesday" +MS_LWThursday "Thursday" +MS_LWFriday "Friday" +MS_LWSaturday "Saturday" + +MS_SMJan "Jan" +MS_SMFeb "Feb" +MS_SMMar "Mar" +MS_SMApr "Apr" +MS_SMMay "May" +MS_SMJun "Jun" +MS_SMJul "Jul" +MS_SMAug "Aug" +MS_SMSep "Sep" +MS_SMOct "Oct" +MS_SMNov "Nov" +MS_SMDec "Dec" + +MS_LMJanuary "January" +MS_LMFebruary "February" +MS_LMMarch "March" +MS_LMApril "April" +MS_LMMay "May" +MS_LMJune "June" +MS_LMJuly "July" +MS_LMAugust "August" +MS_LMSeptember "September" +MS_LMOctober "October" +MS_LMNovember "November" +MS_LMDecember "December" + +---------------------------------------------------------------------- + diff --git a/cfgs/config/goldhelp.cfg b/cfgs/config/goldhelp.cfg new file mode 100644 index 0000000..68ba2e6 --- /dev/null +++ b/cfgs/config/goldhelp.cfg @@ -0,0 +1,714 @@ +-------------------------------------------------------------------------------- + GoldED Help System Definition File +-------------------------------------------------------------------------------- + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ 1234567890123456789012345678901234567890123456789012345678901234567890123456 ³ +³ 2 ³ +³ 3 ³ +³ 4 ³ +³ 5 ³ +³ 6 ³ +³ 7 ³ +³ 8 ³ +³ 9 ³ +³ 10 ³ +³ 11 This is a model of the help screen as it will look in GoldED. ³ +³ 12 ³ +³ 13 ³ +³ 14 ³ +³ 15 ³ +³ 16 ³ +³ 17 ³ +³ 18 ³ +³ 19 ³ +³ 20 ³ +³ 21 ³ +³ 22 - This line cannot be used. If used, the window will scroll one line. ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + +Here is a small "ruler" for the actual definitions below: + +³123456789012345678901234567890123456789012345678901234567890123456789012345678³ +ÃÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ´ + + +-------------------------------------------------------------------------------- + +*B 1000,General + Help Menu. +*E + +-------------------------------------------------------------------------------- + +*B 1001,Drop Message + + You are about to loose the message you have just written or changed. + + Are you quite sure you want to do that? +*E + +-------------------------------------------------------------------------------- + +*B 1002,Quit GoldED + + You can now exit GoldED or stay in. + + A quicker way of exiting is by using , which exits + immediately. +*E + +-------------------------------------------------------------------------------- + +*B 1003,File Exists + + The file you want to export to already exists. You can append to the end of + the existing file or overwrite it. + +*E + +-------------------------------------------------------------------------------- + +*B 1004,Change Attributes + + Here you can change the attributes of the message. + + NOTE: Some attributes apply only to certain message bases or area types + (NET, ECHO or LOCAL areas). +*E + +-------------------------------------------------------------------------------- + +*B 1005,Change Aka + + Here you can change the default AKA (Also Known As) address for the current + area. + + See also: ^Change Origin^, ^Change Template^, ^Change Username^ +*E + +-------------------------------------------------------------------------------- + +*B 1006,Change Origin + + Here you can change the origin for the current area or message. + + See also: ^Change Aka^, ^Change Template^, ^Change Username^ +*E + +-------------------------------------------------------------------------------- + +*B 1007,Change Template + + Here you can change the template for the current area or message. + + See also: ^Change Aka^, ^Change Origin^, ^Change Username^ +*E + +-------------------------------------------------------------------------------- + +*B 1008,Change Username + + Here you can change the current username. + + See also: ^Change Aka^, ^Change Origin^, ^Change Template^ +*E + +-------------------------------------------------------------------------------- + +*B 2000,Area Keys + + Home Move selection bar to first area + End Move selection bar to last area + Right Move selection bar to next area + Left Move selection bar to previous area + Alt-J Move selection bar to next marked area + + Enter Enter the reader for the selected area + + Alt-T, Ins Toggle mark on selected area. See also ^Area Marking^. + Alt-S Scan areas - all or marked. See also ^Scan areas^. + Alt-A Abort the area selection + Alt-B Toggle sequential area numbering or board numbers + Alt-O Shell to DOS + Alt-X Exit GoldED, prompt for final decision + Ctrl-Q Exit immediately, no questions asked +*E + +-------------------------------------------------------------------------------- + +*B 2001,Area Marking + + In the area list, a small arrow by the area number indicates that the area + is marked. Areas are marked automatically, if the lastread pointer is below + the highest message. + + If you have unscanned areas, you can mark areas for rescan. + + You can toggle an area mark by pressing Insert, and go to the scanning menu + with Alt-S. + + You can jump from mark to mark with Alt-J or use Ctrl-Left,Right to Jump + back and forth. + + See also: ^Area Selection^, ^Scan Areas^ or ^Area Keys^ +*E + +-------------------------------------------------------------------------------- + +*B 2002,Scan Areas + + You can scan all areas, marked areas or current area. + + See also: ^Area Selection^, ^Area Marking^ or ^Area Keys^ +*E + +-------------------------------------------------------------------------------- + +*B 2003,Area Selection + + Select a new area to read or a destination area for moved replies or + copy/move/forward. + + You can select the area by typing a part of the echo name, which will cause + the selection bar to move automatically to the closest match to the name, or + you can use the cursor and page keys to browse around. + + The area is selected by pressing Enter. + + See also: ^Area Keys^, ^Area Marking^, ^Scan Areas^ or ^Reader Keys^ +*E + +-------------------------------------------------------------------------------- + +*B 2004,Heat Areas + + This function sets the "Highwater mark" (1.MSG) in *.MSG areas to point to + the *last* message in the area. The effect is that no msgs will be scanned + out from the area. + + You can "heat" all areas, marked areas or the current area. + + See also: ^Area Selection^, ^Area Marking^ or ^Area Keys^ +*E + +-------------------------------------------------------------------------------- + +*B 2005,Zap Areas + + This function sets the "Highwater mark" (1.MSG) in *.MSG areas to point to + the *first* message in the area. The effect is that all msgs in the area + will be scanned out again. + + You can "zap" all areas, marked areas or current area. + + See also: ^Area Selection^, ^Area Marking^ or ^Area Keys^ +*E + +-------------------------------------------------------------------------------- + +*B 3000,Reader Keys + + Esc, Alt-A Enter the area selection screen + Ins, Alt-E Enter a new message + Del, Alt-D Delete current/marked message(s), ask first + Right Next message + Left Previous message + Enter Page down or go to next message + End Display last part of current message + Home Display first part of current message + Down Scroll message display + Up Scroll message display + PgDn Display next page of message + PgUp Display previous page of message + Tab Toggle a BookMark on the current message + Sh-Tab, BckSp Go to the BookMarked message + Ctrl-Left, - Previous message in the replylink + Ctrl-Home, < First message in the area + Ctrl-End, > Last message in the area + Ctrl-G, num Go to a specific message number + Ctrl-N Go directly to the next area + Ctrl-P Go directly to the previous area +*P + + Ctrl-Right, + Go to the next message in the replylink + Ctrl-F Request files from the current msg + Alt-F, Sh-F6 Find string(s) in message header and text + Z, Alt-Z, F6 Find string(s) in message header + F10 Lookup current FROM node + Shift-F10 Lookup current TO node + Ctrl-A Change AKA for the current area + Ctrl-S Change the attributes of the current message + Alt-C, Sh-F2 Change message + Ctrl-O Change origin for the current area + Ctrl-T Change template + Ctrl-I Change tagline + Ctrl-U Change username + Q, Alt-Q, F4 Quote-Reply to message. (Reply to FROM name) + G, Alt-G Comment-Reply to message. (Reply to TO name) + R, Alt-R, F3 Reply to message, without quoting + N, Alt-N, F5 Quote-Reply in another area + B, Alt-B Comment-Reply in another area + L, Alt-L, F9 Enter the message lister. + Alt-M, Sh-F8 Enter the Copy/Move/Forward function menu +*P + + Alt-S, Alt-F9 Enter the marking menu + W, Alt-W, F7 Write/export message(s) to file or printer + Alt-O, Ct-F10 Shell to DOS + Ctrl-R, Sh-F4 Renumber Fido/Opus *.MSG files + Ctrl-L Generate FIDOUSER.LST of all users in area + X, Alt-X Exit GoldED, prompt for final decision + Ctrl-Q Exit GoldED immediately, no questions asked + Alt-I,Ctrl-F9 Toggle hexdump mode. For test/debugging + Alt-V,Ctrl-F5 Toggle display of Hidden and Kludge lines + Alt-H,Ctrl-F7 Toggle display of Hidden lines + Alt-K,Ctrl-F6 Toggle display of Kludge lines + Space Toggle a message mark on the current message + Alt-J,Alt-F10 Toggle "Read Marked" mode + Alt-P,Ctrl-F8 Toggle the "PageBar" feature + Alt-U,Ctrl-F3 Toggle ROT13 crypting for the current message + Alt-Y,Ctrl-F4 Toggle between seq. or real message numbers + T, Alt-T Toggle Twit display - Show/Blank/Skip/Ignore +*E + +-------------------------------------------------------------------------------- + +*B 3001,Change Message + + The message you are about to change, is not written by you, or at least not + with the name you have given in the GoldED configuration file. + + If you decide to change it anyway, the lines defined in the template as + "@changed" will be inserted at the top of the message. +*E + +-------------------------------------------------------------------------------- + +*B 3002,Delete Message + + Are you quite sure you want to delete this/these message(s)? +*E + +-------------------------------------------------------------------------------- + +*B 3003,Marked Messages + + One or more messages are marked. + + You can either perform the function on only the current message or all the + marked messages. +*E + +-------------------------------------------------------------------------------- + +*B 3004,Go To Next Area + + You have reached the last (or first) message in this area. + + You can now proceed to the next area or stay in this one. By pressing + (or ), you also go to the next area. +*E + +-------------------------------------------------------------------------------- + +*B 3005,Copy/Move/Forward + + Copy Copy message(s) to another area + Move Move message(s) to another area + Forward Forward this message. + + Copy and Move never changes the content of the affected message(s). Move + deletes the original message(s), so be careful when using this feature. + + If you select Forward, you are asked for the destination area, and you will + be able to change the header data. A template-defined message is inserted at + the top of the message. +*E + +-------------------------------------------------------------------------------- + +*B 3006,Find String + + You can enter several strings, separated by the '|' search string separator + character like this: + + Odinn|GoldED + + By default, GoldED searches forward (next messages), but by preceeding the + search string with a '-', the search goes backwards (previous messages). + + Besides the backward search, there are a number of other search command + characters. Here is the complete list: + + - Search backward. + + Search forward. (Just for completeness). + < Search the From: field. + > Search the To: field. + : Search the Subj: field. + = Case-sensitive search. + ! Reverse - Stop/mark when the search string(s) are NOT found. +*P + + By default the '<', '>' and ':' search commands are enabled, so that GoldED + searches all header fields. However, when one of these options are actually + used, the search is limited to those only. + + Examples: + + Odinn Searches in From: and To:, but not Subj:. + :tagline Search for "tagline" in the Subj: field only. + + The search command characters are stripped before the search is started. If + you need to search for a string that begins with a search command character, + you must precede it with the search string separator, like this: + + -|++ Search backwards for the string "++". + + See also ^Marking String^. +*E + +-------------------------------------------------------------------------------- + +*B 3007,Go To Message + + Enter the number of the message you wish to read. +*E + +-------------------------------------------------------------------------------- + +*B 3008,Message Marking + + You can select many different ways to mark messages. + + If you select "Your mail", all messages that contain your name in the From, + To or Subject fields will be marked. + + Marked messages, can be Copied, Moved, Deleted or Written to a disk file or + printer. + + GoldED has a special "read marked" mode, toggled by , with which you + can read the marked messages only. +*E + +-------------------------------------------------------------------------------- + +*B 3009,Marking String + + Enter the string(s) you want messages marked from. + + The syntax of the marking string function is the same as the regular find + function. + + See also ^Find String^. +*E + +-------------------------------------------------------------------------------- + +*B 3010,Message Lister + + Esc Abort message lister + Home First message + End Last message + Right Next message + Left Previous message + Alt-S Go to Marking menu + Ctrl-B Switch between wide and narrow subject column. + Enter Go to reader at the selected message + Space Toggle Mark on the selected message + Tab Toggle BookMark on the selected message + Sh-Tab, BckSp Go to BookMarked message + Alt-X Exit GoldED - ask first + Ctrl-Q Quit GoldED immediately + Alt-O Shell to DOS +*E + +-------------------------------------------------------------------------------- + +*B 3011,Write Message + + You can write the current for marked message(s) to either a file or to the + PRN device. + + If you decide to write to the Print Device, you must make sure that it is + turned on and ready to receive data. In the present version, GoldED uses DOS + calls to send the data to the device, and if the device fails for some + reason, you will get ugly Dos messages and prompts plastered all over the + nice GoldED screen. +*E + +-------------------------------------------------------------------------------- + +*B 3013,File Requesting + + The menu is a list of the files found in the current msg. To filerequest one + or more of these, you have mark them by pressing when the cursor bar + sits on the desired file(s). + + Press to send the request. You will be asked for the destination + system of the request, defaulting to the originator of the original msg. You + can send the request with or without an accompanying msg. A FILES.BBS will + be created, containing the names and descriptions (if any). + + NOTE: Only as many files as can fit in the subject can be requested at the + same time. +*E + +-------------------------------------------------------------------------------- + +*B 4000,Header Editing + + You are editing the message header. move around with the cursorkeys, + and . You can quit the message by pressing . + + If you press in the subject field, or anywhere, you end + the header editing, and proceed to the editor menu. + + In netmail areas, you can use the nodelist lookup and address macro feature + by entering a partial address or last name in the "TO:" name or address + fields. In echo/local areas, only the address macros work. +*E + +-------------------------------------------------------------------------------- + +*B 4001,Delete Original Message + + Do you want to delete the message you have just replied to? + + You can turn off this menu by setting the configuration keyword "ASKDELORIG" + in GOLDED.CFG to "No". +*E + +-------------------------------------------------------------------------------- + +*B 4002,Read Only Area + + You are trying to write a message in "Read Only" area. + + Please think twice before answering Yes.. + + It is probably a better idea to reply in netmail or in another area. + If you want to do reply in another area, press instead. +*E + +-------------------------------------------------------------------------------- + +*B 4003,Send Via Zonegate + + The message destination is in another Zone. The INTL kludge will be inserted + in your message (if USEINTL is enabled), but you must now decide if the + message should be sent directly to the destination or via the established + Zonegate. + + Zonegates have the address +*E + +-------------------------------------------------------------------------------- + +*B 4004,Carbon Copy + + The message contained a Carbon Copy list. + + You can make GoldED process the list and generate the Carbon Copy messages, + you can change the format of the CC list and change the attributes of the CC + messages. + + It is also possible to ignore the CC list, so that it won't be processed. +*E + +-------------------------------------------------------------------------------- + +*B 4005,File Selection + + Esc Abort file selection + Home First file + End Last file + Right, Left Next/previous file + Enter Select the marked file(s) + Space Toggle file mark + Ins Mark file + Del Unmark file + Ctrl-Home Mark all files + Ctrl-End Unmark all files + Alt-O Shell to DOS + Alt-X Exit GoldED - ask first + Ctrl-Q Quit GoldED immediately +*E + +-------------------------------------------------------------------------------- + +*B 4006,Editor Options + + In this menu, you can select internal vs external editor, change attributes, + template and origin for the message. +*E + +-------------------------------------------------------------------------------- + +*B 4007,Nodelist Browser + + Esc Abort nodelist browsing + Nodenumber Search for node + Home First node + End Last node + Right Next node + Left Previous node + Enter Select node + Alt-O Shell to DOS + Alt-X Exit GoldED - ask first + Ctrl-Q Quit GoldED immediately +*E + +-------------------------------------------------------------------------------- + +*B 4008,Save Message + + You have just written a message, and now you have the option to either Save + it, Drop it, Continue editing it, View it, ROT13 crypt it, change Attributes + or Origin. + + Please don't crypt messages, unless you have explicit permission from all + systems the message will pass through. FidoNet Policy 4 says so. +*E + +-------------------------------------------------------------------------------- + +*B 5000,Internal Editor + + Internal Editor Cursor Movements: + + Enter Terminate paragraph and/or add a new line + Up, Down Move cursor up/down one line + Left, Right Move cursor one position left/right + Home Move cursor to beginning of line + End Move cursor to the end of the line + PgDn Move cursor one page of lines down + PgUp Move cursor one page of lines up + Ctrl-Home Move cursor to the top line in the display + Ctrl-End Move cursor to the bottom line in the display + Ctrl-PgUp Move cursor to the first line in the message + Ctrl-PgDn Move cursor to the last line in the message + Ctrl-Left Move cursor to the previous word + Ctrl-Right Move cursor to the next word +*P + + Internal Editor Edit commands: + + Ins Toggle insert mode + Del Delete character at the cursor position + BackSpace Delete character to the left of the cursor + Tab Add spaces to the next tab-stop + Alt-K, Alt-Y Delete from cursor position to end of line + C-BckSp C-F5 Delete the word to the left of the cursor + Ctrl-T,Ctrl-F6 Delete the word to the right of the cursor + F4 Duplicates the current line + Alt-D, Ctrl-Y Delete the current line. (Move to Killbuffer) + Ctrl-U Undelete previously deleted lines + Alt-1 Change cursor character to uppercase + Alt-2 Change cursor character to lowercase + Alt-3 Toggle case of the cursor character +*P + + Internal Editor Block commands: + + Alt-A Set a block "anchor" on the current line + Alt-C Copy current block to Cut'n'Paste buffer + Alt-M Cut current block to Cut'n'Paste buffer + Alt-P Paste a prev. Cut block at cursor position + + Internal Editor Other commands: + + Esc Abort editing this message - ask first + Alt-S, F2 Save this message + (no default) Drop this message - NO ASKING! DANGEROUS! + Alt-H Change attributes + Alt-O Shell to DOS + Alt-I,Alt-R,F3 Import text file into this message + Alt-W Export block to a file + F7 Saves the current message as a file + F8 Loads the message file saved with F7 + F9 Calls external spellchecker with message + Alt-X Exit from GoldED - ask first + Ctrl-Q Quit GoldED immediately - no asking +*E + +-------------------------------------------------------------------------------- + +*B 5001,Export Message + + Type the filename of the block to export. +*E + +-------------------------------------------------------------------------------- + +*B 5002,Import File + + Select the filename of the text file to import in this message. +*E + +-------------------------------------------------------------------------------- + +*B 9001,Out Of Memory + + GoldED just ran out of memory. There is nothing you can do now except press + and let GoldED exit. + + If you were writing a message in the internal editor, you may be able to + recover all or most of your message in the file GOLDED.MSG. + + See also: ^Memory Warning^. +*E + +-------------------------------------------------------------------------------- + +*B 9002,Hudson Size Warning + + GoldED has detected that your Hudson message base is rapidly approaching a + very dangerous size. If you do not run a packing utility very soon, you risk + permanent damage to your message base. + + The absolute maximum size for your message base is a 16 MB big MSGTXT.BBS + file (65536 records of 256 bytes). This is approximately 16000 messages of + average size. + + The GOLDED.CFG keyword HUDSONSIZEWARN defines the size when GoldED starts + displaying this warning screen. + + Press to continue. +*E + +-------------------------------------------------------------------------------- + +*B 9008,Hudson/Goldbase Index Errors + + Your message base index files are out of synchronization. The number of + records in MSGHDR.* does not match the number of records in either MSGIDX.* + or MSGTOIDX.* (or both). + + GoldED cannot continue until the index files are rebuilt. Please run a + message base index rebuild utility immediately. + + Press to exit. +*E + +-------------------------------------------------------------------------------- + +*B 9009,Memory Warning + + You are dangerously low on memory. + + If you proceed now, you may get kicked out later with an "Out of memory" + error. Watch the memory meter on the status line - if it gets under 20-30k, + you may experience strange lockups. + + To correct this situation, run GoldED with more free memory or use the -O + commandline option or GEDCMD environment variable to decrease the overlay + size. +*E + +-------------------------------------------------------------------------------- + END OF HELP FILE +-------------------------------------------------------------------------------- + diff --git a/cfgs/config/goldkeys.cfg b/cfgs/config/goldkeys.cfg new file mode 100644 index 0000000..4f86e00 --- /dev/null +++ b/cfgs/config/goldkeys.cfg @@ -0,0 +1,420 @@ +; ------------------------------------------------------------------ +; GOLDED KEYBOARD DEFINITION FILE. (3.0.0) +; ------------------------------------------------------------------ +; +; Keyboard syntax: +; +; can be: +; +; Key Key (Character or key symbol) +; @Key Alt-Key +; ^Key Ctrl-Key +; #Key Shift-Key +; +; A complete list of definable keys can be found in GOLDREF.TXT. +; +; All possible 's are listed below. Descriptions of the +; commands can be found in GOLDREF.TXT or in the online-help. +; +; NOTE: GoldED has a built-in default keyboard definition map, so +; you actually don't need this file if you want to use only +; the defaults. +; +; - You can de-activate these defaults by putting +; +; KEYBDEFAULTS NO +; +; into GOLDED.CFG. If you don't put this statement into +; GOLDED.CFG, GoldED will add the following definitions to +; the already existing default layout. +; +; - If you want to replace a default definition, simply put a +; different definition into this file. +; +; - If you want to remove a single default definition, replace +; it with XXXXundefine, where XXXX is the respective prefix +; (like "AREAundefine", for example). +; +; +; ------------------------------------------------------------------ +; last update on 98/07/27 (DAM) +; ------------------------------------------------------------------ + +; ------------------------------------------------------------------ +; EXTERNAL UTILITY COMMANDS +; ------------------------------------------------------------------ + +;^F1 ExternUtil01 +;^F2 ExternUtil02 +;^F3 ExternUtil03 +;^F4 ExternUtil04 +;^F5 ExternUtil05 +;^F6 ExternUtil06 +;^F7 ExternUtil07 +;^F8 ExternUtil08 +;^F9 ExternUtil09 +;^F10 ExternUtil10 +;^F11 ExternUtil11 +;^F12 ExternUtil12 +;.... + + +; ------------------------------------------------------------------ +; AREA SELECTION COMMANDS +; ------------------------------------------------------------------ + +@A AREAabort +Esc AREAaskexit +@X AREAaskexit +@F4 AREAaskexit +@B AREAboardnos +@C AREAcatchup +@O AREAdosshell +^M AREAdropmsgmarks +Home AREAgotofirst +;Up AREAgotoprev +;Down AREAgotonext +End AREAgotolast +@H AREAheat +@J AREAjump +^Left AREAjump +^Right AREAjump +^Enter AREAjumpnextmatch +Tab AREAjumpnextmatch +^Q AREAquitnow +@S AREAscan +@P AREAscanpm +Right AREAselect +Enter AREAselect +@R AREAselectmarks +Ins AREAtoggle +@T AREAtoggle +^Z AREAtouchnetscan +@W AREAwritegoldlast +@Z AREAzap + + +; ------------------------------------------------------------------ +; INTERNAL EDITOR COMMANDS +; ------------------------------------------------------------------ + +Esc EDITabort +@A EDITanchor +@X EDITaskexit +@F4 EDITaskexit +@F5 EDITcleardeletebuf +@F6 EDITclearpastebuf +@C EDITcopy +^- EDITcopyabovechar +@M EDITcut +Del EDITdelchar +@K EDITdeleteeol +@Y EDITdeleteeol +BackSpace EDITdelleft +@D EDITdelline +^Y EDITdelline +^BackSpace EDITdelltword +^F5 EDITdelltword +^F6 EDITdelrtword +^T EDITdelrtword +@O EDITdosshell +F4 EDITdupline +;@Z EDITexitmsg +@W EDITexporttext +Home EDITgobegline +^PgDn EDITgobotline +^End EDITgobotmsg +@Down EDITgodown +Down EDITgodown +^Down EDITgodown +End EDITgoeol +@Left EDITgoleft +@Left EDITgoleft +Left EDITgoleft +PgDn EDITgopgdn +PgUp EDITgopgup +@Right EDITgoright +@Right EDITgoright +Right EDITgoright +^PgUp EDITgotopline +^Home EDITgotopmsg +@Up EDITgoup +Up EDITgoup +^Up EDITgoup +^Left EDITgowordleft +^Right EDITgowordright +@H EDITheader +@Q EDITimportquotebuf +@I EDITimporttext +@R EDITimporttext +F3 EDITimporttext +F8 EDITloadfile +@L EDITlookupcursor +#F10 EDITlookupdest +F10 EDITlookuporig +Enter EDITnewline +@P EDITpaste +^Q EDITquitnow +@B EDITreflow +F7 EDITsavefile +@S EDITsavemsg +F2 EDITsavemsg +^Z EDITsavemsg +F9 EDITspellcheck +Tab EDITtab +#Tab EDITtabreverse +@3 EDITtogglecase +Ins EDITtoggleinsert +@2 EDITtolower +@1 EDITtoupper +^U EDITundelete +@Z EDITzapquotebelow + + +; ------------------------------------------------------------------ +; FILE SELECTION COMMANDS +; ------------------------------------------------------------------ + +Esc FILEabort +@X FILEaskexit +@F4 FILEaskexit +@O FILEdosshell +Home FILEgotofirst +End FILEgotolast +Right FILEgotonext +Left FILEgotoprev +Ins FILEmark +;+ FILEmark +^Enter FILEmarkall +^Home FILEmarkall +^Q FILEquitnow +Enter FILEselect +Space FILEtogglemark +;* FILEtogglemarkall +Del FILEunmark +;- FILEunmark +^End FILEunmarkall + + +; ------------------------------------------------------------------ +; MESSAGE LISTER COMMANDS +; ------------------------------------------------------------------ + +Esc LISTabort +@X LISTaskexit +@F4 LISTaskexit +@O LISTdosshell +#Tab LISTgotobookmark +BackSpace LISTgotobookmark +Home LISTgotofirst +End LISTgotolast +Right LISTgotonext +Left LISTgotoprev +S LISTmarkingoptions +@S LISTmarkingoptions +@F9 LISTmarkingoptions +^Q LISTquitnow +Enter LISTselect +Tab LISTtogglebookmark +^D LISTtoggledate +Space LISTtogglemark +^B LISTtogglewidesubj + + +; ------------------------------------------------------------------ +; NODELIST BROWSER COMMANDS +; ------------------------------------------------------------------ + +Esc NODEabort +@X NODEaskexit +@F4 NODEaskexit +@O NODEdosshell +Home NODEgotofirst +End NODEgotolast +Right NODEgotonext +Left NODEgotoprev +^Q NODEquitnow +Enter NODEselect + + +; ------------------------------------------------------------------ +; MESSAGE READER COMMANDS +; ------------------------------------------------------------------ + +^B READaddressbookadd +@F4 READaskexit +@X READaskexit +X READaskexit +^A READchangeaka +^S READchangeattrs +; READchangecharsin +; READchangecharsout +@C READchangemsg +C READchangemsg +F2 READchangemsg +^O READchangeorigin +^I READchangetagline +^T READchangetemplate +^U READchangeusername +^J READchangexlatimport +@G READcommentmsg +G READcommentmsg +#F8 READcopymoveforward +@M READcopymoveforward +M READcopymoveforward +; READdecreasemargin +@D READdeletemsg +D READdeletemsg +Del READdeletemsg +@O READdosshell +O READdosshell +^F10 READdosshell +#F4 READfidorenumber +^R READfidorenumber +^F READfilerequest +F READfindall +@F READfindall +#F6 READfindall +Z READfindheader +@Z READfindheader +F6 READfindheader +#Tab READgotobookmark +BackSpace READgotobookmark +- READgotoreplyprev +@Left READgotoreplyprev +^Left READgotoreplyprev +< READgotofirstmsg +^Home READgotofirstmsg +> READgotolastmsg +^End READgotolastmsg +^G READgotomsgno +^N READgotonextarea +Right READgotonextmsg +@Right READgotonextunread +@U READgotonextunread +^P READgotoprevarea +Left READgotoprevmsg +@Left READgotoprevunread ++ READgotoreplies +^Right READgotoreplies +* READgotoreplynext +- READgotoreplyprev +^Left READgotoreplyprev +; READincreasemargin +#F10 READlookupdest +F10 READlookuporig +;^M READmainmenu +^L READmakeuserlist +^K READmakepathreport +S READmarkingoptions +@S READmarkingoptions +@F9 READmarkingoptions +@L READmessagelist +F9 READmessagelist +L READmessagelist +@B READmovecommentmsg +B READmovecommentmsg +@N READmovequotemsg +F5 READmovequotemsg +N READmovequotemsg +Enter READmsgcontinue +End READmsgend +Home READmsghome +Down READmsglinedown +^Down READmsglinedown +Up READmsglineup +^Up READmsglineup +PgDn READmsgpgdn +PgUp READmsgpgup +@A READnewarea +A READnewarea +Esc READnewarea +^F1 READnewarea +@E READnewmsg +E READnewmsg +Ins READnewmsg +^Q READquitnow +^W READquotebuf +@Q READquotemsg +F4 READquotemsg +Q READquotemsg +@R READreplymsg +F3 READreplymsg +R READreplymsg +; READthreadtree +Tab READtogglebookmark +@I READtogglehexdump +I READtogglehexdump +^F9 READtogglehexdump +@H READtogglehidden +H READtogglehidden +^F7 READtogglehidden +@V READtogglehiddklud +V READtogglehiddklud +^F5 READtogglehiddklud +@K READtogglekludge +K READtogglekludge +^F6 READtogglekludge +Space READtogglemark +@J READtogglemarkread +J READtogglemarkread +@P READtogglepagebar +P READtogglepagebar +^F8 READtogglepagebar +^V READtogglequote +@Y READtogglerealmsgno +Y READtogglerealmsgno +^F4 READtogglerealmsgno +U READtogglerot13 +^F3 READtogglerot13 +@T READtoggletwits +T READtoggletwits +^Z READtouchnetscan +@F10 READuserbase +^X READuudecode +@W READwritemsg +F7 READwritemsg +W READwritemsg + + +; ------------------------------------------------------------------ +; KEYBOARD MACROS +; ------------------------------------------------------------------ +; +; Macro syntax: Macro [..] +; +; Any valid Key. +; A string of letters, enclosed in quotes. +; Any valid GoldED Command, see the above. +; +; If is "Auto", the macro will be executed automatically after +; GoldED has initialized. +; +; ------------------------------------------------------------------ + +; This Auto macro scans all areas and puts you in the first with new +; mail. +;Auto Macro AREAscan "A" End AREAjump + +; For the internal editor: Add an empty line below the current. +;^N EDITmacro EDITnewline EDITgoup + +; Move-reply to netmail and go to template selection menu. Note that +; ^Enter means "accept all" in this context (header edit). +;@F1 READmacro READmovequotemsg "NETMAIL" AREAselect ^Enter "T" + +; Set bookmark on the current message before moving in the link. +;@Left READmacro READtogglebookmark READgotoreplyprev +;@Right READmacro READtogglebookmark READgotoreplies + +;@F1 READmacro READcopymoveforward "M" "NET.DK-BBS" Enter +;@F2 READmacro READcopymoveforward "M" "NET.DK-POINT" Enter +;@F3 READmacro READcopymoveforward "M" "NET.GOLDED" Enter +;@F4 READmacro READcopymoveforward "M" "NET.RCVD" Enter +;@F5 READmacro READcopymoveforward "M" "NET.SITES" Enter + +;F12 READmacro READreplymsg ^Enter "T" End Enter "I" EDITsavemsg "Y" +;F11 EDITmacro ":-)" +;^F11 EDITmacro ":-(" + +; ------------------------------------------------------------------ diff --git a/cfgs/config/goldlang.cfg b/cfgs/config/goldlang.cfg new file mode 100644 index 0000000..c98e255 --- /dev/null +++ b/cfgs/config/goldlang.cfg @@ -0,0 +1,499 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.0.1-asa10 * Example Language Definition File +// +// Before you start redefining the language, I suggest you print this +// file and keep it close for reference. Redefining can be a slow and +// difficult process. +// +// The format of lines in this language file is: +// +// <"string"> +// +// Each stringid is prefixed with a category, to allow easier +// identification for your own redefinitions. Not case sensitive. +// +// ID Categories: +// -------------- +// ST_ Status Line Variable length. +// WT_ Window Title Variable length. +// MI_ Menu Item Fixed length, first character QuickChar. +// IL_ Info Line Variable length. +// WL_ Window Line Usually fixed length. +// HD_ Header Line Usually fixed length. +// MS_ Message Variable length. +// ER_ Error Message Variable length. +// +// "Fixed length" means that all the strings must the same length. +// The actual length is normally only limited by the screen size. In +// case of menus, the window width is always based on the length of +// the *first* item string. +// +// A "QuickChar" is the highlighted direct-select character in the +// menu items. The QuickChar is case sensitive, and must match a +// character in the string. +// +// Strings should always be enclosed in quotes ("" or ''). The +// exception is if the string does not need leading/trailing spaces. +// +// Some strings contains escape sequences or format specifiers as +// used in the "C" language. Certain tokens from the templates can +// also be used in some special strings. +// +// Escape sequences: (Case sensitive!) +// ----------------------------------- +// \n - Line Feed (LF) (translates to CR+LF in files under DOS, +// Windows and OS/2). +// \r - Carriage Return (CR). +// +// The escape sequences are normally used in lines for files or +// standard (OS) output messages. +// +// Format specifiers: (Case sensitive!) +// ------------------------------------ +// %c - Character. +// %s - String. +// %i - Integer. +// %u - Unsigned Integer. +// %% - A literal percent (%) character. +// +// If you change a line with format specifiers, please be careful to +// have them in the same quantity and order as in the original +// example. Failure to do this can cause unpredictable results.. +// +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- WEEKDAY AND MONTH NAMES + +// Weekdays, short +MS_SWSUN "Sun" +MS_SWMON "Mon" +MS_SWTUE "Tue" +MS_SWWED "Wed" +MS_SWTHU "Thu" +MS_SWFRI "Fri" +MS_SWSAT "Sat" + +// Weekdays, long +MS_LWSUNDAY "Sunday" +MS_LWMONDAY "Monday" +MS_LWTUESDAY "Tuesday" +MS_LWWEDNESDAY "Wednesday" +MS_LWTHURSDAY "Thursday" +MS_LWFRIDAY "Friday" +MS_LWSATURDAY "Saturday" + +// Months, short +MS_SMJAN "Jan" +MS_SMFEB "Feb" +MS_SMMAR "Mar" +MS_SMAPR "Apr" +MS_SMMAY "May" +MS_SMJUN "Jun" +MS_SMJUL "Jul" +MS_SMAUG "Aug" +MS_SMSEP "Sep" +MS_SMOCT "Oct" +MS_SMNOV "Nov" +MS_SMDEC "Dec" + +// Months, long +MS_LMJANUARY "January" +MS_LMFEBRUARY "February" +MS_LMMARCH "March" +MS_LMAPRIL "April" +MS_LMMAY "May" +MS_LMJUNE "June" +MS_LMJULY "July" +MS_LMAUGUST "August" +MS_LMSEPTEMBER "September" +MS_LMOCTOBER "October" +MS_LMNOVEMBER "November" +MS_LMDECEMBER "December" + +---------------------------------------------------------------------- +-- MISCELLANEOUS LANGUAGE KEYWORDS + +ST_IMPORTFILE "Import File" +WT_IMPORTWHICHFILE " Import which file? " +WT_IMPORTPICK " Import " +WT_IMPORTTXT " Import " +MI_IMPORTTXTTEXT "T File as Text " +MI_IMPORTTXTQUOTE "Q File as Quote " +MI_IMPORTTXTUUE "U Binary as UUE " +MI_IMPORTTXTMIME "M Binary as MIME " +MI_IMPORTTXTCLIP "C From Clipboard " +MI_IMPORTTXTXLAT "s Use Charset.. " +MI_IMPORTTXTQUIT "N Nothing / Quit " +ST_IMPORTSTATUS "Importing from %s" +ST_EXPORTFILE "Export File" +WT_EXPORTWHATFILE " Export to what file? " +ST_EXPORTSTATUS "Exporting to %s" +ST_EDITSTATUS "Edit %i,%i. %s" +ST_SELECTFILES "Select Files" +WL_SELECTEDFILES "Selected Files " +WL_SELECTEDBYTES " Bytes " +WL_TOTALFILES "Total Files " +WL_TOTALBYTES " Bytes " +WL_SCANNINGDIRECTORY " Scanning Directory " +WL_NOFILESFOUND " * NO FILES FOUND * " +ST_FILESPRESSKEY "Press any key to continue" +WT_AREA "Area" +WT_DESCRIPTION "Description" +WT_MSGS "Msgs" +WT_LAST "Last" +WT_ECHOID "EchoID" +ST_UNREAD "unread" +WT_SCANAREAS " Scan Areas " +MI_SCANALL "A Scan All " +MI_SCANMARKED "M Scan Marked " +MI_SCANCURRENT "C Scan Current " +MI_SCANMATCHING "t Scan Matching " +MI_SCANUNSCANNED "U Scan Unscanned " +MI_NOSCAN "N No Scan / ESC " +WT_HEATAREAS " Heat Areas " +MI_HEATALL "A Heat All " +MI_HEATMARKED "M Heat Marked " +MI_HEATCURRENT "C Heat Current " +MI_NOHEAT "N No Heat / ESC " +WT_ZAPAREAS " Zap Areas " +MI_ZAPALL "A Zap All " +MI_ZAPMARKED "M Zap Marked " +MI_ZAPCURRENT "C Zap Current " +MI_NOZAP "N No Zap / ESC " +MS_DOS_SHELL "GoldED Shell. Type EXIT To Return." +IL_SCANNINGAREA " Scanning Area:" +IL_SEARCHINGFOR " Searching for" +ST_READINGMSG "Reading Msg %u of %u" +ER_OUTOFMEM "Out of memory!" +MS_HEXDUMPHEAD "Hexdump of message header:" +MS_HEXDUMPTEXT "Hexdump of message text:" +ST_RENUMBERING "Renumbering" +ST_LOCKED " (locked)" +ST_RENUMBERED "Messages Renumbered - Press Key" +WL_BLANKMSG "" +WL_WAIT " Wait " +IL_GENHEXDUMP " Generating Hexdump - Please Wait " +ST_PROCESSCC "Processing Carbon Copies" +ST_STATUSCC "CC: %s of %u:%u/%u.%u" +ST_DESTINATIONCC "Select Carbon Copy Destination" +MS_LISTCC "%s %u:%u/%u.%u" +WT_DELORIG " Delete Original? " +MI_DELORIGYES "Y Yes Please. " +MI_DELORIGNO "N No! " +WT_DROPMSG " Drop This Msg? " +MI_DROPMSGYES "Y Yes Please. " +MI_DROPMSGNO "N No! " +WT_ZONEGATE " Send via ZoneGate? " +MI_ZONEGATEYES "Y Yes Please. " +MI_ZONEGATENO "N No! " +ST_QUOTEPCT "Your Msg Contains %i%% Quotes%s" +WT_SAVEMSG " Save these %i lines? " +MI_YESGREAT "Y Yes, it's great stuff " +MI_KICKIT "N No, drop it.. / ESC " +MI_CONTINUE "C Continue writing " +MI_ROT13 "R ROT13 Crypting " +MI_ATTRS "A Change Attributes " +MI_ORIGS "O Change Origin " +MI_VIEW "V View the message " +ST_SELECTDESTNODE "Select Destination Node" +WT_ATTACHFILES " Attach Files " +WT_UPDREQFILES " Update Request Files " +ST_EDITHEADER "Edit Header Data" +WT_EDITING " Editing " +MI_INTERNALED "I Internal Editor " +MI_EXTERNALED "E External Editor " +MI_SAVEMESSAGE "S Save Message " +MI_ATTRO "A Attributes " +MI_TEMPLATE "T Templates " +MI_ORIGIN "O Origins " +MI_QUITMESSAGE "Q Quit / ESC " +ST_TEMPLATES " Templates " +WT_CHANGETEMPLATES "Change Default Template" +WT_CARBONCOPY " Carbon Copy " +MI_CCPROCESS "P Process CC's " +MI_CCIGNORE "I Ignore CC's " +MI_CCATTRIBS "C Change Attrs " +MI_CCLISTFMT "L List Format " +WT_CCLIST " CC List " +MI_CCLISTKEEP "K Keep " +MI_CCLISTNAMES "N Names only " +MI_CCLISTVISIBLE "V Visible " +MI_CCLISTHIDDEN "H Hidden " +MI_CCLISTREMOVE "R Remove " +WT_ATTRTITLE " Attributes " +MI_ATTR01 " Private Archive/Sent " +MI_ATTR02 " Crash Direct " +MI_ATTR03 " Received Zonegate " +MI_ATTR04 " Sent Hub/Host-Route " +MI_ATTR05 " File Attach Immediate " +MI_ATTR06 " Transit Xmail " +MI_ATTR07 " Orphan Erase File/Sent " +MI_ATTR08 " Kill/Sent Trunc File/Sent " +MI_ATTR09 " Local Locked " +MI_ATTR10 " Hold Confirm Rcpt Request " +MI_ATTR11 " File Request FTS1 Reserved " +MI_ATTR12 " Return Rcpt Request QBBS Reserved, Net " +MI_ATTR13 " Return Rcpt QBBS Reserved, Echo " +MI_ATTR14 " Audit Request Squish Scanned " +MI_ATTR15 " File Update Request Zap all attribs " +HD_FROM " From : " +HD_TO " To : " +HD_SUBJ " Subj : " +HD_FILE " File : " +MS_EMPTYMSG "\r" +MS_AUTOATTACHMSG "\r" +MS_AUTOREQUESTMSG "\r" +MS_AUTOUPDREQMSG "\r" +WT_FILEATTACH " File Attach " +WT_FILEREQUEST " File Request " +WT_FILEUPDREQ " Update Request " +ST_FILEATTACHING "File Attaching [%i/%i] to %u:%u/%u.%u" +ST_FILEREQUESTING "File Requesting [%i/%i] from %u:%u/%u.%u" +ST_FILEUPDREQING "Update Requesting [%i/%i] from %u:%u/%u.%u" +ST_READMARKED "Read Marked - Msg %u of %u (%u left)" +ST_READALL "Read All - Msg %u of %u (%u left)" +ST_NOQRENUM "This area cannot be renumbered" +MS_HIDINGTWIT "This is a Twit Message - Press to read." +HD_VIA "via" +WT_CHANGEATTRS "Change Message Attributes" +WT_HEADERTEXT " Enter Searchstring (Header+Text) " +WT_HEADERONLY " Enter Searchstring (Header Only) " +WT_NEWAREA ">>Pick New Area: " +WT_REPLYAREA ">>Answer In Area: " +WT_COPYAREA ">>Copy To Area: " +WT_MOVEAREA ">>Move To Area: " +WT_FORWARDAREA ">>Forward To Area: " +WT_FREQAREA ">>Filerequest In Area: " +WT_FREQMENUTITLE "Requestable files" +ST_FREQSTAT "Pick files to request" +IL_FREQINFONOFILES " No requestable files were found in this msg! " +WT_COPY " Copy " +WT_MOVE " Move " +WT_COPYING " Copying " +WT_MOVING " Moving " +ST_COPYINGMSG "Copying Msg %u of %u to %s" +ST_MOVINGMSG "Moving Msg %u of %u to %s" +WT_DELETE " Delete " +WT_DELETING " Deleting " +ST_DELETINGMSG "Deleting Msg %u of %u" +WT_WRITE " Write " +WT_WRITEMSGS " Write Msg(s) to File " +WT_WRITING " Writing " +ST_WRITINGMSG "Writing Msg %u of %u" +WT_WRITINGFILE " Writing Msg(s) to File %s " +WT_WRITINGPRN " Writing Msg(s) to Print Device " +IL_READONLYWARN " This area is READ ONLY! " +WT_ISREADONLY " Write msg anyway? " +MI_READONLYYES "Y Yes Please. " +MI_READONLYNO "N No! " +IL_CHANGEWARN " This msg is NOT from you! " +WT_CHANGE " Change this msg? " +MI_CHANGEYES "Y Yes Please. " +MI_CHANGENO "N No! " +WT_DELETETHIS " Delete this msg? " +MI_DELETEYES "Y Yes Please. " +MI_DELETENO "N No! " +MI_DELETENOASK "D Don't ask.. " +WT_GOTONEXT " Goto Next Area? " +MI_GOTONEXTYES "Y Yes Please. " +MI_GOTONEXTNO "N No! " +MI_GOTONEXTNEW "U Yes, Next Unread Area. " +WT_FORWARD " Use FWD kludges? " +MI_FORWARDYES "Y Yes Please. " +MI_FORWARDNO "N No! " +WT_MSG "Msg" +WT_MSGREAL "Msg#" +WT_FROML "From" +WT_TOL "To" +WT_SUBJL "Subj" +ST_MSGLISTER "Lister - Msg %u of %u (%u left)" +ST_COPYMOVEFORWARD "Copy, Move or Forward this message" +WT_SELECTACTION " Action " +MI_FORWARDMESSAGE "F Forward Msg " +MI_MOVEMESSAGE "M Move Msg " +MI_COPYMESSAGE "C Copy Msg " +MI_QUITCMF "Q Quit / ESC " +ST_ARE "messages are" +ST_IS "message is" +ST_MARKED "marked" +MI_MARKEDMSG "M Marked Msgs " +MI_CURRENTMSG "C Current Msg " +MI_QUITMSGS "Q Quit / ESC " +ST_WRITEMSGSTO "Write Msg(s) to File or Printer" +WT_WRITETO " Write To: " +MI_DISKFILE "D Disk File " +MI_PRINTER "P Print device " +MI_QUITWRITE "Q Quit / ESC " +ST_MARKINGOPTIONS "Message Marking" +WT_MARKWHAT " Mark What? " +MI_YOURMAIL "Y Your personal mail " +MI_FROMTOSUBJ "H Header (From/To/Subj) " +MI_TEXTHDR "T Text and header " +MI_THREAD "R Reply thread " +MI_NEWMSGS "N New msgs >current " +MI_OLDMSGS "O Old msgs to ignore" +IL_READINGECHOLIST "Reading Echolist Files" +IL_READINGADDRMACROS "Reading Address Macros" +IL_CHECKINGNODELISTS "Checking Nodelists" +ST_CROSSPOSTING "Crossposting in %s" +IL_TWITBLANKED " Twit Msgs Blanked " +IL_TWITSKIPPED " Twit Msgs Skipped " +IL_TWITIGNORESKIP " Twit Msgs Ignored and Skipped " +IL_TWITDISPLAYED " Twit Msgs Displayed " +IL_TWITKILLED " Twit Msgs Killed " +IL_STYLECODESNO " Stylecodes disabled " +IL_STYLECODESYES " Stylecodes enabled " +IL_STYLECODESHIDE " Stylecodes enabled and stripped " +ST_GENCFMRECEIPT "Generating Confirmation Receipt" +WT_NEW "New" +ST_LOOKUPINFO "Nodelist Lookup Information" +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" +MS_ORIGINALLYIN "* Originally in %s" +MS_CROSSPOSTEDIN "* Crossposted in %s" +ST_STATUSLINEHELP "F1 Help" +HD_OF "of" +MS_ROBOTMSG "\r--- @longpid @version\r" +ST_STATUSLINETIMEFMT "%H:%M" + +WT_REPLIES " Replies " +ST_SELECTREPLY "Select the reply you want to see" +IL_WAITOREXIT " At this point you must either wait or exit GoldED entirely - Sorry! " +WT_REALLYEXIT " Really exit? " +MI_TAGLINES "T Change Tagline" +MI_HEADEREDIT "H Edit Header" +MI_SCANGROUP "G Scan Group" +WT_QWKPACKET " QWK Packet " +MI_SCANQWK "Q QWK Packet" +WT_SOUPPACKET " SOUP Packet " +MI_SCANSOUP "S SOUP Packet" +MI_SCANIMPORT "I Import" +MI_SCANEXPORT "E Export" +WT_SCANPM " Scan PM " +MI_TAGLINE "g Taglines" +WT_CONFIRM " Honor receipt request? " +MI_CONFIRMYES "Y Yes, send a receipt msg " +MI_CONFIRMNO "N No, ignore the request " +IL_CONFIRMINFO " The sender of this message requests confirmation of receipt (CFM) " +ST_MSG "msg" +ST_MSGS "msgs" +ST_PERSONAL "personal" +WT_GRP "Grp" +IL_FOUNDPERSONAL " Found %u personal mail%s in %u area%s " +IL_NOPERSONAL " No personal mail found " +ST_ESCORCONTINUE "ESC exits. Other keys: Tries to continue" +MS_SPELLCHECKER "SpellChecker: %s" +WT_INS " Ins " +MI_FILELISTFROM "Filelist from %s" +ST_INITIALIZING "Initializing ..." +ST_CHECKING "Checking" +ST_LOCKSHARECAP "%s Lock/Share Capability" +WT_ATTRTURNOFF " Press Alt-F1 to turn off this window " +WT_TAGLINES " Taglines " +ST_CHANGETAGLINE "Change Default Tagline" +IL_NOTAGLINE " No taglines defined. Press key " +WT_CHARSETS " Charsets " +ST_CHANGEXLATIMP "Change Default Import Charset" +IL_NOXLATIMPORT " No XLATIMPORT's defined. Press key " +WT_N_A "n/a" +WT_WRITTEN "Written" +WT_ARRIVED "Arrived" +WT_RECEIVED "Received" +IL_NONODELIST " Unable to access the nodelist or index files " +IL_NODELISTMISSING "Nodelist missing:" +IL_NODELISTOUTDATED "Nodelist out of date:" +MS_REPLYLINKER "Replylinker: %s" +WT_ENTERMSGNO " Enter msgno " +IL_WAITUUDECODING " Wait - uudecoding the current message " +IL_COMPLETEDUUDECODE " Completed uudecode of %s " +IL_NOTUUENCODED " Could not find anything to uudecode in this message " +IL_UUEINVALIDPATH " Invalid path for uudecoding - file not written " +IL_PATHREPORT " Generating PATH report " +IL_ERRORINSOUP " Error in SOUP file %s " +IL_WARNALREADYSENT " WARNING: This message is already sent! " +IL_WAITLOCKED " Wait: %s is locked " +ST_RETRYORESC "%s retry (%lu). Press ESC to exit GoldED." +ST_RETRYLOCK "Lock" +ST_RETRYOPEN "Open" +WT_TOUCHSEMAPHORE " Enter name of semaphore file to touch " +MI_WRITETOHDRNO "H Use Header: NO " +MI_WRITETOHDRYES "H Use Header: YES " +MI_CLIPBOARD "C Clipboard " +WT_SELECTMARKS " Select Mark " +WT_SELECTMARKSEDIT " Edit Mark Description " +IL_DROPMARKSINFO " %s Messages Are Marked " +WT_DROPMARKS " Drop Msg Marks " +MI_DROPALL "A Drop All " +MI_DROPMARKED "M Drop Marked " +MI_DROPCURRENT "C Drop Current " +MI_NODROP "N No Drop / ESC " +WT_CATCHAREAS " Catch-Up Areas " +MI_CATCHALL "A Catch All " +MI_CATCHMARKED "M Catch Marked " +MI_CATCHCURRENT "C Catch Current " +MI_NOCATCH "N No Catch / ESC " +WT_CROSSPOST " Crosspost " +MI_XCPROCESS "P Process XC's " +MI_XCIGNORE "I Ignore XC's " +MI_XCLISTFMT "L List Format " +WT_XCLIST " XC List " +MI_XCLISTRAW "K Keep " +MI_XCLISTVERBOSE "V Verbose " +MI_XCLISTLINE "L Line " +MI_XCLISTREMOVE "R Remove " + +WT_ADDRESSBOOK " Addressbook " +WT_ADVANCEDSEARCH " Advanced Search " +IL_NOMOREMATCHES " No more matches found " +WT_HEADEREDITHELP1 " #F10: Nodelist " +WT_HEADEREDITHELP2 " F10: Addressbook " +WT_THREADLISTTITLE " Message Thread List " +WT_ADVANCEDMARKING " Advanced Marking " +ST_USERSTATUSLINE "GoldED's Address Book - %d of %d (%d left)" +WT_USERHEADERNAME "Name" +WT_USERHEADERORG "Organization" +WT_USERHEADERAKA "Address" +IL_USERWAIT " Wait - Browsing Address Book... " diff --git a/cfgs/config/goldlang.ger b/cfgs/config/goldlang.ger new file mode 100644 index 0000000..24f368f --- /dev/null +++ b/cfgs/config/goldlang.ger @@ -0,0 +1,488 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.00 * Beispieldatei fr eine eingedeutschte Oberfl„che +// +// Bevor du diese Datei ver„nderst, schlage ich Dir vor, sie zuerst +// auszudrucken und als Vorlage zu verwenden. Das Umdefinieren kann +// eine langsame und schwierige Sache sein. +// +// Das Zeilenformat in dieser Sprachdatei ist: +// +// <"string"> +// +// Jede hat einen Kategorieprefix, um Dir mehr Infos +// bei deinen eigenen Redefinitionen zu geben. Groá/Kleinschreibung +// ist egal. +// +// Kategorieprefix: +// -------------- +// ST_ Statuszeile L„nge variabel. +// WT_ Fenstertitel L„nge variabel. +// MI_ Meneintrag feste L„nge, erstes Zeichen Quickchar. +// IL_ Infozeile L„nge variabel. +// WL_ Fensterzeile meist feste L„nge. +// HD_ Kopfzeile meist feste L„nge. +// MS_ Infotext L„nge variabel. +// ER_ Fehlertext L„nge variabel. +// +// "feste L„nge" bedeutet, daá alle Zeichenketten dieselbe L„nge haben +// mssen. Die jeweilige L„nge ist normalerweise nur durch die +// Bildschirmbreite begrenzt. Bei Mens h„ngt die Breite von der L„nge +// des *ersten* Meneintrags ab. +// +// Ein "Quickchar" ist der hervorgehobene "Direktauswahl" Buchstabe +// der Meneintr„ge. Der Quickchar ist Groá/Kleinschreibungsabh„ngig, +// und muá mit einem Buchstaben in der restlichen Zeichenkette +// bereinstimmen. +// +// Die Zeichenketten mssen immer in "" oder '' eingebettet sein, es +// sei denn, es werden keine fhrenden/nachfolgenden Leerzeichen +// ben”tigt. +// +// Manche Zeichenketten k”nnen Formatierungsangaben, wie sie in der +// Programmiersprache "C" verwendet werden, enthalten. Manche +// Templatetokens k”nnen ebenfalls in speziellen Zeichenketten +// verwendet werden. +// +// Kontrollzeichen (Groá/Kleinschreibungsabh„ngig!): +// ------------------------------------------------- +// \n - Zeilenvorschub (LF) (wird in CRLF bei Dateien umgesetzt) +// \r - Wagenrcklauf (CR). +// +// Die Kontrollzeichen werden normalerweise in Zeilen fr Dateien oder +// Standardausgaben (via DOS) benutzt. +// +// Formatierungsangaben (Groá/Kleinschreibungsabh„ngig!): +// ------------------------------------------------------ +// %c - einzelnes Zeichen. +// %s - Zeichenkette. +// %i - eine ganzzahlige Zahl. +// %u - eine vorzeichenlose, ganze Zahl. +// %% - ein Prozent-Zeichen (%) +// +// Wenn du eine Zeile mit Formatierunngsangaben ver„nderst, sei bitte +// vorsichtig und achte darauf, daá sie in der gleichen Anzahl und +// Reihenfolge wie in der ursprnglichen Form stehen. Wenn du dies +// nicht befolgst, k”nnen unerwartete Dinge passieren (sic!). +// +// ------------------------------------------------------------------ +// +// deutsche šbersetzung by Dirk A. Mueller, 2:2468/9909.9 +// e-mail: damware@gmx.net +// +// basierend auf Arbeit by Dirk Frieborg, 2:240/6231 +// +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- WOCHENTAGE UND MONATE + +// Wochentage, kurz +MS_SWSUN "So" +MS_SWMON "Mo" +MS_SWTUE "Di" +MS_SWWED "Mi" +MS_SWTHU "Do" +MS_SWFRI "Fr" +MS_SWSAT "Sa" + +// Wochentage, lang +MS_LWSUNDAY "Sonntag" +MS_LWMONDAY "Montag" +MS_LWTUESDAY "Dienstag" +MS_LWWEDNESDAY "Mittwoch" +MS_LWTHURSDAY "Donnerstag" +MS_LWFRIDAY "Freitag" +MS_LWSATURDAY "Samstag" + +// Monate, kurz +MS_SMJAN "Jan" +MS_SMFEB "Feb" +MS_SMMAR "Mrz" +MS_SMAPR "Apr" +MS_SMMAY "Mai" +MS_SMJUN "Jun" +MS_SMJUL "Jul" +MS_SMAUG "Aug" +MS_SMSEP "Sep" +MS_SMOCT "Okt" +MS_SMNOV "Nov" +MS_SMDEC "Dez" + +// Monate, lang +MS_LMJANUARY "Januar" +MS_LMFEBRUARY "Februar" +MS_LMMARCH "M„rz" +MS_LMAPRIL "April" +MS_LMMAY "Mai" +MS_LMJUNE "Juni" +MS_LMJULY "Juli" +MS_LMAUGUST "August" +MS_LMSEPTEMBER "September" +MS_LMOCTOBER "Oktober" +MS_LMNOVEMBER "November" +MS_LMDECEMBER "Dezember" + + +---------------------------------------------------------------------- +-- VERSCHIEDENES + +ST_IMPORTFILE "Importiere Datei" +WT_IMPORTWHICHFILE " Importiere welche Datei? " +WT_IMPORTPICK " Importiere " +WT_IMPORTTXT " Import " +MI_IMPORTTXTTEXT "T Datei als Text " +MI_IMPORTTXTQUOTE "Q Datei als Quote " +MI_IMPORTTXTUUE "U Bin„r als UUE " +MI_IMPORTTXTMIME "M Bin„r als MIME " +MI_IMPORTTXTCLIP "C Vom Clipboard " +MI_IMPORTTXTXLAT "s Benutze Charset.. " +MI_IMPORTTXTQUIT "N Nichts / zurck " +ST_IMPORTSTATUS "Importiere von %s" +ST_EXPORTFILE "Exportiere Datei" +WT_EXPORTWHATFILE " Exportiere nach.. " +ST_EXPORTSTATUS "Exportiere nach %s" +ST_EDITSTATUS "Editor %i,%i. %s" +ST_SELECTFILES "Dateiauswahl" +WL_SELECTEDFILES "Gew„hlte Dateien " +WL_SELECTEDBYTES " Bytes " +WL_TOTALFILES "Gesamt Dateien " +WL_TOTALBYTES " Bytes " +WL_SCANNINGDIRECTORY " Lese Verzeichnis " +WL_NOFILESFOUND " * KEINE DATEIEN GEFUNDEN * " +ST_FILESPRESSKEY "Beliebige Taste zum Fortsetzen" +WT_AREA "Area" +WT_DESCRIPTION "Beschreibung" +WT_MSGS "Msgs" +WT_LAST "Letzte" +WT_ECHOID "EchoID" +ST_UNREAD "ungelesen" +WT_SCANAREAS " Areas scannen " +MI_SCANALL "A Alle " +MI_SCANMARKED "M Markierte " +MI_SCANCURRENT "D Diese Hier " +MI_SCANMATCHING "P Passende " +MI_SCANUNSCANNED "U Undurchsuchte " +MI_NOSCAN "N Nichts / ESC " +WT_HEATAREAS " Area-Endmarke setzen " +MI_HEATALL "A Alle Areas " +MI_HEATMARKED "M Markierte " +MI_HEATCURRENT "D Diese Hier " +MI_NOHEAT "N Nichts / ESC " +WT_ZAPAREAS " Area-Endmarke l”schen " +MI_ZAPALL "A Alle Areas " +MI_ZAPMARKED "M Markierte " +MI_ZAPCURRENT "D Diese Hier " +MI_NOZAP "N Nichts / ESC " +MS_DOS_SHELL "GoldED-Kommandozeile. Zurck mit EXIT." +IL_SCANNINGAREA " Scanne Area:" +IL_SEARCHINGFOR " Suche nach" +ST_READINGMSG "Lese Message %u von %u" +ER_OUTOFMEM "Nicht gengend Speicher!" +MS_HEXDUMPHEAD "Hexdump des Messageheaders:" +MS_HEXDUMPTEXT "Hexdump des Messagetextes:" +ST_RENUMBERING "Renumeriere" +ST_LOCKED " (geschtzt)" +ST_RENUMBERED "Messages renumeriert - bitte Taste drcken!" +WL_BLANKMSG "" +WL_WAIT " Moment... " +IL_GENHEXDUMP " Erzeuge Hexdump - Moment... " +ST_PROCESSCC "Bearbeite Carbon Copies" +ST_STATUSCC "CC: %s von %u:%u/%u.%u" +ST_DESTINATIONCC "Wer soll Kopien erhalten?" +MS_LISTCC "%s %u:%u/%u.%u" +WT_DELORIG " Original l”schen? " +MI_DELORIGYES "J Ja bitte. " +MI_DELORIGNO "N Nein! " +WT_DROPMSG " Mail verwerfen? " +MI_DROPMSGYES "J Ja bitte. " +MI_DROPMSGNO "N Nein! " +WT_ZONEGATE " Sende via ZoneGate? " +MI_ZONEGATEYES "J Ja bitte. " +MI_ZONEGATENO "N Nein! " +ST_QUOTEPCT "Deine Mail enth„lt %i%% Quotes%s" +WT_SAVEMSG " Speichern der %i Zeilen? " +MI_YESGREAT "J Ja klar - ist super! " +MI_KICKIT "N Nein, weg damit / ESC " +MI_CONTINUE "W Weiterschreiben " +MI_ROT13 "R ROT13 verschlsseln " +MI_ATTRS "A Attribute „ndern " +MI_ORIGS "O Origin „ndern " +MI_VIEW "L Nochmals Lesen " +ST_SELECTDESTNODE "Ziel-Node ausw„hlen" +WT_ATTACHFILES " Dateien anh„ngen " +WT_UPDREQFILES " Datei-Updaterequest " +ST_EDITHEADER "Bearbeite Header" +WT_EDITING " Editieren " +MI_INTERNALED "I Interner Editor " +MI_EXTERNALED "E Externer Editor " +MI_SAVEMESSAGE "S Speichern " +MI_ATTRO "A Attribute " +MI_TEMPLATE "V Vorlagen " +MI_ORIGIN "O Origins " +MI_QUITMESSAGE "N Nichts / ESC " +ST_TEMPLATES " Vorlagen " +WT_CHANGETEMPLATES " Standard-Vorlage „ndern " +WT_CARBONCOPY " Carbon Copy " +MI_CCPROCESS "B Bearbeiten " +MI_CCIGNORE "I Ignorieren " +MI_CCATTRIBS "A Attr. „ndern " +MI_CCLISTFMT "L Listenformat " +WT_CCLIST " CC-Liste " +MI_CCLISTKEEP "B Behalten " +MI_CCLISTNAMES "N Nur Namen " +MI_CCLISTVISIBLE "S Sichtbar " +MI_CCLISTHIDDEN "U Versteckt " +MI_CCLISTREMOVE "L L”schen " +WT_ATTRTITLE " Attribute " +MI_ATTR01 " Private Archive/Sent " +MI_ATTR02 " Crash Direct " +MI_ATTR03 " Received Zonegate " +MI_ATTR04 " Sent Hub/Host-Route " +MI_ATTR05 " File Attach Immediate " +MI_ATTR06 " Transit Xmail " +MI_ATTR07 " Orphan Erase File/Sent " +MI_ATTR08 " Kill/Sent Trunc File/Sent " +MI_ATTR09 " Local Locked " +MI_ATTR10 " Hold Confirm Rcpt Request " +MI_ATTR11 " File Request FTS1 Reserved " +MI_ATTR12 " Return Rcpt Request QBBS Reserved, Net " +MI_ATTR13 " Return Rcpt QBBS Reserved, Echo " +MI_ATTR14 " Audit Request Squish Scanned " +MI_ATTR15 " File Update Request Zap all attribs " +HD_FROM " Von : " +HD_TO " An : " +HD_SUBJ " Betr : " +HD_FILE " Datei: " +MS_EMPTYMSG "\r" +MS_AUTOATTACHMSG "\r" +MS_AUTOREQUESTMSG "\r" +MS_AUTOUPDREQMSG "\r" +WT_FILEATTACH " Datei anh„ngen " +WT_FILEREQUEST " Datei requesten " +WT_FILEUPDREQ " Datei-Updaterequest " +ST_FILEATTACHING "Dateiversand [%i/%i] an %u:%u/%u.%u" +ST_FILEREQUESTING "Dateirequest [%i/%i] bei %u:%u/%u.%u" +ST_FILEUPDREQING "Datei-Updaterequest [%i/%i] bei %u:%u/%u.%u" +ST_READMARKED "Markierte lesen - Msg %u von %u (%u brig)" +ST_READALL "Alle lesen - Msg %u von %u (%u brig)" +ST_NOQRENUM "Diese Area kann nicht renummeriert werden" +HD_VIA "via" +WT_CHANGEATTRS "Attribute „ndern" +WT_HEADERTEXT " Suchen nach (Header+Text): " +WT_HEADERONLY " Suchen nach (nur Header): " +WT_NEWAREA ">>W„hle Area: " +WT_REPLYAREA ">>Antworte in Area: " +WT_COPYAREA ">>Kopieren in Area: " +WT_MOVEAREA ">>Verschieben in Area: " +WT_FORWARDAREA ">>Weiterleiten in Area: " +WT_FREQAREA ">>Dateirequest in Area: " +WT_FREQMENUTITLE " Requestbare Dateien: " +ST_FREQSTAT "W„hle Dateien zum Request aus" +IL_FREQINFONOFILES " Keine requestbaren Dateien gefunden! " +WT_COPY " Kopieren " +WT_MOVE " Verschieben " +WT_COPYING " Kopiere.. " +WT_MOVING " Verschiebe.. " +ST_COPYINGMSG "Kopiere Mail %u von %u nach %s" +ST_MOVINGMSG "Verschiebe Mail von %u nach %s" +WT_DELETE " L”schen " +WT_DELETING " L”sche... " +ST_DELETINGMSG "L”sche Mail %u von %u" +WT_WRITE " Sichern " +WT_WRITEMSGS " Mail(s) in Datei sichern " +WT_WRITING " Sichere.. " +ST_WRITINGMSG "Sichere Mail %u von %u" +WT_WRITINGFILE " Sichere Mail(s) in Datei %s " +WT_WRITINGPRN " Drucke Mail(s) " +IL_READONLYWARN " Diese Area ist READ ONLY! " +WT_ISREADONLY " Trotzdem schreiben? " +MI_READONLYYES "J Ja bitte. " +MI_READONLYNO "N Nein! " +IL_CHANGEWARN " Die Mail stammt NICHT von Dir! " +WT_CHANGE " Trotzdem „ndern? " +MI_CHANGEYES "J Ja bitte. " +MI_CHANGENO "N Nein! " +WT_DELETETHIS " Mail l”schen? " +MI_DELETEYES "J Ja bitte. " +MI_DELETENO "N Nein! " +MI_DELETENOASK "A Alle! Frag' nicht... " +WT_GOTONEXT " Zur n„chsten Area? " +MI_GOTONEXTYES "J Ja bitte. " +MI_GOTONEXTNO "N Nein! " +MI_GOTONEXTNEW "U zur Ungelesenen Area. " +WT_FORWARD " Nutze FWD-Kludges? " +MI_FORWARDYES "J Ja bitte. " +MI_FORWARDNO "N Nein! " +WT_MSG "Msg" +WT_MSGREAL "Msg#" +WT_FROML "Von" +WT_TOL "An" +WT_SUBJL "Betr" +ST_MSGLISTER "Liste - Msg. %u von %u (%u brig)" +ST_COPYMOVEFORWARD "Kopieren, Verschieben oder Weiterleiten" +WT_SELECTACTION " Aktion " +MI_FORWARDMESSAGE "W Weiterleiten " +MI_MOVEMESSAGE "V Verschieben " +MI_COPYMESSAGE "K Kopieren " +MI_QUITCMF "N Nichts / ESC " +ST_ARE "Mails sind" +ST_IS "Mail ist" +ST_MARKED "markiert" +MI_MARKEDMSG "M Markierte " +MI_CURRENTMSG "k Aktuelle " +MI_QUITMSGS "N Nichts / ESC " +ST_WRITEMSGSTO "Mail sichern oder drucken" +WT_WRITETO " Schreiben: " +MI_DISKFILE "S Sichern " +MI_PRINTER "D Drucken " +MI_QUITWRITE "N Nichts / ESC " +ST_MARKINGOPTIONS "Mails markieren" +WT_MARKWHAT " Was Markieren? " +MI_YOURMAIL "P Pers”nliche Mail " +MI_FROMTOSUBJ "H Header (Von/An/Betr) " +MI_TEXTHDR "T Text und Header " +MI_THREAD "R Reply-Kette " +MI_NEWMSGS "n nachfolgende >aktuell " +MI_OLDMSGS "v vorhergehende zum šbergehen" +IL_READINGECHOLIST "Lese Echolist-Dateien" +IL_READINGADDRMACROS "Lese Adress-Macros" +IL_CHECKINGNODELISTS "Prfe Nodelisten" +ST_CROSSPOSTING "Crossposting in %s" +IL_TWITBLANKED " Twitmails leeren " +IL_TWITSKIPPED " Twitmails berspringen " +IL_TWITIGNORESKIP " Twitmails ignorieren und berspringen " +IL_TWITDISPLAYED " Twitmails anzeigen " +IL_TWITKILLED " Twitmails l”schen " +IL_STYLECODESNO " Hervorhebung ausgeschaltet " +IL_STYLECODESYES " Hervorhebung eingeschaltet " +IL_STYLECODESHIDE " Hervorhebung ohne Begrenzer " +ST_GENCFMRECEIPT "Erzeuge Empfangsbest„tigung" +WT_NEW "Neu" +ST_LOOKUPINFO "Nodelist-Suche: " +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" +MS_CROSSPOSTEDIN "* Crossposted in %s" +ST_STATUSLINEHELP "F1 Hilfe" +HD_OF "von" +MS_ROBOTMSG "\r--- @longpid @version\r" +ST_STATUSLINETIMEFMT "%H:%M:%S" +WT_REPLIES " Replies " +ST_SELECTREPLY "W„hle den zu lesenden Reply aus" +IL_WAITOREXIT " Hier muát du warten oder GoldED komplett beenden - Sorry! " +WT_REALLYEXIT " Wirklich beenden? " +MI_TAGLINES "T Tagline „ndern" +MI_HEADEREDIT "H Header editieren" +MI_SCANGROUP "G Gruppe durchsuchen" +WT_QWKPACKET " QWK Paket " +MI_SCANQWK "Q QWK Paket" +WT_SOUPPACKET " SOUP Paket " +MI_SCANSOUP "S SOUP Paket" +MI_SCANIMPORT "I Import" +MI_SCANEXPORT "E Export" +WT_SCANPM " Suche pers”nliche Mail " +MI_TAGLINE "g Taglines" +WT_CONFIRM " Ankunft best„tigen? " +MI_CONFIRMYES "J Ja, sende Best„tigung " +MI_CONFIRMNO "N Nein, Anfrage ablehnen " +IL_CONFIRMINFO " Der Absender erbittet Ankunftsbest„tigung (CFM) " +ST_MSG "msg" +ST_MSGS "msgs" +ST_PERSONAL "pers”nlich" +WT_GRP "Grp" +IL_FOUNDPERSONAL " %u pers”nliche Mail%s in %u Area%s gefunden " +IL_NOPERSONAL " Keine pers”nliche Mails gefunden " +ST_ESCORCONTINUE "ESC bricht ab. Jede andere: Versuche fortzusetzen." +MS_SPELLCHECKER "Rechtschreibungsprfer: %s" +WT_INS " Einf " +MI_FILELISTFROM "Dateiliste von %s" +ST_UNREGWAIT "Unregistriert - Bitte Taste drcken oder %ld Sekunden warten" +ST_INITIALIZING "Initialisiere.." +ST_CHECKING "Prfe.." +ST_LOCKSHARECAP "%s Lock/Share-Untersttzung" +WT_ATTRTURNOFF " Alt-F1 schlieát dieses Fenster " +WT_TAGLINES " Taglines " +ST_CHANGETAGLINE "Standard-Tagline „ndern" +IL_NOTAGLINE " Keine Taglines definiert. Taste drcken " +WT_CHARSETS " Zeichens„tze " +ST_CHANGEXLATIMP "Standard-Charset fr Import „ndern" +IL_NOXLATIMPORT " Keine XLATIMPORT's definiert. Taste drcken " +WT_N_A "nv." +WT_WRITTEN "Verfasst" +WT_ARRIVED "Angekommen" +WT_RECEIVED "Gelesen" +IL_NONODELIST " Kann Nodeliste oder Index nicht ”ffnen " +IL_NODELISTMISSING "Nodeliste fehlt:" +IL_NODELISTOUTDATED "Nodeliste veraltet:" +MS_REPLYLINKER "Replylinker: %s" +WT_ENTERMSGNO " Msg.-Nr eingeben: " +IL_WAITUUDECODING " Moment... UUdecodiere Nachricht " +IL_COMPLETEDUUDECODE " UUdecode von %s beendet " +IL_NOTUUENCODED " Nichts zum UUdecodieren gefunden " +IL_ERRORINSOUP " Fehler in SOUP-Datei %s " +IL_WARNALREADYSENT " ACHTUNG: Nachricht ist bereits versendet! " +IL_WAITLOCKED " Moment: %s ist geschtzt " +ST_RETRYORESC "%s Wiederholung (%lu). Um GoldED zu beenden, drcke ESC." +ST_RETRYLOCK "Geschtzt" +ST_RETRYOPEN "Verfgbar" +WT_TOUCHSEMAPHORE " Name der Semaphore eingeben " +MI_WRITETOHDRNO "H Header: Nein " +MI_WRITETOHDRYES "K Header: Ja " +MI_CLIPBOARD "C Clipboard " +WT_SELECTMARKS " Markierungsgruppe w„hlen " +WT_SELECTMARKSEDIT " Editiere Gruppenbeschreibung " +IL_DROPMARKSINFO "%s Nachrichten sind markiert " +WT_DROPMARKS " L”sche Markierungen in.. " +MI_DROPALL "A Allen Areas " +MI_DROPMARKED "M Markierten Areas " +MI_DROPCURRENT "D Dieser Area hier " +MI_NODROP "N Nichts / ESC " +WT_CATCHAREAS " Areas einholen " +MI_CATCHALL "A Alle " +MI_CATCHMARKED "M Markierte " +MI_CATCHCURRENT "D Diese hier " +MI_NOCATCH "N Nichts / ESC " + +---------------------------------------------------------------------- + diff --git a/cfgs/config/goldlang.it b/cfgs/config/goldlang.it new file mode 100644 index 0000000..8f0bc90 --- /dev/null +++ b/cfgs/config/goldlang.it @@ -0,0 +1,501 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.00 * Italian Language Definition File +// +// Translated 15-04-1999 (rev 1.00) by : Gd'A; +// e-mail : gda@cryogen.com +// +// Note : Alcune parole sono intraducibili e quindi ho preferito +// lasciarle invariate. +// Spero di aver tempo per rimettere mano a questa traduzione +// in modo da ottenere un risultato meno ridicolo! :-) +// Sicuramente ho fatto molti errori di traduzione, ogni +// segnalazione sara' ben gradita! +// +// Prima di iniziare la ridefinizione di questo file di linguaggio, +// e' consigliabile stamparlo cosi' da poterlo tenere vicino +// come testo di riferimento. +// La ridefinizione potrebbe diventare un processo lento e difficile. +// +// Il formato delle linee in questo file di linguaggio e': +// +// <"stringa"> +// +// Ogni stringa e' prefissata da una categoria, questo per +// permettere una piu' facile identificazione delle +// ridefinizioni. La stringa non differenzia tra maiuscolo e +// minuscolo. +// +// Categorie identificative: +// -------------- +// ST_ Linea di stato Lunghezza variabile. +// WT_ Titolo di finestra Lunghezza variabile. +// MI_ Voce del menu Lunghezza fissa, primo carattere QuickChar. +// IL_ Linea informativa Lunghezza variabile. +// WL_ Linea di finestra Usualmente lunghezza fissa. +// HD_ Linea dell'header Usualmente lunghezza fissa. +// MS_ Messaggio Lunghezza variabile. +// ER_ Messaggio di errore Lunghezza variabile. +// +// "Lunghezza fissa" significa che tutte le stringhe devono avere +// la medesima lunghezza. +// Effettivamente la lunghezza e' normalmente limitata solo dalla +// dimensione dello schermo. Nel caso dei menu, la larghezza della +// finestra e' sempre basata sulla lunghezza della stringa della +// *prima* voce. +// +// Il "QuickChar", all'interno di un menu, e' il carattere che viene +// mostrato come evidenziato e che e' direttamente selezionabile. +// Questo QuickChar e' sensibile all'uso delle maiuscole o minuscole +// e naturalmente deve trovare corrispondenza in una carattere che +// si trova all'interno della stringa. +// +// Le stringhe dovrebbero sempre essere racchiuse tra la virgolette +// doppie o singole ("" oppure ''). Si puo' fare eccezione a questa +// regola se la stringa non ha bisogno di spazi in testa o alla +// fine. +// +// Alcune stringhe contengono delle sequenze di "escape" o degli +// specificatori di formato cosi' come vengono utilizzati dal +// linguaggio di programmazione "C". +// Alcune espressioni provenienti da template possono essere +// utilizzate in stringhe speciali. +// +// Sequenze di escape: (sensibili alle maiuscole/minuscole!) +// ----------------------------------- +// \n - Fine riga (LF) (tradotto in CR+LF nei files). +// \r - Ritorno carrello (CR). +// +// Le sequenze di escape sono normalmente usate nelle linee +// per files oppure nei messaggi di output standard (DOS). +// +// Specificatori di formato: (sensibili alle maiuscole/minuscole!) +// ------------------------------------ +// %c - Carattere. +// %s - Stringa. +// %i - Intero. +// %u - Integero senza segno. +// %% - Il carattere percentuale (%). +// +// Se modifichi una linea che contiene uno specificatore di formato, +// fai attenzione che questi siano in numero ed ordine uguali a quanto +// specificato dall'esempio originale. +// Non seguire questa regola puo' causare degli errori imprevedibili. +// +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- NOMI DEI GIORNI DELLA SETTIMANA E DEI MESI + +// Giorni della settimana, forma breve +MS_SWSUN "Dom" +MS_SWMON "Lun" +MS_SWTUE "Mar" +MS_SWWED "Mer" +MS_SWTHU "Gio" +MS_SWFRI "Ven" +MS_SWSAT "Sab" + +// Giorni della settimana, forma lunga +MS_LWSUNDAY "Domenica" +MS_LWMONDAY "Lunedi" +MS_LWTUESDAY "Martedi" +MS_LWWEDNESDAY "Mercoledi" +MS_LWTHURSDAY "Giovedi" +MS_LWFRIDAY "Venerdi" +MS_LWSATURDAY "Sabato" + +// Mesi, forma breve +MS_SMJAN "Gen" +MS_SMFEB "Feb" +MS_SMMAR "Mar" +MS_SMAPR "Apr" +MS_SMMAY "Mag" +MS_SMJUN "Giu" +MS_SMJUL "Lug" +MS_SMAUG "Ago" +MS_SMSEP "Set" +MS_SMOCT "Ott" +MS_SMNOV "Nov" +MS_SMDEC "Dic" + +// Mesi, forma lunga +MS_LMJANUARY "Gennaio" +MS_LMFEBRUARY "Febbraio" +MS_LMMARCH "Marzo" +MS_LMAPRIL "Aprile" +MS_LMMAY "Maggio" +MS_LMJUNE "Giugno" +MS_LMJULY "Luglio" +MS_LMAUGUST "Agosto" +MS_LMSEPTEMBER "Settembre" +MS_LMOCTOBER "Ottobre" +MS_LMNOVEMBER "Novembre" +MS_LMDECEMBER "Dicembre" + + +---------------------------------------------------------------------- +-- MISCELA DI PAROLE CHIAVE + +ST_IMPORTFILE "File da importare" +WT_IMPORTWHICHFILE " Quale file importare? " +WT_IMPORTPICK " Importa " +WT_IMPORTTXT " Importa " +MI_IMPORTTXTTEXT "T File di Testo " +MI_IMPORTTXTQUOTE "Q File come Quote" +MI_IMPORTTXTUUE "U Binario in UUE " +MI_IMPORTTXTMIME "M Binario in MIME" +MI_IMPORTTXTCLIP "C da Clipboard " +MI_IMPORTTXTXLAT "s Usa Charset.. " +MI_IMPORTTXTQUIT "N Nulla / Esci " +ST_IMPORTSTATUS "Importo da %s" +ST_EXPORTFILE "Esporta File" +WT_EXPORTWHATFILE " Esporto su quale file? " +ST_EXPORTSTATUS "Esporto su %s" +ST_EDITSTATUS "Edita %i,%i. %s" +ST_SELECTFILES "Seleziona Files" +WL_SELECTEDFILES "Files Selezionati " +WL_SELECTEDBYTES " Bytes " +WL_TOTALFILES "Totale Files " +WL_TOTALBYTES " Bytes " +WL_SCANNINGDIRECTORY " Analizzo le directory " +WL_NOFILESFOUND " * NESSUN FILE TROVATO * " +ST_FILESPRESSKEY "Premi un carattere per continuare" +WT_AREA "Area" +WT_DESCRIPTION "Descrizione" +WT_MSGS "Msgs" +WT_LAST "Ultimo" +WT_ECHOID "EchoID" +ST_UNREAD "non letti" +WT_SCANAREAS " Analizzo Aree " +MI_SCANALL "A Scan All " +MI_SCANALL "A Tutte " +MI_SCANMARKED "M Selezionate " +MI_SCANCURRENT "C Corrente " +MI_SCANMATCHING "t Corrispondenti " +MI_SCANUNSCANNED "U Non analizzate " +MI_NOSCAN "N Nessuna / ESC " +WT_HEATAREAS " Seleziona Aree " +MI_HEATALL "A Tutte " +MI_HEATMARKED "M Marcate " +MI_HEATCURRENT "C Corrente " +MI_NOHEAT "N Nessuna / ESC " +WT_ZAPAREAS " Deseleziona Aree " +MI_ZAPALL "A Tutte " +MI_ZAPMARKED "M Marcate " +MI_ZAPCURRENT "C Corrente " +MI_NOZAP "N Nessuna / ESC" +MS_DOS_SHELL "GoldED Shell. Scrivi EXIT per ritornare." +IL_SCANNINGAREA " Analizzo Area:" +IL_SEARCHINGFOR " Cerca" +ST_READINGMSG "Leggo Msg %u di %u" +ER_OUTOFMEM "Fine della memoria!" +MS_HEXDUMPHEAD "Contenuto esadecimale dell'header del messaggio:" +MS_HEXDUMPTEXT "Contenuto esadecimale del corpo del messaggio:" +ST_RENUMBERING "Rinumerazione" +ST_LOCKED " (lockato)" +ST_RENUMBERED "Messaggi rinumerati - Premi un tasto" +WL_BLANKMSG "" +WL_WAIT " Stop " +IL_GENHEXDUMP " Genero l'Hexdump - Attendi " +ST_PROCESSCC "Processo le copie carbone" +ST_STATUSCC "CC: %s of %u:%u/%u.%u" +ST_DESTINATIONCC "Seleziona le destinazioni delle copie carbone" +MS_LISTCC "%s %u:%u/%u.%u" +WT_DELORIG " Cancello l'originale? " +MI_DELORIGYES "Y Si, grazie. " +MI_DELORIGNO "N No! " +WT_DROPMSG " D Elimino questo messaggio? " +MI_DROPMSGYES "Y Si, grazie. " +MI_DROPMSGNO "N No! " +WT_ZONEGATE " Spedisco via ZoneGate? " +MI_ZONEGATEYES "Y Si, grazie. " +MI_ZONEGATENO "N No! " +ST_QUOTEPCT "Il tuo messaggio contiene %i%% Quotes%s" +WT_SAVEMSG " Salvo queste %i linee? " +MI_YESGREAT "Y Si, certo! " +MI_KICKIT "N No, grazie.. / ESC " +MI_CONTINUE "C Continuo a scrivere " +MI_ROT13 "R Criptazione ROT13 " +MI_ATTRS "A Cambia gli attributi " +MI_ORIGS "O Cambia l'Origin " +MI_VIEW "V Visualizza messaggio " +ST_SELECTDESTNODE "Seleziona il nodo di destinazione" +WT_ATTACHFILES " Files Attaccati " +WT_UPDREQFILES " Aggiorna i File richiesti " +ST_EDITHEADER "Modifica i dati dell'Header" +WT_EDITING " Modifica " +MI_INTERNALED "I Editor Interno " +MI_EXTERNALED "E Editor Esterno " +MI_SAVEMESSAGE "S Salva Messaggio " +MI_ATTRO "A Attributi " +MI_TEMPLATE "T Template " +MI_ORIGIN "O Origini " +MI_QUITMESSAGE "Q Esci / ESC " +ST_TEMPLATES " Template " +WT_CHANGETEMPLATES "Cambia il Template" +WT_CARBONCOPY " Copia carbone " +MI_CCPROCESS "P Processa CC " +MI_CCIGNORE "I Ignora CC " +MI_CCATTRIBS "C Cambia Attr. " +MI_CCLISTFMT "L Mostra Form. " +WT_CCLIST " Lista CC" +MI_CCLISTKEEP "K Mantini " +MI_CCLISTNAMES "N Solo Nomi " +MI_CCLISTVISIBLE "V Visibili " +MI_CCLISTHIDDEN "H Nascosti " +MI_CCLISTREMOVE "R Rimuovi " +WT_ATTRTITLE " Attributi " +MI_ATTR01 " Privato Archiviato/Spedito " +MI_ATTR02 " Crash Diretto " +MI_ATTR03 " Ricevuto Zonegate " +MI_ATTR04 " Spedito Hub/Host-Route " +MI_ATTR05 " File attaccato Immediato " +MI_ATTR06 " In transito Xmail " +MI_ATTR07 " Orfano Erase File/Sent " +MI_ATTR08 " Kill/Sent Trunc File/Sent " +MI_ATTR09 " Locale Lockato " +MI_ATTR10 " Hold Confirm Rcpt Request " +MI_ATTR11 " Richiesta file FTS1 Reserved " +MI_ATTR12 " Return Rcpt Request QBBS Reserved, Net " +MI_ATTR13 " Return Rcpt QBBS Reserved, Echo " +MI_ATTR14 " Audit Request Squish scanned " +MI_ATTR15 " File Update Request Elimina tutti attrib " +HD_FROM " From : " +HD_TO " To : " +HD_SUBJ " Subj : " +HD_FILE " File : " +MS_EMPTYMSG "\r" +MS_AUTOATTACHMSG "\r" +MS_AUTOREQUESTMSG "\r" +MS_AUTOUPDREQMSG "\r" +WT_FILEATTACH " File Attaccato " +WT_FILEREQUEST " File Richiesto " +WT_FILEUPDREQ " Aggiorna richiesta " +ST_FILEATTACHING "File Attaccato [%i/%i] a %u:%u/%u.%u" +ST_FILEREQUESTING "File Richiesto [%i/%i] da %u:%u/%u.%u" +ST_FILEUPDREQING "Aggiona Richiesta [%i/%i] da %u:%u/%u.%u" +ST_READMARKED "Leggi Marcati - Msg %u di %u (%u ancora)" +ST_READALL "Leggi Tutti - Msg %u di %u (%u ancora)" +ST_NOQRENUM "Questa area non puo' essere renumerata" +MS_HIDINGTWIT "Questo e' un Twit Message - Premi per leggerlo." +HD_VIA "via" +WT_CHANGEATTRS "Cambia gli attributi del messaggio" +WT_HEADERTEXT " Stringa di ricerca (Header+Testo) " +WT_HEADERONLY " Stringa di ricerca (Solo Header) " +WT_NEWAREA ">>Seleziona nuova area: " +WT_REPLYAREA ">>Rispondi nell'area: " +WT_COPYAREA ">>Copia nell'area: " +WT_MOVEAREA ">>Muovi nell'area: " +WT_FORWARDAREA ">>Sposta nell'area: " +WT_FREQAREA ">>Filerequest nell'area: " +WT_FREQMENUTITLE "File richiedibili" +ST_FREQSTAT "Prendi i file richiedibili" +IL_FREQINFONOFILES " Non ci sono file richiedibili in questo messaggio! " +WT_COPY " Copia " +WT_MOVE " Muovi " +WT_COPYING " Copio " +WT_MOVING " Muovo " +ST_COPYINGMSG "Copio Msg %u di %u a %s" +ST_MOVINGMSG "Muovo Msg %u di %u a %s" +WT_DELETE " Cancella " +WT_DELETING " Cancello " +ST_DELETINGMSG "Cancello Msg %u di %u" +WT_WRITE " Scrivi " +WT_WRITEMSGS " Scrivi Msg/i sul file " +WT_WRITING " Scrivo " +ST_WRITINGMSG "Srivo Msg %u di %u" +WT_WRITINGFILE " Scrivo Msg/i sul file %s " +WT_WRITINGPRN " Stampo Msg/i " +IL_READONLYWARN " Quest'area e' in SOLA LETTURA " +WT_ISREADONLY " Scrivi comunque il messaggio? " +MI_READONLYYES "Y Si, grazie. " +MI_READONLYNO "N No! " +IL_CHANGEWARN " Questo messaggio NON proviene da te! " +WT_CHANGE " Cambia questo messaggio? " +MI_CHANGEYES "Y Si, grazie. " +MI_CHANGENO "N No! " +WT_DELETETHIS " Cancello questo messaggio? " +MI_DELETEYES "Y Si, grazie. " +MI_DELETENO "N No! " +MI_DELETENOASK "D Non chiedere.. " +WT_GOTONEXT " Prossima area? " +MI_GOTONEXTYES "Y Si, grazie. " +MI_GOTONEXTNO "N No! " +MI_GOTONEXTNEW "U Si, prossima non letta " +WT_FORWARD " Usa FWD kludges? " +MI_FORWARDYES "Y Si, grazie. " +MI_FORWARDNO "N No! " +WT_MSG "Msg" +WT_MSGREAL "Msg#" +WT_FROML "From" +WT_TOL "To" +WT_SUBJL "Subj" +ST_MSGLISTER "Lista - Msg %u di %u (%u ancora)" +ST_COPYMOVEFORWARD "Copia, Muovi or Sposta questo messaggio" +WT_SELECTACTION " Azione " +MI_FORWARDMESSAGE "F Sposta Msg " +MI_MOVEMESSAGE "M Muovi Msg " +MI_COPYMESSAGE "C Copia Msg " +MI_QUITCMF "Q Esci / ESC " +ST_ARE "messaggi sono" +ST_IS "messaggio è" +ST_MARKED "marcato" +MI_MARKEDMSG "M Msg marcati " +MI_CURRENTMSG "C Msg correnti" +MI_QUITMSGS "Q Esci / ESC " +ST_WRITEMSGSTO "Scrivi Msg/i su File o Stampante" +WT_WRITETO " Scrivi a: " +MI_DISKFILE "D Su disco " +MI_PRINTER "P Su stampante " +MI_QUITWRITE "Q Esci / ESC " +ST_MARKINGOPTIONS "Marco messaggio" +WT_MARKWHAT " Quale marco? " +MI_YOURMAIL "Y Posta personale " +MI_FROMTOSUBJ "H Header (From/To/Subj) " +MI_TEXTHDR "T Testo ed header " +MI_THREAD "R Catena delle repliche " +MI_NEWMSGS "N Nuovi msg/i > attuale " +MI_OLDMSGS "O Vecchi msg/i < attuale " +MI_ALLMSGS "A Tutti " +MI_UNMARK "U Deseleziona msg/i " +MI_RANGE "M Msg range (bookm-curr) " +MI_MARKSTOGGLE "g Inverti i marcati " +MI_QUITMARKS "Q Esci / ESC " +WT_ENTERMARKSTRING " Stringa per marcare " +ST_SEARCHINGMSG "Ricerco Msg %u di %u. Marcati: %u" +WT_USERLISTNAME " Nome del file della lista utenti? " +IL_GENUSERLIST " Lista utenti... " +WT_FILEEXISTS " Il file esiste! " +MI_APPEND "A Aggiungi alla fine " +MI_OVERWRITE "O Sovrascrivi " +MI_QUITEXIST "R Nuovo nome ESC " +IL_WARNUNSENT " ATTENZIONE! Questo messaggio NON è stato spedito!" +IL_WARNLOCKED " ATTENZIONE! Questo messaggio è in uso! " +ST_CHANGEORIGIN "Cambia l'origin di default" +WT_ORIGINS " Origini " +ST_CHANGEUSERNAME "Cambia il nome utente di default" +WT_USERNAMES " Nomi utente " +ST_CHANGEAKA "Cambia l'indizzo AKA di default" +WT_AKAS " AKA " +WT_LOOKUP " Ricerca: %s " +WL_PHONE "Telefono" +WT_QUITGOLDED " Esci da GoldED? " +MI_QUITYES "Y Si, grazie. " +MI_QUITNO "N No! " +MS_EDITCMD "Editor: %s" +IL_NOORIGDEFINED " Nessuna origin definita. Premi un tasto " +IL_NOUSERDEFINED " Nessun nome utente definito. Premi un tasto " +IL_NOAKADEFINED " Nessuna AKA definito. Premi un tasto " +IL_NOTPLDEFINED " Nessun template definito. Premi un tasto " +IL_NOTHREADLIST " Nessana catena delle repliche. Premi un tasto" +MS_SKIPPINGTWIT "Salto i messaggi Twit..." +MS_KILLINGTWIT "Cancello i messaggi Twit..." +IL_WRITINGCFG " Scrivo la configurazione " +IL_COULDNOTOPEN " Non posso aprire %s " +MS_PROMPT "Digita il comando \"EXIT\" per tornare a GoldED.\r\n" +IL_UNFINISHEDMSG " Ho trovato un messaggio NON finito! " +ST_LOADUNFINISHED "Premi un tasto per caricarlo o per ignorarlo" +IL_READINGECHOLIST "Leggo i file di Echolist " +IL_READINGADDRMACROS "Leggo le macro per gli Indirizzi" +IL_CHECKINGNODELISTS "Controllo la Nodelist" +ST_CROSSPOSTING "Crossposting in %s" +IL_TWITBLANKED " Msg/i Twit ripuliti " +IL_TWITSKIPPED " Msg/i Twit saltati " +IL_TWITIGNORESKIP " Msg/i Twit ignorati e saltati " +IL_TWITDISPLAYED " Msg/i Twit visualizzati " +IL_TWITKILLED " Msg/i Twit cancellati " +IL_STYLECODESNO " Codici di stile disabilitati " +IL_STYLECODESYES " Codici di stile abilitati " +IL_STYLECODESHIDE " Codici di stile abilitati ed eliminati " +ST_GENCFMRECEIPT "Generazione conferma di ricevimento" +WT_NEW "Nuovo" +ST_LOOKUPINFO "Informazioni di ricerca sulla Nodelist" +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" +MS_CROSSPOSTEDIN "* Crosspostato su %s" +ST_STATUSLINEHELP "F1 Aiuto" +HD_OF "of" +MS_ROBOTMSG "\r--- @longpid @version\r" +ST_STATUSLINETIMEFMT "%H:%M:%S" +WT_REPLIES " Repliche " +ST_SELECTREPLY "Seleziona le repliche che vuoi vedere" +IL_WAITOREXIT " A questo punto devi aspettare o uscire totalmente da GoldED! " +WT_REALLYEXIT " Confermi uscita? " +MI_TAGLINES "T Cambia Tagline" +MI_HEADEREDIT "H Edit Header" +MI_SCANGROUP "G Group." +WT_QWKPACKET " Paccheto QWK " +MI_SCANQWK "Q QWK Pack. " +WT_SOUPPACKET " SOUP Pack. " +MI_SCANSOUP "S SOUP Pack. " +MI_SCANIMPORT "I Import" +MI_SCANEXPORT "E Esport" +WT_SCANPM " Ricerva PM " +MI_TAGLINE "g Tagline " +WT_CONFIRM " Permetti le richieste di avvenuta conferma? " +MI_CONFIRMYES "Y Si, ma la conferma " +MI_CONFIRMNO "N No, ignorala " +IL_CONFIRMINFO " Il mittente di questo messaggio ha richiesto una conferma di ricezione (CFM) " +ST_MSG "msg" +ST_MSGS "msgs" +ST_PERSONAL "personali" +WT_GRP "Grp" +IL_FOUNDPERSONAL " Trovati %u mail personali%s in %u aree%s " +IL_NOPERSONAL " Nessuna mail personale trovata " +ST_ESCORCONTINUE "ESC per uscire. Altro tasto: Per tentare di continuare" +MS_SPELLCHECKER "SpellChecker: %s" +WT_INS " Ins " +MI_FILELISTFROM "Lista file da %s" +ST_UNREGWAIT "Non registrato - Premi un tasto oppure attendi %ld secondi" +ST_INITIALIZING "Inizializzazione ..." +ST_CHECKING "Controllo..." +ST_LOCKSHARECAP "%s caratteristica di Esclusione/Condivisione" +WT_ATTRTURNOFF " Premi Alt-F1 per chiudere questa finestra " +WT_TAGLINES " Taglines " +ST_CHANGETAGLINE "Modifica la Tagline di default" +IL_NOTAGLINE " Nessuna tagline definita. Premi un tasto " +WT_CHARSETS " Charsets " +ST_CHANGEXLATIMP "Cambia il Charset di default per l'importazione" +IL_NOXLATIMPORT " Nessun XLATIMPORT è definito. Permi un tasto " +WT_N_A "n/a" +WT_WRITTEN "Scritto" +WT_ARRIVED "Arrivato" +WT_RECEIVED "Ricevuto" +IL_NONODELIST " Non sono in grado di accedere alla nodelist o alla lista file " +IL_NODELISTMISSING "Nodelist mancante:" +IL_NODELISTOUTDATED "Nodelist scaduta:" +MS_REPLYLINKER "Replylinker: %s" +WT_ENTERMSGNO " Numero del msg " +IL_WAITUUDECODING " Attendi - decodifica del messaggio corrente " +IL_COMPLETEDUUDECODE " Ho completato la decodifica del msg %s " +IL_NOTUUENCODED " Non c'è nulla da decodificare in questo messaggio " +IL_UUEINVALIDPATH " Percorso non valido per la decodifica - file non scritto " +IL_ERRORINSOUP " Errore nel file SOUP %s " +IL_WARNALREADYSENT " Attenzione: Questo messaggio è già stato spedito! " +IL_WAITLOCKED " Attendi: %s è lockato" +ST_RETRYORESC "%s ritentativo (%lu). Premi ESC per uscire da GoldED." +ST_RETRYLOCK "Lock" +ST_RETRYOPEN "Apri" +WT_TOUCHSEMAPHORE " Indica il nome del file semaforo da aggiornare " }, +MI_WRITETOHDRNO "H Usa Header: NO " +MI_WRITETOHDRYES "H Usa Header: YES " +MI_CLIPBOARD "C Clipboard " +WT_SELECTMARKS " Seleziona marchio " +WT_SELECTMARKSEDIT " Edita la descrizone del marchio " +IL_DROPMARKSINFO " %s Messaggi sono marcati " }, +WT_DROPMARKS " Elimina Msg Marcati " +MI_DROPALL "A Elimina tutti " +MI_DROPMARKED "M Elimina marc. " +MI_DROPCURRENT "C Elimina corr. " +MI_NODROP "N Nessuna / ESC " +WT_CATCHAREAS " Raccogli aree " +MI_CATCHALL "A Raccogli tutte " +MI_CATCHMARKED "M Raccogli marc. " +MI_CATCHCURRENT "C Raccogli corr. " +MI_NOCATCH "N Nessuna / ESC " + +---------------------------------------------------------------------- + diff --git a/cfgs/config/goldlang.nl b/cfgs/config/goldlang.nl new file mode 100644 index 0000000..8b03420 --- /dev/null +++ b/cfgs/config/goldlang.nl @@ -0,0 +1,480 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.00 * Dutch Language Definition File +// +// Translated 29-03-1999 by : Cees Schouten; e-mail : wpp@dds.nl +// +// Before you start redefining the language, I suggest you print this +// file and keep it close for reference. Redefining can be a slow and +// difficult process. +// +// The format of lines in this language file is: +// +// <"string"> +// +// Each stringid is prefixed with a category, to allow easier +// identification for your own redefinitions. Not case sensitive. +// +// ID Categories: +// -------------- +// ST_ Status Line Variable length. +// WT_ Window Title Variable length. +// MI_ Menu Item Fixed length, first character QuickChar. +// IL_ Info Line Variable length. +// WL_ Window Line Usually fixed length. +// HD_ Header Line Usually fixed length. +// MS_ Message Variable length. +// ER_ Error Message Variable length. +// +// "Fixed length" means that all the strings must the same length. +// The actual length is normally only limited by the screen size. In +// case of menus, the window width is always based on the length of +// the *first* item string. +// +// A "QuickChar" is the highlighted direct-select character in the +// menu items. The QuickChar is case sensitive, and must match a +// character in the string. +// +// Strings should always be enclosed in quotes ("" or ''). The +// exception is if the string does not need leading/trailing spaces. +// +// Some strings contains escape sequences or format specifiers as +// used in the "C" language. Certain tokens from the templates can +// also be used in some special strings. +// +// Escape sequences: (Case sensitive!) +// ----------------------------------- +// \n - Line Feed (LF) (translates to CR+LF in files). +// \r - Carriage Return (CR). +// +// The escape sequences are normally used in lines for files or +// standard (DOS) output messages. +// +// Format specifiers: (Case sensitive!) +// ------------------------------------ +// %c - Character. +// %s - String. +// %i - Integer. +// %u - Unsigned Integer. +// %% - A literal percent (%) character. +// +// If you change a line with format specifiers, please be careful to +// have them in the same quantity and order as in the original +// example. Failure to do this can cause unpredictable results.. +// +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- WEEKDAY AND MONTH NAMES + +// Weekdays, short +MS_SWSUN "Zon" +MS_SWMON "Maa" +MS_SWTUE "Din" +MS_SWWED "Woe" +MS_SWTHU "Don" +MS_SWFRI "Vrij" +MS_SWSAT "Zat" + +// Weekdays, long +MS_LWSUNDAY "Zondag" +MS_LWMONDAY "Maandag" +MS_LWTUESDAY "Dinsdag" +MS_LWWEDNESDAY "Woensdag" +MS_LWTHURSDAY "Donderdag" +MS_LWFRIDAY "Vrijdag" +MS_LWSATURDAY "Zaterdag" + +// Months, short +MS_SMJAN "Jan" +MS_SMFEB "Feb" +MS_SMMAR "Maa" +MS_SMAPR "Apr" +MS_SMMAY "Mei" +MS_SMJUN "Jun" +MS_SMJUL "Jul" +MS_SMAUG "Aug" +MS_SMSEP "Sep" +MS_SMOCT "Okt" +MS_SMNOV "Nov" +MS_SMDEC "Dec" + +// Months, long +MS_LMJANUARY "Januari" +MS_LMFEBRUARY "Februari" +MS_LMMARCH "Maart" +MS_LMAPRIL "April" +MS_LMMAY "Mei" +MS_LMJUNE "Juni" +MS_LMJULY "Juli" +MS_LMAUGUST "Augustus" +MS_LMSEPTEMBER "September" +MS_LMOCTOBER "Oktober" +MS_LMNOVEMBER "November" +MS_LMDECEMBER "December" + + +---------------------------------------------------------------------- +-- MISCELLANEOUS LANGUAGE KEYWORDS + +ST_IMPORTFILE "Importeren bestand" +WT_IMPORTWHICHFILE " Importeer welk bestand? " +WT_IMPORTPICK " Importeer " +WT_IMPORTTXT " Importeer " +MI_IMPORTTXTTEXT "T Bestand als Tekst " +MI_IMPORTTXTQUOTE "Q Bestand als Quote " +MI_IMPORTTXTUUE "U Binair als UUE " +MI_IMPORTTXTMIME "M Binair als MIME " +MI_IMPORTTXTCLIP "C Van klembord " +MI_IMPORTTXTXLAT "s Gebruik karakterset.. " +MI_IMPORTTXTQUIT "N Niets / Stoppen " +ST_IMPORTSTATUS "Importeren van %s" +ST_EXPORTFILE "Exporteer Bestand" +WT_EXPORTWHATFILE " Exporteer naar welk bestand? " +ST_EXPORTSTATUS "Exporteren naar %s" +ST_EDITSTATUS "Edit %i,%i. %s" +ST_SELECTFILES "Selecteer Bestanden" +WL_SELECTEDFILES "Geselecteerde Bestanden " +WL_SELECTEDBYTES " Bytes " +WL_TOTALFILES "Totaal Bestanden " +WL_TOTALBYTES " Bytes " +WL_SCANNINGDIRECTORY " Scannen Directory " +WL_NOFILESFOUND " * GEEN BESTANDEN GEVONDEN * " +ST_FILESPRESSKEY "Druk op een willekeurige toets om verder te gaan" +WT_AREA "Gebied" +WT_DESCRIPTION "Omschrijving" +WT_MSGS "Berichten" +WT_LAST "Laatste" +WT_ECHOID "EchoID" +ST_UNREAD "ongelezen" +WT_SCANAREAS " Scan Gebieden " +MI_SCANALL "A Scan Alles " +MI_SCANMARKED "M Scan Gemarkeerd " +MI_SCANCURRENT "C Scan Huidig " +MI_SCANMATCHING "t Scan Overeenkomend " +MI_SCANUNSCANNED "U Scan Ongescanned " +MI_NOSCAN "N Geen Scan / ESC " +WT_HEATAREAS " Heat Gebieden " +MI_HEATALL "A Heat Alles " +MI_HEATMARKED "M Heat Gemarkeerd " +MI_HEATCURRENT "C Heat Huidig " +MI_NOHEAT "N Geen Heat / ESC " +WT_ZAPAREAS " Zap Gebieden " +MI_ZAPALL "A Zap Alles " +MI_ZAPMARKED "M Zap Gemarkeerd " +MI_ZAPCURRENT "C Zap Huidig " +MI_NOZAP "N Geen Zap / ESC " +MS_DOS_SHELL "GoldED Shell. Type EXIT om terug te keren." +IL_SCANNINGAREA " Scannen van Gebied:" +IL_SEARCHINGFOR " Zoeken naar:" +ST_READINGMSG "Leest Bericht %u of %u" +ER_OUTOFMEM "Out of memory!" +MS_HEXDUMPHEAD "Hexdump van bericht-header:" +MS_HEXDUMPTEXT "Hexdump van bericht-tekst:" +ST_RENUMBERING "Hernummeren" +ST_LOCKED " (locked)" +ST_RENUMBERED "Berichten hernummerd - Druk Toets" +WL_BLANKMSG "" +WL_WAIT " wacht " +IL_GENHEXDUMP " Genereerd Hexdump - Even Geduld " +ST_PROCESSCC "Verwerkt Carbon Copies" +ST_STATUSCC "CC: %s of %u:%u/%u.%u" +ST_DESTINATIONCC "Selecteer Carbon Copy Bestemming:" +MS_LISTCC "%s %u:%u/%u.%u" +WT_DELORIG " Delete het Origineel? " +MI_DELORIGYES "J Ja, Graag. " +MI_DELORIGNO "N Nee! " +WT_DROPMSG " Dit bericht laten vervallen? " +MI_DROPMSGYES "J Ja, Graag. " +MI_DROPMSGNO "N Nee! " +WT_ZONEGATE " Verzenden via ZoneGate? " +MI_ZONEGATEYES "J Ja, Graag. " +MI_ZONEGATENO "N Nee! " +ST_QUOTEPCT "Uw Bericht Bevat %i%% Quotes%s" +WT_SAVEMSG " Bewaar deze %i regels? " +MI_YESGREAT "J Ja, het is fantastisch! " +MI_KICKIT "N Nee, laat vervallen / ESC " +MI_CONTINUE "D Doorgaan met schrijven " +MI_ROT13 "R ROT13 Crypting " +MI_ATTRS "A Verander Attributen " +MI_ORIGS "O Verander Origin " +MI_VIEW "B Bekijk het Bericht " +ST_SELECTDESTNODE "Selecteer Node van Bestemming" +WT_ATTACHFILES " Bestand Meesturen " +WT_UPDREQFILES " Updaten van FileRequests " +ST_EDITHEADER "Bewerk Berichten Kop" +WT_EDITING " Bewerken " +MI_INTERNALED "I Interne Editor " +MI_EXTERNALED "E Externe Editor " +MI_SAVEMESSAGE "B Bewaar Bericht " +MI_ATTRO "A Attributen " +MI_TEMPLATE "S Sjablonen " +MI_ORIGIN "O Origins " +MI_QUITMESSAGE "T sToppen / ESC " +ST_TEMPLATES " Sjablonen " +WT_CHANGETEMPLATES "Verander Standaard Sjabloon" +WT_CARBONCOPY " Carbon Copy " +MI_CCPROCESS "V Verwerk CC's " +MI_CCIGNORE "N Negeer CC's " +MI_CCATTRIBS "V Verander Attrs " +MI_CCLISTFMT "L Lijst Formaat " +WT_CCLIST " CC Lijst " +MI_CCLISTKEEP "B Behoud " +MI_CCLISTNAMES "N Alleen Namen " +MI_CCLISTVISIBLE "Z Zichtbaar " +MI_CCLISTHIDDEN "V Verborgen " +MI_CCLISTREMOVE "W Weghalen " +WT_ATTRTITLE " Attributen " +MI_ATTR01 " Prive Archiveer na verz. " +MI_ATTR02 " Crash verzenden Direct " +MI_ATTR03 " Ontvangen Zonegate " +MI_ATTR04 " Verzonden Hub/Host-Route " +MI_ATTR05 " Bestand meesturen Immediate " +MI_ATTR06 " Transit Xmail " +MI_ATTR07 " Orphan Erase File/Sent " +MI_ATTR08 " Delete na verzenden Trunc File/Sent " +MI_ATTR09 " Lokaal Locked " +MI_ATTR10 " Hold Bevestig ontvangstbewijs " +MI_ATTR11 " File Request FTS1 Reserved " +MI_ATTR12 " Verzoek ontvangsbewijs QBBS Reserved, Net " +MI_ATTR13 " Ontvangsbevestiging QBBS Reserved, Echo " +MI_ATTR14 " Verzoek bewerken Squish Scanned " +MI_ATTR15 " File Update Request Zap all attribs " +HD_FROM " Van : " +HD_TO " Aan : " +HD_SUBJ " Ondw : " +HD_FILE " Bstd : " +MS_EMPTYMSG "\r" +MS_AUTOATTACHMSG "\r" +MS_AUTOREQUESTMSG "\r" +MS_AUTOUPDREQMSG "\r" +WT_FILEATTACH " Bestand Meesturen " +WT_FILEREQUEST " Bestand Opvragen " +WT_FILEUPDREQ " Update Verzoek " +ST_FILEATTACHING "Bestand Meesturen [%i/%i] to %u:%u/%u.%u" +ST_FILEREQUESTING "Bestand Opvragen [%i/%i] from %u:%u/%u.%u" +ST_FILEUPDREQING "Updaten Verzoek [%i/%i] from %u:%u/%u.%u" +ST_READMARKED "Lees Gemarkeerd - Msg %u of %u (%u left)" +ST_READALL "Lees Alles - Msg %u of %u (%u left)" +ST_NOQRENUM "Dit Gebied Kan Niet Hernummerd Worden" +MS_HIDINGTWIT "Dit is een Twit Bericht - Toets om te lezen." +HD_VIA "via" +WT_CHANGEATTRS "Verander Bericht Attributen" +WT_HEADERTEXT " Enter Zoekstring (Header+Tekst) " +WT_HEADERONLY " Enter Zoekstring (Alleen Header) " +WT_NEWAREA ">>Kies Nieuwe Area: " +WT_REPLYAREA ">>Antwoord In Area: " +WT_COPYAREA ">>Kopieer Naar Area: " +WT_MOVEAREA ">>Verplaats Naar Area: " +WT_FORWARDAREA ">>Doorsturen Naar Area: " +WT_FREQAREA ">>Verzoek Bestand In Area: " +WT_FREQMENUTITLE "Opvraagbare Bestanden" +ST_FREQSTAT "Kies Bestanden om op te vragen" +IL_FREQINFONOFILES " Er zijn geen opvraagbare bestanden gevonden in dit bericht! " +WT_COPY " kopieer " +WT_MOVE " verplaats " +WT_COPYING " kopieren " +WT_MOVING " verplaatsen " +ST_COPYINGMSG "kopieert Bericht %u van %u naar %s" +ST_MOVINGMSG "Verplaatst Bericht %u van %u naar %s" +WT_DELETE " Delete " +WT_DELETING " Deleten " +ST_DELETINGMSG "Delete Bericht %u van %u" +WT_WRITE " Schrijven " +WT_WRITEMSGS " Schrijft Bericht(en) naar Bestand " +WT_WRITING " Schrijven " +ST_WRITINGMSG "Schrijft Bericht %u van %u" +WT_WRITINGFILE " Schrijft Bericht(en) naar Bestand %s " +WT_WRITINGPRN " Schrijft Bericht(en) naar Printer " +IL_READONLYWARN " Deze Area is ALLEEN LEZEN! " +WT_ISREADONLY " Bericht toch schrijven? " +MI_READONLYYES "J Ja, Graag. " +MI_READONLYNO "N Nee! " +IL_CHANGEWARN " Dit Bericht is NIET van jou! " +WT_CHANGE " Verander dit Bericht? " +MI_CHANGEYES "J Ja, Graag. " +MI_CHANGENO "N Nee! " +WT_DELETETHIS " Verwijder dit Bericht? " +MI_DELETEYES "J Ja, Graag. " +MI_DELETENO "N Nee! " +MI_DELETENOASK "V Vraag maar niet... " +WT_GOTONEXT " Naar de volgende Area? " +MI_GOTONEXTYES "J Ja, Graag. " +MI_GOTONEXTNO "N Nee! " +MI_GOTONEXTNEW "U Ja, Volgende Ongelezen Area. " +WT_FORWARD " Gebruik Doorstuur kludges? " +MI_FORWARDYES "J Ja, Graag. " +MI_FORWARDNO "N Nee! " +WT_MSG "Bericht" +WT_MSGREAL "Bericht#" +WT_FROML "Van" +WT_TOL "Aan" +WT_SUBJL "Ondw" +ST_MSGLISTER "Lijstweergave - Bericht %u van %u (%u over)" +ST_COPYMOVEFORWARD "Kopieer, Verplaats of Doorsturen van dit bericht" +WT_SELECTACTION " Aktie " +MI_FORWARDMESSAGE "D Doorsturen Bericht " +MI_MOVEMESSAGE "V Verplaatsen Bericht " +MI_COPYMESSAGE "K Kopieer Bericht " +MI_QUITCMF "S Stop / ESC " +ST_ARE "berichten zijn" +ST_IS "bericht is" +ST_MARKED "marked" +MI_MARKEDMSG "M geMarkeerde Berichten " +MI_CURRENTMSG "H Huidig Bericht " +MI_QUITMSGS "S Stop / ESC " +ST_WRITEMSGSTO "schrijf Bericht(en) naar Bestand of Printer" +WT_WRITETO " Schrijf Aan: " +MI_DISKFILE "H Naar Harde schijf " +MI_PRINTER "P Print apparaat " +MI_QUITWRITE "S Stop / ESC " +ST_MARKINGOPTIONS "Berichten Markeren" +WT_MARKWHAT " Markeer Wat? " +MI_YOURMAIL "P Persoonlijke Berichten " +MI_FROMTOSUBJ "B Berichtenkop (van/Aan/Ondw) " +MI_TEXTHDR "T Tekst en berichtenkop " +MI_THREAD "R Reeks Antwoorden " +MI_NEWMSGS "N Nieuwe berichten > huidig " +MI_OLDMSGS "O Oude berichten < huidig " +MI_ALLMSGS "A Alle berichten " +MI_UNMARK "D Demarkeer alle berichten " +MI_RANGE "H Huidige bericht = huidig " +MI_MARKSTOGGLE "g behandel alle markeringen " +MI_QUITMARKS "S Stop / ESC " +WT_ENTERMARKSTRING " Geef Markeersleutel Op " +ST_SEARCHINGMSG "Zoekt Bericht %u van %u. Gemarkeerd: %u" +WT_USERLISTNAME " Gebruikerslijst bestandsnaam? " +IL_GENUSERLIST " Genereerd Gebruikerslijst " +WT_FILEEXISTS " Bestand bestaat al! " +MI_APPEND "A Toevoegen aan einde van bestand" +MI_OVERWRITE "O Overschrijf het bestand " +MI_QUITEXIST "R Re-enter bestandsnaam / ESC" +IL_WARNUNSENT " WAARSCHUWING! Dit bericht is NIET verzonden!" +IL_WARNLOCKED " WAARSCHUWING! Dit bericht is GelOcKed! " +ST_CHANGEORIGIN "Verander Standaard Origin" +WT_ORIGINS " Origins " +ST_CHANGEUSERNAME "Verander Standaard Gebruikersnaam" +WT_USERNAMES " Gebruikersnamen " +ST_CHANGEAKA "Verander Standaard Adres AKA" +WT_AKAS " AKA's " +WT_LOOKUP " Opzoeken: %s " +WL_PHONE "Telefoon" +WT_QUITGOLDED " Stoppen met GoldED? " +MI_QUITYES "J Ja, Graag. " +MI_QUITNO "N Nee! " +MS_EDITCMD "Editor: %s" +IL_NOORIGDEFINED " Geen origins gedefinieerd. Druk Toets " +IL_NOUSERDEFINED " Geen gebruikersnamen gedefinieerd. Druk Toets " +IL_NOAKADEFINED " Geen AKA's defined. Press key " +IL_NOTPLDEFINED " No templates gedefinieerd. Druk Toets " +IL_NOTHREADLIST " Sorry, geen berichtenserie beschikbaar. Druk Toets " +MS_SKIPPINGTWIT "Slaat Twit bericht over..." +MS_KILLINGTWIT "Delete Twit Bericht..." +IL_WRITINGCFG " Schrijft Configuratie weg " +IL_COULDNOTOPEN " Kon %s niet openen " +MS_PROMPT "Typ \"EXIT\" om naar GoldED terug te keren.\r\n" +IL_UNFINISHEDMSG " Niet afgemaakt bericht gevonden! " +ST_LOADUNFINISHED "Druk op een willekeurige toets om dit bericht in te laden of om het te negeren" +IL_READINGECHOLIST "Leest Echolijst Bestanden" +IL_READINGADDRMACROS "Leest Adres-macro's" +IL_CHECKINGNODELISTS "Controleert de nodelijsten" +ST_CROSSPOSTING "Crosspost in %s" +IL_TWITBLANKED " Twit Berichten Blanco gemaakt " +IL_TWITSKIPPED " Twit Berichten Overgeslagen " +IL_TWITIGNORESKIP " Twit Berichten Genegeerd en overgeslagen " +IL_TWITDISPLAYED " Twit Berichten Laten zien " +IL_TWITKILLED " Twit Berichten Gedelete " +IL_STYLECODESNO " Stylecodes uitgeschakeld " +IL_STYLECODESYES " Stylecodes ingeschakeld " +IL_STYLECODESHIDE " Stylecodes ingeschakeld en gestript " +ST_GENCFMRECEIPT "Genereren van ontvangstbevestiging" +WT_NEW "Nieuw" +ST_LOOKUPINFO "Nodelist Lookup Informatie" +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" +MS_CROSSPOSTEDIN "* Gecrosspost in %s" +ST_STATUSLINEHELP "F1 Help" +HD_OF "van" +MS_ROBOTMSG "\r--- @longpid @version\r" +ST_STATUSLINETIMEFMT "%H:%M:%S" +WT_REPLIES " Antwoorden " +ST_SELECTREPLY "Selecteer het antwoord dat je wilt zien" +IL_WAITOREXIT " Op dit punt moet je of wachten of GoldED helemaal verlaten - Sorry! " +WT_REALLYEXIT " Echt Stoppen? " +MI_TAGLINES "T Verander Tagline" +MI_HEADEREDIT "K Bewerk Kopregel" +MI_SCANGROUP "G Scan Groep" +WT_QWKPACKET " QWK Pakket " +MI_SCANQWK "Q QWK Pakket" +WT_SOUPPACKET " SOUP Pakket " +MI_SCANSOUP "S SOUP Pakket" +MI_SCANIMPORT "I Importeer" +MI_SCANEXPORT "E Exporteer" +WT_SCANPM " Scan PM " +MI_TAGLINE "g Taglines" +WT_CONFIRM " Honoreer ontvangstbevestigingen? " +MI_CONFIRMYES "J Ja, stuur een ontvangstbevestiging " +MI_CONFIRMNO "N Nee, negeer het verzoek " +IL_CONFIRMINFO " De afzender van dit bericht verzoekt om een bevestiging van ontvangst (BVO) " +ST_MSG "bericht" +ST_Msgs "Berichten" +ST_PERSONAL "persoonlijk" +WT_GRP "Groep" +IL_FOUNDPERSONAL " Vond %u persoonlijke berichten%s in %u area%s " +IL_NOPERSONAL " Geen persoonlijke berichten gevonden " +ST_ESCORCONTINUE "ESC stopt. Andere toetsen: probeert om verder te gaan" +MS_SPELLCHECKER "Spellingscontrole: %s" +WT_INS " Ins " +MI_FILELISTFROM "Bestandenlijst van %s" +ST_UNREGWAIT "ongeregistreerd - Druk een toets of wacht %ld seconden" +ST_INITIALIZING "Initializeert ..." +ST_CHECKING "Controleert" +ST_LOCKSHARECAP "%s Lock/Share Mogelijkheid" +WT_ATTRTURNOFF " Druk op Alt-F1 om dit scherm af te sluiten " +WT_TAGLINES " Taglines " +ST_CHANGETAGLINE "Veranderd Standaard Tagline" +IL_NOTAGLINE " Geen taglines gedefinieerd. Druk Toets " +WT_CHARSETS " Charsets " +ST_CHANGEXLATIMP "Change Default Import Charset" +IL_NOXLATIMPORT " Geen XLATIMPORT's gedefinieerd. Druk Toets " +WT_N_A "n/a" +WT_WRITTEN "geschreven" +WT_ARRIVED "Gearriveerd" +WT_RECEIVED "Ontvangen" +IL_NONODELIST " het was niet mogelijk om de nodelijst of het index-bestand te benaderen " +IL_NODELISTMISSING "Nodelijst ontbreekt:" +IL_NODELISTOUTDATED "Nodelijst verouderd:" +MS_REPLYLINKER "Replylinker: %s" +WT_ENTERMSGNO " Enter berichtnr " +IL_WAITUUDECODING " Wacht - uudecoderen van het huidige bericht " +IL_COMPLETEDUUDECODE " Klaar met uudecoderen van %s " +IL_NOTUUENCODED " Kon niets vinden om dit bericht mee te uudecoderen " +IL_UUEINVALIDPATH " Ongeldig pad voor het uuencoderen - bestand niet weggeschreven " +IL_ERRORINSOUP " Error in SOUP bestanden %s " +IL_WARNALREADYSENT " WAARSCHUWING: Dit bericht is al verstuurd! " +IL_WAITLOCKED " Wacht: %s is gelocked " +ST_RETRYORESC "%s poging (%lu). Druk op ESC om GoldED te verlaten." +ST_RETRYLOCK "Lock" +ST_RETRYOPEN "Open" +WT_TOUCHSEMAPHORE " Enter naam van semafoor-bestand om bij te werken " }, +MI_WRITETOHDRNO "H Gebruik Header: NEE " +MI_WRITETOHDRYES "H Gebruik Header: JA " +MI_CLIPBOARD "C Clipboard " +WT_SELECTMARKS " Selecteer Markering " +WT_SELECTMARKSEDIT " Bewerk Markering Omschrijving " +IL_DROPMARKSINFO " %s Messages Are Marked " }, +WT_DROPMARKS " Laat berichten Markeringen vervallen " +MI_DROPALL "A Laat Alles vervallen " +MI_DROPMARKED "M Laat geMarkeerde vervallen " +MI_DROPCURRENT "H Laat Hudige Vervallen " +MI_NODROP "N Niets Laten Vervallen / ESC " +WT_CATCHAREAS " Werk Areas Bij" +MI_CATCHALL "A Alles Bijwerken " +MI_CATCHMARKED "M geMarkeerde Bijwerken " +MI_CATCHCURRENT "H Hudige Bijwerken " +MI_NOCATCH "N Niets Bijwerken / ESC " + +---------------------------------------------------------------------- + diff --git a/cfgs/config/goldlang.ru2 b/cfgs/config/goldlang.ru2 new file mode 100644 index 0000000..88d1ebf --- /dev/null +++ b/cfgs/config/goldlang.ru2 @@ -0,0 +1,511 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.0.1-asa10 * ਬ¥à ä ©«  ª®­ä¨£ãà æ¨¨ ï§ëª®¢®© ¯®¤¤¥à¦ª¨ +// +// Translated 29-06-1999 (rev. 1.01) by : Alexander S. Aganichev; +// e-mail: asa@eed.miee.ru +// +// ‚ ®â«¨ç¨¥ ®â goldlang.rus ¢ í⮬ ä ©«¥ ­¥ á®åà ­¥­ë ®à¨£¨­ «ì­ë¥ +// "£®àï稥 ª« ¢¨è¨", ®¤­ ª® §  áç¥â í⮣® ­¥â ¯¥à¢®£® á⮫¡¨ª  á +// ¡ãª¢ ¬¨. —â® «ãçè¥ - à¥è âì ‚ ¬. +// +// ¥à¥¤ ¢­¥á¥­¨¥¬ ¨á¯à ¢«¥­¨© ¢ íâ®â ä ©« ¥£® ४®¬¥­¤ã¥âáï +// à á¯¥ç â âì ­  ¯à¨­â¥à¥ ¨ ¤¥à¦ âì "¯®¤ à㪮©" ¢ ª ç¥á⢥ ¯à¨¬¥à . +// ¥à¥®¯à¥¤¥«¥­¨¥ ¬®¦¥â ¡ëâì ¤®áâ â®ç­® ¤®«£¨¬ ¨ § ­ã¤­ë¬ ¯à®æ¥áᮬ. +// +// ”®à¬ â í⮣® ä ©« : +// +// <¨¤¥­â¨ä¨ª â®à> <"áâப "> +// +// Š ¦¤ë© ¨¤¥­â¨ä¨ª â®à ᮤ¥à¦¨â ¯à¥ä¨ªá, 㪠§ë¢ î騩 ­  ª â¥£®à¨î, +// çâ® ¯®§¢®«ï¥â ¡ëáâ॥ á®à¨¥­â¨à®¢ âìáï ¯à¨ ¯¥à¥®¯à¥¤¥«¥­¨¨. ‚ᥠ+// ¨¤¥­â¨ä¨ª â®àë ॣ¨áâà®­¥§ ¢¨á¨¬ë. +// +// Š â¥£®à¨¨: +// ---------- +// ST_ ‘âப  áâ áãá  ¥à¥¬¥­­ ï ¤«¨­ . +// WT_ ‡ £®«®¢®ª ®ª­  ¥à¥¬¥­­ ï ¤«¨­ . +// MI_ «¥¬¥­â ¬¥­î ”¨ªá¨à®¢ ­­ ï ¤«¨­ , ¯¥à¢ë© ᨬ¢®« +// ï¥âáï "£®àï祩 ª« ¢¨è¥©". +// IL_ ˆ­ä®à¬ æ¨®­­ ï áâப  ¥à¥¬¥­­ ï ¤«¨­ . +// WL_ ‘âப  ¢ ®ª­¥ Š ª ¯à ¢¨«® ¤«¨­  䨪á¨à®¢ ­ . +// HD_ ‘âப  § £®«®¢ª  Š ª ¯à ¢¨«® ¤«¨­  䨪á¨à®¢ ­ . +// MS_ ‘®®¡é¥­¨¥ ¥à¥¬¥­­ ï ¤«¨­ . +// ER_ ‘®®¡é¥­¨¥ ®¡ ®è¨¡ª¥ ¥à¥¬¥­­ ï ¤«¨­ . +// +// "”¨ªá¨à®¢ ­­ ï ¤«¨­ " ®§­ ç ¥â, çâ® ¢á¥ áâப¨ ¤®«¦­ë ¡ëâì +// ®¤¨­ ª®¢®© ¤«¨­ë. „«¨­  áâப¨ ®¡ëç­® ®£à ­¨ç¥­  «¨èì à §¬¥à ¬¨ +// íªà ­ . ਠᮧ¤ ­¨¨ ¬¥­î à §¬¥à ®ª­  § ¤ ¥âáï ¤«¨­®© *¯¥à¢®£®* +// í«¥¬¥­â  ¬¥­î. +// +// "ƒ®àïç ï ª« ¢¨è " íâ® ¯®¤á¢¥ç¨¢ ¥¬ë© ¢ í«¥¬¥­â¥ ¬¥­î ᨬ¢®«, +// á«ã¦ é¨© ¤«ï ¢ë¡®à  ®¯æ¨¨ ¯® ­ ¦ â¨î á®â¢¥âáâ¢ãî饩 ª« ¢¨è¨. +// "ƒ®àïç ï ª« ¢¨è " ॣ¨áâ஧ ¢¨á¨¬  ¨ ¤®«¦­  ᮮ⢥âá⢮¢ âì +// ᨬ¢®«ã ¢ áâப¥. +// +// ‘âப¨ ¤®«¦­ë ¡ëâì § ª«îç¥­ë ¢ ª ¢ë窨 ¨«¨  ¯®áâà®äë ("" ¨«¨ ''). +// ¨áª«î祭¨¥ á®áâ ¢«ïâ áâப¨, ª®â®àë¥ ­¥ âॡãîâ ®¡à ¬«ïîé¨å ⥪áâ +// ¯à®¡¥«®¢. +// +// ¥ª®â®àë¥ áâப¨ ᮤ¥à¦ â ã¯à ¢«ïî騥 ¯®á«¥¤®¢ â¥«ì­®á⨠¨«¨ +// è ¡«®­ë ä®à¬ â , ¯à¨¬¥­ï¥¬ë¥ ¢ ï§ëª¥ "C". ¥ª®â®àë¥ áâப¨ ¬®£ãâ +// ᮤ¥à¦ âì ¬ ªà®¯®¤áâ ­®¢ª¨, ¯à¨¬¥­ï¥¬ë¥ ¢ ⥬¯«¥©â å. +// +// “¯à ¢«ïî騥 ¯®á«¥¤®¢ â¥«ì­®á⨠(¥£¨áâ஧ ¢¨á¨¬ë¥!) +// --------------------------------------------------- +// \n - ¥à¥¢®¤ áâப¨ (LF) (८¡à §ã¥âáï ¢ ¯ àã CR+LF ¢ ä ©« å +// ¢ Ž‘ DOS, Windows ¨ OS/2). +// \r - ‚®§¢à â ª à¥âª¨ (CR). +// +// “¯à ¢«ïî騥 ¯®á«¥¤®¢ â¥«ì­®á⨠®¡ëç­® ¨á¯®«ì§ãîâáï ¢ á®®¡é¥­¨ïå, +// § ¯¨á뢠¥¬ëå ¢ ä ©«ë, ¨«¨ ¢ áâ ­¤ àâ­ëå á®®¡é¥­¨ïå Ž‘. +// +// ˜ ¡«®­ë ä®à¬ â  (¥£¨áâ஧ ¢¨á¨¬ë¥!) +// ------------------------------------ +// %c - ‘¨¬¢®«. +// %s - ‘âப . +// %i - –¥«®¥ ç¨á«®. +// %u - ¥§§­ ª®¢®¥ 楫®¥ ç¨á«®. +// %% - ‘¨¬¢®« ¯à®æ¥­â  (%). +// +// …᫨ ¢ë ᮡ¨à ¥â¥áì ¯®¬¥­ïâì á®®¡é¥­¨¥ á è ¡«®­®¬ ä®à¬ â¨à®¢ ­¨ï, +// â® ¡ã¤ì⥠¢­¨¬ â¥«ì­ë ¨ á®åà ­¨â¥ ª®«¨ç¥á⢮ ¨ ¯®à冷ª è ¡«®­®¢ +// ª ª ¢ ®à¨£¨­ «ì­®¬ á®®¡é¥­¨¨. ਠ­¥á®¡«î¤¥­¨¨ í⮣® ãá«®¢¨ï +// १ã«ìâ â ­¥¯à¥¤áª §ã¥¬.. +// +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- €‡‚€ˆ… „…‰ …„…‹ˆ ˆ Œ…‘Ÿ–Ž‚ + +// „­¨ ­¥¤¥«¨, ª®à®âª ï ä®à¬  +MS_SWMON "­" +MS_SWTUE "‚â" +MS_SWWED "‘à" +MS_SWTHU "—â" +MS_SWFRI "â" +MS_SWSAT "‘¡" +MS_SWSUN "‚á" + +// „­¨ ­¥¤¥«¨, ¯®«­®áâìî +MS_LWMONDAY "¯®­¥¤¥«ì­¨ª" +MS_LWTUESDAY "¢â®à­¨ª" +MS_LWWEDNESDAY "á। " +MS_LWTHURSDAY "ç¥â¢¥à£" +MS_LWFRIDAY "¯ïâ­¨æ " +MS_LWSATURDAY "áã¡¡®â " +MS_LWSUNDAY "¢®áªà¥á¥­ì¥" + +// Œ¥áïæ , ª®à®âª ï ä®à¬  +MS_SMJAN "Ÿ­¢" +MS_SMFEB "”¥¢" +MS_SMMAR "Œ à" +MS_SMAPR "€¯à" +MS_SMMAY "Œ ©" +MS_SMJUN "ˆî­" +MS_SMJUL "ˆî«" +MS_SMAUG "€¢£" +MS_SMSEP "‘¥­" +MS_SMOCT "Žªâ" +MS_SMNOV "®ï" +MS_SMDEC "„¥ª" + +// Œ¥áïæ , ¯®«­®áâìî +MS_LMJANUARY "ï­¢ àì" +MS_LMFEBRUARY "䥢ࠫì" +MS_LMMARCH "¬ àâ" +MS_LMAPRIL " ¯à¥«ì" +MS_LMMAY "¬ ©" +MS_LMJUNE "¨î­ì" +MS_LMJULY "¨î«ì" +MS_LMAUGUST " ¢£ãáâ" +MS_LMSEPTEMBER "ᥭâï¡àì" +MS_LMOCTOBER "®ªâï¡àì" +MS_LMNOVEMBER "­®ï¡àì" +MS_LMDECEMBER "¤¥ª ¡àì" + +---------------------------------------------------------------------- +-- MISCELLANEOUS LANGUAGE KEYWORDS + +ST_IMPORTFILE "‚áâ ¢ª  ä ©« " +WT_IMPORTWHICHFILE " ‚¢¥¤¨â¥ ¨¬ï ä ©«  ¤«ï ¢áâ ¢ª¨ " +WT_IMPORTPICK " ‚ë¡¥à¨â¥ ä ©« ¤«ï ¢áâ ¢ª¨ " +WT_IMPORTTXT " ‚áâ ¢ª  " +MI_IMPORTTXTTEXT "e Ž¡ëç­ë© âeªáâ®¢ë© ä ©« " +MI_IMPORTTXTQUOTE "p p¥®¡à §®¢ âì ¢ æ¨â¨à®¢ ­¨¥ " +MI_IMPORTTXTUUE "U ¥à¥ª®¤¨à®¢ âì ¢ UUE " +MI_IMPORTTXTMIME "M ¥à¥ª®¤¨à®¢ âì ¢ MIME " +MI_IMPORTTXTCLIP "y ˆ§ ¡yä¥à  ®¡¬¥­  " +MI_IMPORTTXTXLAT "a a¡®à ᨬ¢®«®¢.. " +MI_IMPORTTXTQUIT "S O⬥­  / ESC " +ST_IMPORTSTATUS "‚áâ ¢ª  ¨§ %s" +ST_EXPORTFILE "‡ ¯¨áì ¢ ä ©«" +WT_EXPORTWHATFILE " ‚¢¥¤¨â¥ ¨¬ï ä ©«  ¤«ï § ¯¨á¨ " +ST_EXPORTSTATUS "‡ ¯¨áì ¢ %s" +ST_EDITSTATUS "¥¤ ªâ¨à®¢ ­¨¥ %i,%i. %s" +WT_ATTACHFILES " à¨æ¥¯¨âì ä ©«ë " +WT_UPDREQFILES " ‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«®¢ " +ST_SELECTFILES "‚ë¡®à ä ©«®¢" +WL_SELECTEDFILES "‚ë¡à ­® ä ©«®¢ " +WL_SELECTEDBYTES " ¡ ©â " +WL_TOTALFILES "‚ᥣ® ä ©«®¢ " +WL_TOTALBYTES " ¡ ©â " +WL_SCANNINGDIRECTORY " —’…ˆ… Š€’€‹Žƒ€ " +WL_NOFILESFOUND " * ”€‰‹› … €‰„…› * " +ST_FILESPRESSKEY " ¦¬¨â¥ «î¡ãî ª« ¢¨èã" +WT_AREA "N¯/¯" +WT_DESCRIPTION "Ž¯¨á ­¨¥" +WT_MSGS "‘®®¡é¥­¨©" +WT_NEW "®¢ëå" +WT_LAST "®á«¥¤­¥¥" +WT_ECHOID "å®â £" +WT_GRP "ƒà㯯 " +ST_MSG "á®®¡é¥­¨¥" +ST_MSGS "á®®¡é¥­¨©" +ST_UNREAD "­¥ç¨â ­­ëå" +ST_PERSONAL "«¨ç­ëå" +WT_SCANAREAS " ‘ª ­¨à®¢ âì " +WT_SCANPM " ®¨áª «¨ç­ëå ¯¨á¥¬ " +MI_SCANALL "c Bc¥ " +MI_SCANMARKED "B B뤥«¥­­ë¥ " +MI_SCANCURRENT "T T¥ªãéãî " +MI_SCANMATCHING "a ‚ª«îçaî騥 ¯®¤áâபã " +MI_SCANUNSCANNED "e e᪠­¨à®¢ ­­ë¥ " +MI_SCANGROUP "y ƒày¯¯ã " +MI_SCANQWK "Q QWK ¯ ª¥âë " +MI_SCANSOUP "U SOUP ¯ ª¥âë " +WT_QWKPACKET " QWK ¯ ª¥âë " +WT_SOUPPACKET " SOUP ¯ ª¥âë " +MI_SCANIMPORT "o ˆ¬¯oàâ¨à®¢ ­¨¥ " +MI_SCANEXPORT "c ªc¯®àâ¨à®¢ ­¨¥ " +MI_NOSCAN "S O⬥­  / ESC " +WT_HEATAREAS " ®¬¥â¨âì ª ª ᪠­¨à®¢ ­­ë¥ " +MI_HEATALL "c ‚c¥ " +MI_HEATMARKED "B B뤥«¥­­ë¥ " +MI_HEATCURRENT "T T¥ªãéãî " +MI_NOHEAT "S O⬥­  / ESC " +WT_ZAPAREAS " ®¬¥â¨âì ª ª ­¥áª ­¨à®¢ ­­ë¥ " +MI_ZAPALL "c ‚c¥ " +MI_ZAPMARKED "B B뤥«¥­­ë¥ " +MI_ZAPCURRENT "T T¥ªãéãî " +MI_NOZAP "S O⬥­  / ESC " +MS_DOS_SHELL "Š®¬ ­¤­ ï áâப , ¢ë§¢ ­­ ï ¨§ GoldED. ‚¢¥¤¨â¥ EXIT ¤«ï ¢ë室 ." +IL_SCANNINGAREA " ‘ª ­¨à®¢ ­¨¥:" +IL_SEARCHINGFOR " ®¨áª" +ST_READINGMSG "‘®®¡é¥­¨¥ %u ¨§ %u" +ER_OUTOFMEM "¥¤®áâ â®ç­® ¯ ¬ïâ¨!" +MS_HEXDUMPHEAD "„ ¬¯ § £®«®¢ª :" +MS_HEXDUMPTEXT "„ ¬¯ ⥪áâ  á®®¡é¥­¨ï:" +ST_RENUMBERING "¥à¥­ã¬¥à æ¨ï" +ST_LOCKED " (§ ¡«®ª¨à®¢ ­®)" +ST_RENUMBERED "á®®¡é¥­¨ï ¯¥à¥­ã¬¥à®¢ ­ë -  ¦¬¨â¥ ª« ¢¨èã" +WL_BLANKMSG "" +WL_WAIT " ®¤®¦¤¨â¥ " +IL_GENHEXDUMP " ®¤£®â®¢ª  ¤ ¬¯  - ¯®¤®¦¤¨â¥ " +ST_PROCESSCC "Ž¡à ¡®âª  ª®¯¨©" +ST_STATUSCC "Š®¯¨à®¢ ­¨¥: %s (%u:%u/%u.%u)" +ST_DESTINATIONCC "‚ë¡¥à¨â¥  ¤à¥á â , ¯®«ãç î饣® ª®¯¨î" +MS_LISTCC "%s %u:%u/%u.%u" +WT_DELORIG " “¤ «¨âì ®à¨£¨­ «? " +MI_DELORIGYES "a „a, ®­ ¬­¥ ­¥ ­ã¦¥­ " +MI_DELORIGNO "S eâ, ï ¨å ᮡ¨à î! / ESC " +WT_DROPMSG " à®á¨âì á®®¡é¥­¨¥? " +MI_DROPMSGYES "a „a, ®­® ­¥ 㤠«®áì " +MI_DROPMSGNO "S eâ, ï ¯à®¬ § «! / ESC " +WT_ZONEGATE " ®á« âì ç¥à¥§ ¬¥¦§®­ «ì­ë© £¥©â? " +MI_ZONEGATEYES "A A ª ª ¦¥ ¨­ ç¥!? " +MI_ZONEGATENO "e eâ, ¬ë ¯®©¤¥¬ ¤à㣨¬ ¯ã⥬ " +ST_QUOTEPCT "‚ è¥ á®®¡é¥­¨¥ ᮤ¥à¦¨â %i%% æ¨â â%s" +WT_SAVEMSG " ‘®åà ­¨âì í⨠%i áâப? " +MI_YESGREAT "a „a, íâ® ªàãâ®! " +MI_KICKIT "S eâ, ¢ë¡à®áì⥠íâ®.. / ESC " +MI_CONTINUE "B B®â ⮫쪮 ¯®¯p ¢«î " +MI_ROT13 "T ‡ ªà¨¯â®¢ âì ROT13 " +MI_ATTRS "y ®¬¥­ïâì  ââਡyâë " +MI_ORIGS "p ®¬¥­ïâì op¨¤¦¨­ " +MI_VIEW "c ®c¬®âà¥âì ª ª íâ® ¡ã¤¥â " +MI_TAGLINES "e ®¬e­ïâì â £« ©­ " +MI_HEADEREDIT "o ˆ§¬¥­¨âì § £o«®¢®ª " +ST_SELECTDESTNODE "‚ë¡¥à¨â¥  ¤à¥á â " +ST_EDITHEADER "¥¤ ªâ¨à®¢ ­¨¥ § £®«®¢ª " +WT_EDITING " ¥¤ ªâ¨à®¢ ­¨¥ " +MI_INTERNALED "e ‚® ¢áâà®e­­®¬ । ªâ®à¥ " +MI_EXTERNALED "o ‚o ¢­¥è­¥¬ । ªâ®à¥ " +MI_SAVEMESSAGE "C C®åà ­¨âì á®®¡é¥­¨¥ " +MI_ATTRO "y ®¬¥­ïâì  ââਡyâë " +MI_TEMPLATE "B Bë¡à âì \"àë¡y\" " +MI_ORIGIN "p ‚ë¡à âì op¨¤¦¨­ " +MI_TAGLINE "e ®¬e­ïâì â £« ©­ " +MI_QUITMESSAGE "S Žâ¬¥­  / ESC " +ST_TEMPLATES " ‚ë¡®à \"àë¡ë\" " +WT_CHANGETEMPLATES "®¬¥­ïâì \"àë¡ã\" ¯®-㬮«ç ­¨î" +WT_CARBONCOPY " ¥â¬¥©«-ª®¯¨¨ " +MI_CCPROCESS "a ®á«aâì ª®¯¨¨ " +MI_CCIGNORE "S ¥ ¯®áë« âì ª®¯¨¨ / ESC " +MI_CCATTRIBS "y ®¬¥­ïâì  ââਡyâë " +MI_CCLISTFMT "o ‚ë¡®à ä®à¬ â  " +WT_CCLIST " ”®à¬ â " +MI_CCLISTKEEP "K K ª ­ ¯¨á ­® " +MI_CCLISTNAMES "e ˆ¬e­  ç¥à¥§ § ¯ïâãî " +MI_CCLISTVISIBLE "c ˆ¬ï ¨  ¤à¥á ¢ c⮫¡¨ª " +MI_CCLISTHIDDEN "P P §¬¥áâ¨âì ¢ ª« ¤¦ å " +MI_CCLISTREMOVE "a “¡àaâì " +WT_ATTRTITLE " €ââਡãâë ¯¨á쬠 " +MI_ATTR01 " ‹¨ç­®¥ ‡ ¡«®ª¨à®¢ ­­®¥ " +MI_ATTR02 " ‹®ª «ì­®¥ ’à ­§¨â­®¥ " +MI_ATTR03 " ®¢ë襭­ë© ¯à¨®à¨â¥â  ¯àï¬ãî " +MI_ATTR04 " ¥§ ¬¥¤«¨â¥«ì­®¥ Žáâ ¢¨âì ¤«ï § ¡®à  " +MI_ATTR05 " Žâ¯à ¢«¥­­®¥ ®«ã祭­®¥ " +MI_ATTR06 " —¥à¥§ ¬¥¦§®­ «ì­ë© £¥©â —¥à¥§ å ¡ /å®áâ " +MI_ATTR07 " ‘â¥à¥âì ä ©« ¯® ®â¯à ¢ª¥ “¤ «¨âì ¯® ®â¯à ¢ª¥ " +MI_ATTR08 " “á¥çì ä ©« ¯® ®â¯à ¢ª¥ ‚  à娢 ¯® ®â¯à ¢ª¥ " +MI_ATTR09 " ¥ ¯ ª®¢ âì (Xmail) à¨æ¥¯«¥­ ä ©« " +MI_ATTR10 " ‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«  ‡ ¯à®á ä ©«  " +MI_ATTR11 " 㦥­ ª¢¨â®ª ® ¯à®ç⥭¨¨ ‡ ¯à®á ¯à®å®¦¤¥­¨ï " +MI_ATTR12 " 㦥­ ª¢¨â®ª ® ¯®«ã祭¨¨ Š¢¨â®ª ® ¯®«ã祭¨¨ " +MI_ATTR13 " ¥§à®¤­®¥ (Orphan) FTS1 (१¥à¢) " +MI_ATTR14 " QBBS (१¥à¢), ¬ë«® QBBS (१¥à¢), íå  " +MI_ATTR15 " ‘ª ­¨à®¢ ­®¥ Squish ‘­ïâì ¢á¥ " +WT_ATTRTURNOFF "  ¦¬¨â¥ Alt-F1, ç⮡ ã¡à âì íâ® ®ª­® " +HD_FROM " Žâ : " +HD_TO " Š : " +HD_SUBJ " ’¥¬  : " +HD_FILE " ” ©« : " +MS_EMPTYMSG "\r" +MS_AUTOATTACHMSG "\r" +MS_AUTOREQUESTMSG "\r" +MS_AUTOUPDREQMSG "\r" +WT_FILEATTACH " à¨æ¥¯«¥­¨¥ ä ©«®¢ " +WT_FILEREQUEST " ‡ ¯à®á ä ©«®¢ " +WT_FILEUPDREQ " ‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«®¢ " +ST_FILEATTACHING "à¨æ¥¯«¥­¨¥ ä ©«®¢ [%i/%i] ¤«ï %u:%u/%u.%u" +ST_FILEREQUESTING "‡ ¯à®á ä ©«®¢ [%i/%i] á %u:%u/%u.%u" +ST_FILEUPDREQING "‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«®¢ [%i/%i] á %u:%u/%u.%u" +ST_READMARKED "—⥭¨¥ ¢ë¤¥«¥­­ëå - ‘®®¡é¥­¨¥ %u ¨§ %u (%u ®áâ «®áì)" +ST_READALL "—⥭¨¥ ¢á¥å - ‘®®¡é¥­¨¥ %u ¨§ %u (%u ®áâ «®áì)" +ST_NOQRENUM "â®â 䮫¤¥à ­¥«ì§ï ¯¥à¥­ã¬¥à®¢ âì" +MS_HIDINGTWIT "â® ¨¤¨®â᪮¥ á®®¡é¥­¨¥ -  ¦¬¨â¥ ¤«ï ç⥭¨ï." +HD_VIA "-->" +WT_CHANGEATTRS "ˆ§¬¥­¥­¨¥  ââਡã⮢" +WT_HEADERTEXT " ‚¢¥¤¨â¥ ¨áª®¬ãî áâபã (§ £®«®¢®ª ¨ ⥫®) " +WT_HEADERONLY " ‚¢¥¤¨â¥ ¨áª®¬ãî áâபã (⮫쪮 § £®«®¢®ª) " +WT_NEWAREA ">>‚ë¡¥à¨â¥ 䮫¤¥à: " +WT_REPLYAREA ">>Žâ¢¥â¨âì ¢ 䮫¤¥à¥: " +WT_COPYAREA ">>Š®¯¨à®¢ âì ¢ 䮫¤¥à: " +WT_MOVEAREA ">>¥à¥¬¥áâ¨âì ¢ 䮫¤¥à: " +WT_FORWARDAREA ">>¥à¥á« âì ¢ 䮫¤¥à¥: " +WT_FREQAREA ">>‡ ¯à®á¨âì ä ©« ¢ 䮫¤¥à¥: " +WT_FREQMENUTITLE "‚®§¬®¦­ë¥ ¤«ï § ¯à®á  ä ©«ë" +ST_FREQSTAT "‚ë¡¥à¨â¥ ä ©«ë ¤«ï ᮧ¤ ­¨ï § ¯à®á " +IL_FREQINFONOFILES " ‚ á®®¡é¥­¨¨ ­¥ ­ ©¤¥­® ááë«®ª ­  ä ©«ë " +WT_COPY " Š®¯¨à®¢ âì " +WT_MOVE " ¥à¥¬¥áâ¨âì " +WT_COPYING " Š®¯¨à®¢ ­¨¥ " +WT_MOVING " ¥à¥¬¥é¥­¨¥ " +ST_COPYINGMSG "Š®¯¨àã¥âáï á®®¡é¥­¨¥ %u ¨§ %u ¤«ï %s" +ST_MOVINGMSG "¥à¥¬¥é ¥âáï á®®¡é¥­¨¥ %u ¨§ %u ¤«ï %s" +WT_DELETE " “¤ «¨âì " +WT_DELETING " “¤ «¥­¨¥ " +ST_DELETINGMSG "“¤ «ï¥âáï á®®¡é¥­¨¥ %u ¨§ %u" +WT_WRITE " ‡ ¯¨áì " +WT_WRITEMSGS " ‡ ¯¨áì á®®¡é¥­¨ï(¨©) ¢ ä ©« " +WT_WRITING " ‡ ¯¨áì " +ST_WRITINGMSG "‡ ¯¨á뢠¥âáï á®®¡é¥­¨¥ %u ¨§ %u" +WT_WRITINGFILE " ‡ ¯¨áì á®®¡é¥­¨ï(¨©) ¢ ä ©« %s " +WT_WRITINGPRN " ¥ç âì á®®¡é¥­¨ï(¨©) " +IL_READONLYWARN " â®â 䮫¤¥à ’Ž‹œŠŽ „‹Ÿ —’…ˆŸ! " +WT_ISREADONLY " ‚ᥠࠢ­® § ¯¨á âì? " +MI_READONLYYES "a „a, ï ¢ ªãàá¥, § ¯¨á뢠¬ " +MI_READONLYNO "S Ž©, ᯠᨡ® çâ® ­ ¯®¬­¨«¨! / ESC " +IL_CHANGEWARN " â® á®®¡é¥­¨¥ ­ ¯¨á ­® … ‚ ¬¨! " +WT_CHANGE " ˆ§¬¥­¨âì á®®¡é¥­¨¥? " +MI_CHANGEYES "a „a, ­ ¤® ¡ë " +MI_CHANGENO "S ¥â, ï ᢮¥ ­ ©¤ã / ESC " +WT_DELETETHIS " “¤ «¨âì á®®¡é¥­¨¥? " +MI_DELETEYES "a „a, ª®­¥ç­® " +MI_DELETENO "S ¥â, ­¥ ­ ¤® / ESC " +MI_DELETENOASK "e ‚áe ¨ ¡¥§ ¢®¯à®á®¢.. " +WT_GOTONEXT " ¥à¥©â¨ ¢ ¤à㣮© 䮫¤¥à? " +MI_GOTONEXTYES "a „a, ¯®¦ «ã©áâ  " +MI_GOTONEXTNO "S ¥â, ã ¬¥­ï ¥é¥ âãâ ¤¥«  / ESC " +MI_GOTONEXTNEW "c „ , ¢ c«¥¤ãî騩 ­¥ç¨â ­­ë© " +WT_FORWARD " ˆá¯®«ì§®¢ âì ª« ¤¦¨ FWD? " +MI_FORWARDYES "a „a, ¨á¯®«ì§®¢ âì " +MI_FORWARDNO "S € § ç¥¬ ¬ãá®à¨âì? / ESC " +WT_MSG "N¯/¯" +WT_MSGREAL "N(#)" +WT_FROML "Žâ" +WT_TOL "Š" +WT_SUBJL "’¥¬ " +ST_MSGLISTER "‘¯¨á®ª - ‘®®¡é¥­¨¥ %u ¨§ %u (%u ®áâ «®áì)" +ST_COPYMOVEFORWARD "Š®¯¨à®¢ ­¨¥, ¯¥à¥¬¥é¥­¨¥ ¨ ¯¥à¥á뫪  á®®¡é¥­¨©" +WT_SELECTACTION " „¥©á⢨¥ " +MI_FORWARDMESSAGE "e eà¥á« âì á®®¡é¥­¨¥ " +MI_MOVEMESSAGE "p ¥p¥¬¥áâ¨âì á®®¡é¥­¨¥ " +MI_COPYMESSAGE "C Cª®¯¨à®¢ âì á®®¡é¥­¨¥ " +MI_QUITCMF "S Žâ¬¥­  / ESC " +ST_ARE "á®®¡é¥­¨©" +ST_IS "á®®¡é¥­¨¥" +ST_MARKED "¢ë¤¥«¥­®(ë)" +MI_MARKEDMSG "B B뤥«¥­­ë¥ á®®¡é¥­¨ï " +MI_CURRENTMSG "T T¥ªã饥 á®®¡é¥­¨¥ " +MI_QUITMSGS "S Žâ¬¥­  / ESC " +ST_WRITEMSGSTO "‡ ¯¨áì ¨«¨ ¯¥ç âì á®®¡é¥­¨ï(¨©) " +WT_WRITETO " ‘®åà ­¨âì ⥪áâ " +MI_DISKFILE "a ‡a¯¨á âì ¢ ä ©« " +MI_PRINTER "e Žâ¯à ¢¨âì ­  ¯eç âì " +MI_CLIPBOARD "o  ¯ª  o¡¬¥­  " +MI_WRITETOHDRNO "c ˆc¯®«ì§®¢ âì § £®«®¢®ª: …’ " +MI_WRITETOHDRYES "c ˆc¯®«ì§®¢ âì § £®«®¢®ª: „€ " +MI_QUITWRITE "S Žâ¬¥­  / ESC " +ST_MARKINGOPTIONS "‚뤥«¥­¨¥ á®®¡é¥­¨©" +WT_MARKWHAT " ‚ë¡¥à¨â¥ ªà¨â¥à¨© ¤«ï ¢ë¤¥«¥­¨ï " +MI_YOURMAIL "e ‹¨ç­ëe ¯¨á쬠 " +MI_FROMTOSUBJ "K o § £®«®¢ªã (Žâ/K/’¥¬ ) " +MI_TEXTHDR "c ® ⥪câã ¨ § £®«®¢ªã " +MI_THREAD "o „¥p¥¢® o⢥⮢ " +MI_NEWMSGS "> ®¢ë¥ á®®¡é¥­¨ï >⥪ã饣® " +MI_OLDMSGS "< ‘â àë¥ á®®¡é¥­¨ï <⥪ã饣® " +MI_ALLMSGS "B Bᥠᮮ¡é¥­¨ï " +MI_UNMARK "x ‘­ïâì ¢ë¤¥«¥­¨¥ á® ¢á¥x " +MI_RANGE "y „¨ ¯ §®­ (®â ¬ àª¥à  ¤® ⥪y饣®) " +MI_MARKSTOGGLE "p ˆ­¢¥àâ¨p®¢ âì ¢ë¤¥«¥­¨¥ " +MI_QUITMARKS "S Žâ¬¥­  / ESC " +WT_ENTERMARKSTRING " ‚¢¥¤¨â¥ áâபã, ¯® ª®â®à®© ¡ã¤¥â ¯à®¨§¢®¤¨âìáï ¢ë¤¥«¥­¨¥ " +ST_SEARCHINGMSG "®¨áª ¢ á®®¡é¥­¨¨ %u ¨§ %u. ‚뤥«¥­®: %u" +WT_USERLISTNAME " ‚¢¥¤¨â¥ ¨¬ï ä ©«  ¤«ï § ¯¨á¨ ᯨ᪠ ¯®«ì§®¢ â¥«¥© " +IL_GENUSERLIST " ‘®§¤ ­¨¥ ᯨ᪠ ¯®«ì§®¢ â¥«¥© " +WT_FILEEXISTS " ” ©« áãé¥áâ¢ã¥â! " +MI_APPEND "a „®¯¨áaâì ¢ ª®­¥æ " +MI_OVERWRITE "c ‡ ¯¨c âì ¯®¢¥àå " +MI_QUITEXIST "S ‚¢¥á⨠¨¬ï § ­®¢® / ESC " +IL_WARNUNSENT " …„“…†„…ˆ…! â® á®®¡é¥­¨¥ ¥é¥ … ®â¯à ¢«¥­®! " +IL_WARNLOCKED " …„“…†„…ˆ…! â® á®®¡é¥­¨¥ § ¡«®ª¨à®¢ ­®! " +ST_CHANGEORIGIN "ˆ§¬¥­¥­¨¥ ®à¨¤¦¨­  ¯® 㬮«ç ­¨î" +WT_ORIGINS " ‚ë¡¥à¨â¥ áâப㠮ਤ¦¨­  " +ST_CHANGEUSERNAME "ˆ§¬¥­¥­¨¥ ¨¬¥­¨ ¯®«ì§®¢ â¥«ï" +WT_USERNAMES " ‚ë¡¥à¨â¥ ¨¬ï ¯®«ì§®¢ â¥«ï " +ST_CHANGEAKA "ˆ§¬¥­¥­¨¥  ¤à¥á  ¯® 㬮«ç ­¨î" +WT_AKAS " €¤à¥á  " +WT_LOOKUP " ®¨áª: %s " +WL_PHONE "’¥«¥ä®­" +WT_QUITGOLDED " ‚ë©â¨ ¨§ GoldED' ? " +MI_QUITYES "a „a, ¯®à  ¨ ¯®à ¡®â âì " +MI_QUITNO "S ¥â, ï ¯à®¬ § « / ESC " +MS_EDITCMD "¥¤ ªâ®à: %s" +IL_NOORIGDEFINED " Žà¨¤¦¨­ë ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOUSERDEFINED " ˆ¬¥­  ¯®«ì§®¢ â¥«¥© ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOAKADEFINED " €¤à¥á  ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOTPLDEFINED " \"ë¡ë\" ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOTHREADLIST " ˆ§¢¨­¨â¥, ¤¥à¥¢® ®â¢¥â®¢ ­¥¤®áâ㯭®.  ¦¬¨â¥ ª« ¢¨èã " +MS_SKIPPINGTWIT "யã᪠¨¤¨®â᪨å á®®¡é¥­¨©..." +MS_KILLINGTWIT "“¤ «¥­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨©..." +IL_WRITINGCFG " ‡ ¯¨áì ª®­ä¨£ãà æ¨¨ " +IL_COULDNOTOPEN " ¥¢®§¬®¦­® ®âªàëâì %s " +MS_PROMPT "‚¢¥¤¨â¥ ª®¬ ­¤ã \"EXIT\" çâ®¡ë ¢¥à­ãâìáï ¢ GoldED.\r\n" +IL_UNFINISHEDMSG " Ž¡­ à㦥­® ­¥§ ª®­ç¥­­®¥ á®®¡é¥­¨¥! " +ST_LOADUNFINISHED " ¦¬¨â¥ «î¡ãî ª« ¢¨èã ¤«ï ¯à®¤®«¦¥­¨ï ¨«¨ ¤«ï ®â¬¥­ë " +IL_READINGECHOLIST "—⥭¨¥ ä ©«  ᯨ᪠ íå" +IL_READINGADDRMACROS "—⥭¨¥ ¬ ªà®¯®¤áâ ­®¢®ª  ¤à¥á®¢" +IL_CHECKINGNODELISTS "஢¥àª  ­®¤«¨á⮢" +ST_CROSSPOSTING "Š®¯¨à®¢ ­¨¥ ¢ %s" +IL_TWITBLANKED " ’¥«  ¨¤¨®â᪨å á®®¡é¥­¨© ­¥ ®â®¡à ¦ îâáï " +IL_TWITSKIPPED " யã᪠¨¤¨®â᪨å á®®¡é¥­¨© ­¥ ¤«ï ‚ á " +IL_TWITIGNORESKIP " ˆ£­®à¨à®¢ ­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨© " +IL_TWITDISPLAYED " Žâ®¡à ¦¥­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨© " +IL_TWITKILLED " “¤ «¥­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨© " +IL_STYLECODESNO " ‘⨫¥¢ë¥ ª®¤  ­¥ ¨á¯®«ì§ãîâáï " +IL_STYLECODESYES " ‘⨫¥¢ë¥ ª®¤  ¨á¯®«ì§ãîâáï " +IL_STYLECODESHIDE " ‘⨫¥¢ë¥ ª®¤  ¨á¯®«ì§ãîâáï ¨ ¢ë१ îâáï " +ST_GENCFMRECEIPT "‘®§¤ ­¨¥ ª¢¨âª  ® ¯à®ç⥭¨¨" +ST_LOOKUPINFO "ˆ­ä®à¬ æ¨ï ® ¯®¨áª¥ ¢ ­®¤«¨áâ¥" +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" +MS_ORIGINALLYIN "* Žà¨£¨­ « ­ ¯¨á ­ ¢ %s" +MS_CROSSPOSTEDIN "* ‘ª®¯¨à®¢ ­® ¢ %s" +ST_STATUSLINEHELP "F1 ®¤áª §ª " +HD_OF "¨§" +MS_ROBOTMSG "\r--- @longpid @version\r" +ST_STATUSLINETIMEFMT "%H:%M" + +WT_REPLIES " Žâ¢¥âë " +ST_SELECTREPLY "‚ë¡¥à¨â¥ ®â¢¥â, ª®â®àë© å®â¨â¥ ¯®á¬®âà¥âì" +IL_WAITOREXIT " ‚ë ¬®¦¥â¥ «¨¡® ¯®¤®¦¤ âì, «¨¡® ¢ë©â¨ ¨§ GoldEd'  ᮢᥬ - ˆ§¢¨­¨â¥! " +WT_REALLYEXIT " ‚ë©â¨ ¨§ ¯à®£à ¬¬ë? " +WT_CONFIRM " ®á« âì ª¢¨â®ª ® ¯à®ç⥭¨¨? " +MI_CONFIRMYES "a „a, ¯®á« âì " +MI_CONFIRMNO "S ¥â, ¨£­®à¨à®¢ âì § ¯à®á / ESC " +IL_CONFIRMINFO " €¤à¥á ­â âॡã¥â § ¯à®á  ® ¯à®ç⥭¨¨ (CFM) " +IL_FOUNDPERSONAL "  ©¤¥­® %u «¨ç­ëå á®®¡é¥­¨©%s ¢ %u 䮫¤¥à å%s " +IL_NOPERSONAL " ‹¨ç­ëå á®®¡é¥­¨© ­¥ ­ ©¤¥­® " +ST_ESCORCONTINUE "ESC - ¢ë室. Žáâ «ì­ë¥ ª­®¯ª¨ - ¯®¯ë⪠ ¯à®¤®«¦¨âì. " +MS_SPELLCHECKER "஢¥àª  ®à䮣à ä¨¨: %s" +WT_INS " ‚áâ " +MI_FILELISTFROM "‘¯¨á®ª ¨¬¥î饣®áï ã %s" +ST_INITIALIZING "ˆ­¨æ¨ «¨§ æ¨ï ..." +ST_CHECKING "஢¥àª " +ST_LOCKSHARECAP "%s ¢®§¬®¦­®á⨠ࠧ¤¥«¥­¨ï ä ©«®¢" +WT_TAGLINES " ‚ë¡¥à¨â¥ â £« ©­ " +ST_CHANGETAGLINE "ˆ§¬¥­¥­¨¥ â £« ©­  ¯® 㬮«ç ­¨î" +IL_NOTAGLINE " ’ £« ©­ë ­¥ § ¤ ­ë.  ¦¬¨â¥ ª« ¢¨èã " +WT_CHARSETS " „®áâã¯­ë¥ â ¡«¨æë ¯¥à¥ª®¤¨à®¢ª¨ " +ST_CHANGEXLATIMP "ˆ§¬¥­¥­¨¥ â ¡«¨æë ¯¥à¥ª®¤¨à®¢ª¨ ¯à¨ ¢áâ ¢ª¥" +IL_NOXLATIMPORT " ’ ¡«¨æë ¯¥àª®¤¨à®¢ª¨ ­¥ § ¤ ­ë.  ¦¬¨â¥ ª« ¢¨èã " +WT_N_A "n/a" +WT_WRITTEN " ¯¨á ­®" +WT_ARRIVED "®«ã祭®" +WT_RECEIVED "à®ç⥭®" +IL_NONODELIST " ˆ­¤¥ªáë ­®¤«¨áâ  ­¥¤®áâ㯭ë " +IL_NODELISTMISSING "Žâáãâáâ¢ã¥â ­®¤«¨áâ:" +IL_NODELISTOUTDATED "®¤«¨áâ ãáâ à¥«:" +MS_REPLYLINKER "‹¨­ª®¢é¨ª ®â¢¥â®¢: %s" +WT_ENTERMSGNO " ‚¢¥¤¨â¥ ­®¬¥à á®®¡é¥­¨ï " +IL_WAITUUDECODING " ®¤®¦¤¨â¥ - ¤¥ª®¤¨àã¥âáï UUE ¨§ ⥪ã饣® á®®¡é¥­¨ï " +IL_COMPLETEDUUDECODE " ‡ ª®­ç¥­® ¤¥ª®¤¨à®¢ ­¨¥ %s " +IL_NOTUUENCODED " ¨ç¥£® ¯®å®¦¥£® ­  UUE ­¥ ­ ©¤¥­® " +IL_UUEINVALIDPATH " ¥ª®à४â­ë© ¯ãâì ¤«ï § ¯¨á¨ ¤¥ª®¤¨à®¢ ­­ëå ä ©«®¢ - ä ©« ­¥ § ¯¨á ­ " +IL_PATHREPORT " ‘®§¤ ­¨¥ ä ©«  ¯ã⨠¯à®å®¦¤¥­¨ï á®®¡é¥­¨© " +IL_ERRORINSOUP " Žè¨¡ª  ¢ SOUP ¯ ª¥â¥ %s " +IL_WARNALREADYSENT " ।ã¯à¥¦¤¥­¨¥: â® á®®¡é¥­¨¥ 㦥 ®â¯à ¢«¥­®! " +IL_WAITLOCKED " ®¤®¦¤¨â¥: %s § ¡«®ª¨à®¢ ­ " +ST_RETRYORESC "%s ¯®¯ë⪠ (%lu).  ¦¬¨â¥ ESC çâ®¡ë ¢ë©â¨ ¨§ GoldED' ." +ST_RETRYLOCK "«®ª¨à®¢ ­¨¥" +ST_RETRYOPEN "Žâªàë⨥" +WT_TOUCHSEMAPHORE " ‚¢¥¤¨â¥ ¨¬ï ä ©« -ᥬ ä®à  ¤«ï ®¡­®¢«¥­¨ï ¤ âë " +WT_SELECTMARKS " ‚ë¡®à £àã¯¯ë ¢ë¤¥«¥­­ëå á®®¡é¥­¨© " +WT_SELECTMARKSEDIT " ¥¤ ªâ¨à®¢ ­¨¥ ®¯¨á ­¨ï ¢ë¤¥«¥­­ëå á®®¡é¥­¨© " +IL_DROPMARKSINFO " %s á®®¡é¥­¨© ¯®¬¥ç¥­® " +WT_DROPMARKS " ‘­ïâì ¢ë¤¥«¥­¨¥ á á®®¡é¥­¨©? " +MI_DROPALL "e ‘­ïâì ¢o ¢áeå 䮫¤¥à å " +MI_DROPMARKED "C C­ïâì ¢ ¢ë¤e«¥­­ëå 䮫¤¥à å " +MI_DROPCURRENT "y C­ïâì ¢ ⥪y饬 䮫¤¥à¥ " +MI_NODROP "S Žâ¬¥­  / ESC " +WT_CATCHAREAS " ®¬¥â¨âì ª ª ¯à®ç⥭­ë¥? " +MI_CATCHALL "e ®¬¥â¨âì ¢áe " +MI_CATCHMARKED "o o¬¥â¨âì ¢ë¤¥«¥­­ë¥ " +MI_CATCHCURRENT "y ®¬¥â¨âì ⥪yéãî " +MI_NOCATCH "S Žâ¬¥­  / ESC " +WT_CROSSPOST " å®-ª®¯¨¨ " +MI_XCPROCESS "c ®c« âì ª®¯¨¨ " +MI_XCIGNORE "e He ¯®áë« âì ª®¯¨¨ " +MI_XCLISTFMT "B Bë¡®à ä®à¬ â  " +WT_XCLIST " ”®à¬ â " +MI_XCLISTRAW "K K ª ­ ¯¨á ­® " +MI_XCLISTVERBOSE "c ˆ¬ï ¨  ¤à¥á ¢ c⮫¡¨ª " +MI_XCLISTLINE "a ˆ¬¥­a ç¥à¥§ § ¯ïâãî " +MI_XCLISTREMOVE "p “¡p âì " + +WT_ADDRESSBOOK " €¤à¥á­ ï ª­¨£  " +WT_ADVANCEDSEARCH "  áè¨à¥­­ë© ¯®¨áª " +IL_NOMOREMATCHES " ®«ìè¥ á®¢¯ ¤¥­¨© ­¥ ­ ©¤¥­® " +WT_HEADEREDITHELP1 " #F10: ­®¤«¨áâ " +WT_HEADEREDITHELP2 " F10:  ¤à¥á­ ï ª­¨£  " +WT_THREADLISTTITLE " „¥à¥¢® ®â¢¥â®¢ " +WT_ADVANCEDMARKING "  áè¨à¥­­®¥ ¢ë¤¥«¥­¨¥ " +ST_USERSTATUSLINE "€¤à¥á­ ï ª­¨£  GoldED'  - %d ¨§ %d (%d ®áâ «®áì)" +WT_USERHEADERNAME "ˆ¬ï" +WT_USERHEADERORG "Žà£ ­¨§ æ¨ï" +WT_USERHEADERAKA "€¤à¥á" +IL_USERWAIT " ®¤®¦¤¨â¥ - ¨¤¥â ¯®¨áª ¢  ¤à¥á­®© ª­¨£¥... " diff --git a/cfgs/config/goldlang.rus b/cfgs/config/goldlang.rus new file mode 100644 index 0000000..51dfca1 --- /dev/null +++ b/cfgs/config/goldlang.rus @@ -0,0 +1,509 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.0.1-asa10 * ਬ¥à ä ©«  ª®­ä¨£ãà æ¨¨ ï§ëª®¢®© ¯®¤¤¥à¦ª¨ +// +// Translated 29-06-1999 (rev. 1.00) by : Alexander S. Aganichev; +// e-mail: asa@eed.miee.ru +// +// ¥à¥¤ ¢­¥á¥­¨¥¬ ¨á¯à ¢«¥­¨© ¢ íâ®â ä ©« ¥£® ४®¬¥­¤ã¥âáï +// à á¯¥ç â âì ­  ¯à¨­â¥à¥ ¨ ¤¥à¦ âì "¯®¤ à㪮©" ¢ ª ç¥á⢥ ¯à¨¬¥à . +// ¥à¥®¯à¥¤¥«¥­¨¥ ¬®¦¥â ¡ëâì ¤®áâ â®ç­® ¤®«£¨¬ ¨ § ­ã¤­ë¬ ¯à®æ¥áᮬ. +// +// ”®à¬ â í⮣® ä ©« : +// +// <¨¤¥­â¨ä¨ª â®à> <"áâப "> +// +// Š ¦¤ë© ¨¤¥­â¨ä¨ª â®à ᮤ¥à¦¨â ¯à¥ä¨ªá, 㪠§ë¢ î騩 ­  ª â¥£®à¨î, +// çâ® ¯®§¢®«ï¥â ¡ëáâ॥ á®à¨¥­â¨à®¢ âìáï ¯à¨ ¯¥à¥®¯à¥¤¥«¥­¨¨. ‚ᥠ+// ¨¤¥­â¨ä¨ª â®àë ॣ¨áâà®­¥§ ¢¨á¨¬ë. +// +// Š â¥£®à¨¨: +// ---------- +// ST_ ‘âப  áâ áãá  ¥à¥¬¥­­ ï ¤«¨­ . +// WT_ ‡ £®«®¢®ª ®ª­  ¥à¥¬¥­­ ï ¤«¨­ . +// MI_ «¥¬¥­â ¬¥­î ”¨ªá¨à®¢ ­­ ï ¤«¨­ , ¯¥à¢ë© ᨬ¢®« +// ï¥âáï "£®àï祩 ª« ¢¨è¥©". +// IL_ ˆ­ä®à¬ æ¨®­­ ï áâப  ¥à¥¬¥­­ ï ¤«¨­ . +// WL_ ‘âப  ¢ ®ª­¥ Š ª ¯à ¢¨«® ¤«¨­  䨪á¨à®¢ ­ . +// HD_ ‘âப  § £®«®¢ª  Š ª ¯à ¢¨«® ¤«¨­  䨪á¨à®¢ ­ . +// MS_ ‘®®¡é¥­¨¥ ¥à¥¬¥­­ ï ¤«¨­ . +// ER_ ‘®®¡é¥­¨¥ ®¡ ®è¨¡ª¥ ¥à¥¬¥­­ ï ¤«¨­ . +// +// "”¨ªá¨à®¢ ­­ ï ¤«¨­ " ®§­ ç ¥â, çâ® ¢á¥ áâப¨ ¤®«¦­ë ¡ëâì +// ®¤¨­ ª®¢®© ¤«¨­ë. „«¨­  áâப¨ ®¡ëç­® ®£à ­¨ç¥­  «¨èì à §¬¥à ¬¨ +// íªà ­ . ਠᮧ¤ ­¨¨ ¬¥­î à §¬¥à ®ª­  § ¤ ¥âáï ¤«¨­®© *¯¥à¢®£®* +// í«¥¬¥­â  ¬¥­î. +// +// "ƒ®àïç ï ª« ¢¨è " íâ® ¯®¤á¢¥ç¨¢ ¥¬ë© ¢ í«¥¬¥­â¥ ¬¥­î ᨬ¢®«, +// á«ã¦ é¨© ¤«ï ¢ë¡®à  ®¯æ¨¨ ¯® ­ ¦ â¨î á®â¢¥âáâ¢ãî饩 ª« ¢¨è¨. +// "ƒ®àïç ï ª« ¢¨è " ॣ¨áâ஧ ¢¨á¨¬  ¨ ¤®«¦­  ᮮ⢥âá⢮¢ âì +// ᨬ¢®«ã ¢ áâப¥. +// +// ‘âப¨ ¤®«¦­ë ¡ëâì § ª«îç¥­ë ¢ ª ¢ë窨 ¨«¨  ¯®áâà®äë ("" ¨«¨ ''). +// ¨áª«î祭¨¥ á®áâ ¢«ïâ áâப¨, ª®â®àë¥ ­¥ âॡãîâ ®¡à ¬«ïîé¨å ⥪áâ +// ¯à®¡¥«®¢. +// +// ¥ª®â®àë¥ áâப¨ ᮤ¥à¦ â ã¯à ¢«ïî騥 ¯®á«¥¤®¢ â¥«ì­®á⨠¨«¨ +// è ¡«®­ë ä®à¬ â , ¯à¨¬¥­ï¥¬ë¥ ¢ ï§ëª¥ "C". ¥ª®â®àë¥ áâப¨ ¬®£ãâ +// ᮤ¥à¦ âì ¬ ªà®¯®¤áâ ­®¢ª¨, ¯à¨¬¥­ï¥¬ë¥ ¢ ⥬¯«¥©â å. +// +// “¯à ¢«ïî騥 ¯®á«¥¤®¢ â¥«ì­®á⨠(¥£¨áâ஧ ¢¨á¨¬ë¥!) +// --------------------------------------------------- +// \n - ¥à¥¢®¤ áâப¨ (LF) (८¡à §ã¥âáï ¢ ¯ àã CR+LF ¢ ä ©« å +// ¢ Ž‘ DOS, Windows ¨ OS/2). +// \r - ‚®§¢à â ª à¥âª¨ (CR). +// +// “¯à ¢«ïî騥 ¯®á«¥¤®¢ â¥«ì­®á⨠®¡ëç­® ¨á¯®«ì§ãîâáï ¢ á®®¡é¥­¨ïå, +// § ¯¨á뢠¥¬ëå ¢ ä ©«ë, ¨«¨ ¢ áâ ­¤ àâ­ëå á®®¡é¥­¨ïå Ž‘. +// +// ˜ ¡«®­ë ä®à¬ â  (¥£¨áâ஧ ¢¨á¨¬ë¥!) +// ------------------------------------ +// %c - ‘¨¬¢®«. +// %s - ‘âப . +// %i - –¥«®¥ ç¨á«®. +// %u - ¥§§­ ª®¢®¥ 楫®¥ ç¨á«®. +// %% - ‘¨¬¢®« ¯à®æ¥­â  (%). +// +// …᫨ ¢ë ᮡ¨à ¥â¥áì ¯®¬¥­ïâì á®®¡é¥­¨¥ á è ¡«®­®¬ ä®à¬ â¨à®¢ ­¨ï, +// â® ¡ã¤ì⥠¢­¨¬ â¥«ì­ë ¨ á®åà ­¨â¥ ª®«¨ç¥á⢮ ¨ ¯®à冷ª è ¡«®­®¢ +// ª ª ¢ ®à¨£¨­ «ì­®¬ á®®¡é¥­¨¨. ਠ­¥á®¡«î¤¥­¨¨ í⮣® ãá«®¢¨ï +// १ã«ìâ â ­¥¯à¥¤áª §ã¥¬.. +// +////////////////////////////////////////////////////////////////////// + + +---------------------------------------------------------------------- +-- €‡‚€ˆ… „…‰ …„…‹ˆ ˆ Œ…‘Ÿ–Ž‚ + +// „­¨ ­¥¤¥«¨, ª®à®âª ï ä®à¬  +MS_SWMON "­" +MS_SWTUE "‚â" +MS_SWWED "‘à" +MS_SWTHU "—â" +MS_SWFRI "â" +MS_SWSAT "‘¡" +MS_SWSUN "‚á" + +// „­¨ ­¥¤¥«¨, ¯®«­®áâìî +MS_LWMONDAY "¯®­¥¤¥«ì­¨ª" +MS_LWTUESDAY "¢â®à­¨ª" +MS_LWWEDNESDAY "á। " +MS_LWTHURSDAY "ç¥â¢¥à£" +MS_LWFRIDAY "¯ïâ­¨æ " +MS_LWSATURDAY "áã¡¡®â " +MS_LWSUNDAY "¢®áªà¥á¥­ì¥" + +// Œ¥áïæ , ª®à®âª ï ä®à¬  +MS_SMJAN "Ÿ­¢" +MS_SMFEB "”¥¢" +MS_SMMAR "Œ à" +MS_SMAPR "€¯à" +MS_SMMAY "Œ ©" +MS_SMJUN "ˆî­" +MS_SMJUL "ˆî«" +MS_SMAUG "€¢£" +MS_SMSEP "‘¥­" +MS_SMOCT "Žªâ" +MS_SMNOV "®ï" +MS_SMDEC "„¥ª" + +// Œ¥áïæ , ¯®«­®áâìî +MS_LMJANUARY "ï­¢ àì" +MS_LMFEBRUARY "䥢ࠫì" +MS_LMMARCH "¬ àâ" +MS_LMAPRIL " ¯à¥«ì" +MS_LMMAY "¬ ©" +MS_LMJUNE "¨î­ì" +MS_LMJULY "¨î«ì" +MS_LMAUGUST " ¢£ãáâ" +MS_LMSEPTEMBER "ᥭâï¡àì" +MS_LMOCTOBER "®ªâï¡àì" +MS_LMNOVEMBER "­®ï¡àì" +MS_LMDECEMBER "¤¥ª ¡àì" + +---------------------------------------------------------------------- +-- MISCELLANEOUS LANGUAGE KEYWORDS + +ST_IMPORTFILE "‚áâ ¢ª  ä ©« " +WT_IMPORTWHICHFILE " ‚¢¥¤¨â¥ ¨¬ï ä ©«  ¤«ï ¢áâ ¢ª¨ " +WT_IMPORTPICK " ‚ë¡¥à¨â¥ ä ©« ¤«ï ¢áâ ¢ª¨ " +WT_IMPORTTXT " ‚áâ ¢ª  " +MI_IMPORTTXTTEXT "T T Ž¡ëç­ë© ⥪áâ®¢ë© ä ©« " +MI_IMPORTTXTQUOTE "Q Q ८¡à §®¢ âì ¢ æ¨â¨à®¢ ­¨¥ " +MI_IMPORTTXTUUE "U U ¥à¥ª®¤¨à®¢ âì ¢ UUE " +MI_IMPORTTXTMIME "M M ¥à¥ª®¤¨à®¢ âì ¢ MIME " +MI_IMPORTTXTCLIP "C C ˆ§ ¡ãä¥à  ®¡¬¥­  " +MI_IMPORTTXTXLAT "S S  ¡®à ᨬ¢®«®¢.. " +MI_IMPORTTXTQUIT "N N Žâ¬¥­  / ESC " +ST_IMPORTSTATUS "‚áâ ¢ª  ¨§ %s" +ST_EXPORTFILE "‡ ¯¨áì ¢ ä ©«" +WT_EXPORTWHATFILE " ‚¢¥¤¨â¥ ¨¬ï ä ©«  ¤«ï § ¯¨á¨ " +ST_EXPORTSTATUS "‡ ¯¨áì ¢ %s" +ST_EDITSTATUS "¥¤ ªâ¨à®¢ ­¨¥ %i,%i. %s" +WT_ATTACHFILES " à¨æ¥¯¨âì ä ©«ë " +WT_UPDREQFILES " ‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«®¢ " +ST_SELECTFILES "‚ë¡®à ä ©«®¢" +WL_SELECTEDFILES "‚ë¡à ­® ä ©«®¢ " +WL_SELECTEDBYTES " ¡ ©â " +WL_TOTALFILES "‚ᥣ® ä ©«®¢ " +WL_TOTALBYTES " ¡ ©â " +WL_SCANNINGDIRECTORY " —’…ˆ… Š€’€‹Žƒ€ " +WL_NOFILESFOUND " * ”€‰‹› … €‰„…› * " +ST_FILESPRESSKEY " ¦¬¨â¥ «î¡ãî ª« ¢¨èã" +WT_AREA "N¯/¯" +WT_DESCRIPTION "Ž¯¨á ­¨¥" +WT_MSGS "‘®®¡é¥­¨©" +WT_NEW "®¢ëå" +WT_LAST "®á«¥¤­¥¥" +WT_ECHOID "å®â £" +WT_GRP "ƒà㯯 " +ST_MSG "á®®¡é¥­¨¥" +ST_MSGS "á®®¡é¥­¨©" +ST_UNREAD "­¥ç¨â ­­ëå" +ST_PERSONAL "«¨ç­ëå" +WT_SCANAREAS " ‘ª ­¨à®¢ âì " +WT_SCANPM " ®¨áª «¨ç­ëå ¯¨á¥¬ " +MI_SCANALL "A A ‚ᥠ" +MI_SCANMARKED "M M ‚뤥«¥­­ë¥ " +MI_SCANCURRENT "C C ’¥ªãéãî " +MI_SCANMATCHING "t t ‚ª«îç î騥 ¯®¤áâபã " +MI_SCANUNSCANNED "U U ¥áª ­¨à®¢ ­­ë¥ " +MI_SCANGROUP "G G ƒà㯯ã " +MI_SCANQWK "Q Q QWK ¯ ª¥âë " +MI_SCANSOUP "S S SOUP ¯ ª¥âë " +WT_QWKPACKET " QWK ¯ ª¥âë " +WT_SOUPPACKET " SOUP ¯ ª¥âë " +MI_SCANIMPORT "I I ˆ¬¯®àâ¨à®¢ ­¨¥ " +MI_SCANEXPORT "E E ªá¯®àâ¨à®¢ ­¨¥ " +MI_NOSCAN "N N Žâ¬¥­  / ESC " +WT_HEATAREAS " ®¬¥â¨âì ª ª ᪠­¨à®¢ ­­ë¥ " +MI_HEATALL "A A ‚ᥠ" +MI_HEATMARKED "M M ‚뤥«¥­­ë¥ " +MI_HEATCURRENT "C C ’¥ªãéãî " +MI_NOHEAT "N N Žâ¬¥­  / ESC " +WT_ZAPAREAS " ®¬¥â¨âì ª ª ­¥áª ­¨à®¢ ­­ë¥ " +MI_ZAPALL "A A ‚ᥠ" +MI_ZAPMARKED "M M ‚뤥«¥­­ë¥ " +MI_ZAPCURRENT "C C ’¥ªãéãî " +MI_NOZAP "N N Žâ¬¥­  / ESC " +MS_DOS_SHELL "Š®¬ ­¤­ ï áâப , ¢ë§¢ ­­ ï ¨§ GoldED. ‚¢¥¤¨â¥ EXIT ¤«ï ¢ë室 ." +IL_SCANNINGAREA " ‘ª ­¨à®¢ ­¨¥:" +IL_SEARCHINGFOR " ®¨áª" +ST_READINGMSG "‘®®¡é¥­¨¥ %u ¨§ %u" +ER_OUTOFMEM "¥¤®áâ â®ç­® ¯ ¬ïâ¨!" +MS_HEXDUMPHEAD "„ ¬¯ § £®«®¢ª :" +MS_HEXDUMPTEXT "„ ¬¯ ⥪áâ  á®®¡é¥­¨ï:" +ST_RENUMBERING "¥à¥­ã¬¥à æ¨ï" +ST_LOCKED " (§ ¡«®ª¨à®¢ ­®)" +ST_RENUMBERED "á®®¡é¥­¨ï ¯¥à¥­ã¬¥à®¢ ­ë -  ¦¬¨â¥ ª« ¢¨èã" +WL_BLANKMSG "" +WL_WAIT " ®¤®¦¤¨â¥ " +IL_GENHEXDUMP " ®¤£®â®¢ª  ¤ ¬¯  - ¯®¤®¦¤¨â¥ " +ST_PROCESSCC "Ž¡à ¡®âª  ª®¯¨©" +ST_STATUSCC "Š®¯¨à®¢ ­¨¥: %s (%u:%u/%u.%u)" +ST_DESTINATIONCC "‚ë¡¥à¨â¥  ¤à¥á â , ¯®«ãç î饣® ª®¯¨î" +MS_LISTCC "%s %u:%u/%u.%u" +WT_DELORIG " “¤ «¨âì ®à¨£¨­ «? " +MI_DELORIGYES "Y Y „ , ®­ ¬­¥ ­¥ ­ã¦¥­ " +MI_DELORIGNO "N N ¥â, ï ¨å ᮡ¨à î! " +WT_DROPMSG " à®á¨âì á®®¡é¥­¨¥? " +MI_DROPMSGYES "Y Y „ , ®­® ­¥ 㤠«®áì " +MI_DROPMSGNO "N N ¥â, ï ¯à®¬ § «! " +WT_ZONEGATE " ®á« âì ç¥à¥§ ¬¥¦§®­ «ì­ë© £¥©â? " +MI_ZONEGATEYES "Y Y € ª ª ¦¥ ¨­ ç¥!? " +MI_ZONEGATENO "N N ¥â, ¬ë ¯®©¤¥¬ ¤à㣨¬ ¯ã⥬ " +ST_QUOTEPCT "‚ è¥ á®®¡é¥­¨¥ ᮤ¥à¦¨â %i%% æ¨â â%s" +WT_SAVEMSG " ‘®åà ­¨âì í⨠%i áâப? " +MI_YESGREAT "Y Y „ , íâ® ªàãâ®! " +MI_KICKIT "N N ¥â, ¢ë¡à®áì⥠íâ®.. / ESC " +MI_CONTINUE "C C ‚®â ⮫쪮 ¯®¯à ¢«î " +MI_ROT13 "R R ‡ ªà¨¯â®¢ âì ROT13 " +MI_ATTRS "A A ®¬¥­ïâì  ââਡãâë " +MI_ORIGS "O O ®¬¥­ïâì ®à¨¤¦¨­ " +MI_VIEW "V V ®á¬®âà¥âì ª ª íâ® ¡ã¤¥â " +MI_TAGLINE "G G ®¬¥­ïâì â £« ©­" +MI_TAGLINES "T T ®¬¥­ïâì â £« ©­" +MI_HEADEREDIT "H H ˆ§¬¥­¨âì § £®«®¢®ª" +ST_SELECTDESTNODE "‚ë¡¥à¨â¥  ¤à¥á â " +ST_EDITHEADER "¥¤ ªâ¨à®¢ ­¨¥ § £®«®¢ª " +WT_EDITING " ¥¤ ªâ¨à®¢ ­¨¥ " +MI_INTERNALED "I I ‚® ¢áâ஥­­®¬ । ªâ®à¥ " +MI_EXTERNALED "E E ‚® ¢­¥è­¥¬ । ªâ®à¥ " +MI_SAVEMESSAGE "S S ‘®åà ­¨âì á®®¡é¥­¨¥ " +MI_ATTRO "A A ®¬¥­ïâì  ââਡãâë " +MI_TEMPLATE "T T ‚ë¡à âì "àë¡ã" " +MI_ORIGIN "O O ‚ë¡à âì ®à¨¤¦¨­ " +MI_QUITMESSAGE "Q Q Žâ¬¥­  / ESC " +ST_TEMPLATES " ‚ë¡®à "àë¡ë" " +WT_CHANGETEMPLATES "®¬¥­ïâì "àë¡ã" ¯®-㬮«ç ­¨î" +WT_CARBONCOPY " ¥â¬¥©«-ª®¯¨¨ " +MI_CCPROCESS "P P ®á« âì ª®¯¨¨ " +MI_CCIGNORE "I I ¥ ¯®áë« âì ª®¯¨¨ " +MI_CCATTRIBS "C C ®¬¥­ïâì  ââਡãâë " +MI_CCLISTFMT "L L ‚ë¡®à ä®à¬ â  " +WT_CCLIST " ”®à¬ â " +MI_CCLISTKEEP "K K Š ª ­ ¯¨á ­® " +MI_CCLISTNAMES "N N ˆ¬¥­  ç¥à¥§ § ¯ïâãî " +MI_CCLISTVISIBLE "V V ˆ¬ï ¨  ¤à¥á ¢ á⮫¡¨ª " +MI_CCLISTHIDDEN "H H  §¬¥áâ¨âì ¢ ª« ¤¦ å " +MI_CCLISTREMOVE "R R “¡à âì " +WT_ATTRTITLE " €ââਡãâë ¯¨á쬠 " +MI_ATTR01 " ‹¨ç­®¥ ‡ ¡«®ª¨à®¢ ­­®¥ " +MI_ATTR02 " ‹®ª «ì­®¥ ’à ­§¨â­®¥ " +MI_ATTR03 " ®¢ë襭­ë© ¯à¨®à¨â¥â  ¯àï¬ãî " +MI_ATTR04 " ¥§ ¬¥¤«¨â¥«ì­®¥ Žáâ ¢¨âì ¤«ï § ¡®à  " +MI_ATTR05 " Žâ¯à ¢«¥­­®¥ ®«ã祭­®¥ " +MI_ATTR06 " —¥à¥§ ¬¥¦§®­ «ì­ë© £¥©â —¥à¥§ å ¡ /å®áâ " +MI_ATTR07 " ‘â¥à¥âì ä ©« ¯® ®â¯à ¢ª¥ “¤ «¨âì ¯® ®â¯à ¢ª¥ " +MI_ATTR08 " “á¥çì ä ©« ¯® ®â¯à ¢ª¥ ‚  à娢 ¯® ®â¯à ¢ª¥ " +MI_ATTR09 " ¥ ¯ ª®¢ âì (Xmail) à¨æ¥¯«¥­ ä ©« " +MI_ATTR10 " ‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«  ‡ ¯à®á ä ©«  " +MI_ATTR11 " 㦥­ ª¢¨â®ª ® ¯à®ç⥭¨¨ ‡ ¯à®á ¯à®å®¦¤¥­¨ï " +MI_ATTR12 " 㦥­ ª¢¨â®ª ® ¯®«ã祭¨¨ Š¢¨â®ª ® ¯®«ã祭¨¨ " +MI_ATTR13 " ¥§à®¤­®¥ (Orphan) FTS1 (१¥à¢) " +MI_ATTR14 " QBBS (१¥à¢), ¬ë«® QBBS (१¥à¢), íå  " +MI_ATTR15 " ‘ª ­¨à®¢ ­®¥ Squish ‘­ïâì ¢á¥ " +WT_ATTRTURNOFF "  ¦¬¨â¥ Alt-F1, ç⮡ ã¡à âì íâ® ®ª­® " +HD_FROM " Žâ : " +HD_TO " Š : " +HD_SUBJ " ’¥¬  : " +HD_FILE " ” ©« : " +MS_EMPTYMSG "\r" +MS_AUTOATTACHMSG "\r" +MS_AUTOREQUESTMSG "\r" +MS_AUTOUPDREQMSG "\r" +WT_FILEATTACH " à¨æ¥¯«¥­¨¥ ä ©«®¢ " +WT_FILEREQUEST " ‡ ¯à®á ä ©«®¢ " +WT_FILEUPDREQ " ‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«®¢ " +ST_FILEATTACHING "à¨æ¥¯«¥­¨¥ ä ©«®¢ [%i/%i] ¤«ï %u:%u/%u.%u" +ST_FILEREQUESTING "‡ ¯à®á ä ©«®¢ [%i/%i] á %u:%u/%u.%u" +ST_FILEUPDREQING "‡ ¯à®á ®¡­®¢«¥­¨ï ä ©«®¢ [%i/%i] á %u:%u/%u.%u" +ST_READMARKED "—⥭¨¥ ¢ë¤¥«¥­­ëå - ‘®®¡é¥­¨¥ %u ¨§ %u (%u ®áâ «®áì)" +ST_READALL "—⥭¨¥ ¢á¥å - ‘®®¡é¥­¨¥ %u ¨§ %u (%u ®áâ «®áì)" +ST_NOQRENUM "â®â 䮫¤¥à ­¥«ì§ï ¯¥à¥­ã¬¥à®¢ âì" +MS_HIDINGTWIT "â® ¨¤¨®â᪮¥ á®®¡é¥­¨¥ -  ¦¬¨â¥ ¤«ï ç⥭¨ï." +HD_VIA "-->" +WT_CHANGEATTRS "ˆ§¬¥­¥­¨¥  ââਡã⮢" +WT_HEADERTEXT " ‚¢¥¤¨â¥ ¨áª®¬ãî áâபã (§ £®«®¢®ª ¨ ⥫®) " +WT_HEADERONLY " ‚¢¥¤¨â¥ ¨áª®¬ãî áâபã (⮫쪮 § £®«®¢®ª) " +WT_NEWAREA ">>‚ë¡¥à¨â¥ 䮫¤¥à: " +WT_REPLYAREA ">>Žâ¢¥â¨âì ¢ 䮫¤¥à¥: " +WT_COPYAREA ">>Š®¯¨à®¢ âì ¢ 䮫¤¥à: " +WT_MOVEAREA ">>¥à¥¬¥áâ¨âì ¢ 䮫¤¥à: " +WT_FORWARDAREA ">>¥à¥á« âì ¢ 䮫¤¥à¥: " +WT_FREQAREA ">>‡ ¯à®á¨âì ä ©« ¢ 䮫¤¥à¥: " +WT_FREQMENUTITLE "‚®§¬®¦­ë¥ ¤«ï § ¯à®á  ä ©«ë" +ST_FREQSTAT "‚ë¡¥à¨â¥ ä ©«ë ¤«ï ᮧ¤ ­¨ï § ¯à®á " +IL_FREQINFONOFILES " ‚ á®®¡é¥­¨¨ ­¥ ­ ©¤¥­® ááë«®ª ­  ä ©«ë " +WT_COPY " Š®¯¨à®¢ âì " +WT_MOVE " ¥à¥¬¥áâ¨âì " +WT_COPYING " Š®¯¨à®¢ ­¨¥ " +WT_MOVING " ¥à¥¬¥é¥­¨¥ " +ST_COPYINGMSG "Š®¯¨àã¥âáï á®®¡é¥­¨¥ %u ¨§ %u ¤«ï %s" +ST_MOVINGMSG "¥à¥¬¥é ¥âáï á®®¡é¥­¨¥ %u ¨§ %u ¤«ï %s" +WT_DELETE " “¤ «¨âì " +WT_DELETING " “¤ «¥­¨¥ " +ST_DELETINGMSG "“¤ «ï¥âáï á®®¡é¥­¨¥ %u ¨§ %u" +WT_WRITE " ‡ ¯¨áì " +WT_WRITEMSGS " ‡ ¯¨áì á®®¡é¥­¨ï(¨©) ¢ ä ©« " +WT_WRITING " ‡ ¯¨áì " +ST_WRITINGMSG "‡ ¯¨á뢠¥âáï á®®¡é¥­¨¥ %u ¨§ %u" +WT_WRITINGFILE " ‡ ¯¨áì á®®¡é¥­¨ï(¨©) ¢ ä ©« %s " +WT_WRITINGPRN " ¥ç âì á®®¡é¥­¨ï(¨©) " +IL_READONLYWARN " â®â 䮫¤¥à ’Ž‹œŠŽ „‹Ÿ —’…ˆŸ! " +WT_ISREADONLY " ‚ᥠࠢ­® § ¯¨á âì? " +MI_READONLYYES "Y Y „ , ï ¢ ªãàá¥, § ¯¨á뢠¬ " +MI_READONLYNO "N N Ž©, ᯠᨡ® çâ® ­ ¯®¬­¨«¨! " +IL_CHANGEWARN " â® á®®¡é¥­¨¥ ­ ¯¨á ­® … ‚ ¬¨! " +WT_CHANGE " ˆ§¬¥­¨âì á®®¡é¥­¨¥? " +MI_CHANGEYES "Y Y „ , ­ ¤® ¡ë " +MI_CHANGENO "N N ¥â, ï ᢮¥ ­ ©¤ã " +WT_DELETETHIS " “¤ «¨âì á®®¡é¥­¨¥? " +MI_DELETEYES "Y Y „ , ª®­¥ç­® " +MI_DELETENO "N N ¥â, ­¥ ­ ¤® " +MI_DELETENOASK "D D ‚ᥠ¨ ¡¥§ ¢®¯à®á®¢.. " +WT_GOTONEXT " ¥à¥©â¨ ¢ ¤à㣮© 䮫¤¥à? " +MI_GOTONEXTYES "Y Y „ , ¯®¦ «ã©áâ  " +MI_GOTONEXTNO "N N ¥â, ã ¬¥­ï ¥é¥ âãâ ¤¥«  " +MI_GOTONEXTNEW "U U „ , ¢ á«¥¤ãî騩 ­¥ç¨â ­­ë© " +WT_FORWARD " ˆá¯®«ì§®¢ âì ª« ¤¦¨ FWD? " +MI_FORWARDYES "Y Y „ , ¨á¯®«ì§®¢ âì " +MI_FORWARDNO "N N € § ç¥¬ ¬ãá®à¨âì? " +WT_MSG "N¯/¯" +WT_MSGREAL "N(#)" +WT_FROML "Žâ" +WT_TOL "Š" +WT_SUBJL "’¥¬ " +ST_MSGLISTER "‘¯¨á®ª - ‘®®¡é¥­¨¥ %u ¨§ %u (%u ®áâ «®áì)" +ST_COPYMOVEFORWARD "Š®¯¨à®¢ ­¨¥, ¯¥à¥¬¥é¥­¨¥ ¨ ¯¥à¥á뫪  á®®¡é¥­¨©" +WT_SELECTACTION " „¥©á⢨¥ " +MI_FORWARDMESSAGE "F F ¥à¥á« âì á®®¡é¥­¨¥ " +MI_MOVEMESSAGE "M M ¥à¥¬¥áâ¨âì á®®¡é¥­¨¥ " +MI_COPYMESSAGE "C C ‘ª®¯¨à®¢ âì á®®¡é¥­¨¥ " +MI_QUITCMF "Q Q Žâ¬¥­  / ESC " +ST_ARE "á®®¡é¥­¨©" +ST_IS "á®®¡é¥­¨¥" +ST_MARKED "¢ë¤¥«¥­®(ë)" +MI_MARKEDMSG "M M ‚뤥«¥­­ë¥ á®®¡é¥­¨ï " +MI_CURRENTMSG "C C ’¥ªã饥 á®®¡é¥­¨¥ " +MI_QUITMSGS "Q Q Žâ¬¥­  / ESC " +ST_WRITEMSGSTO "‡ ¯¨áì ¨«¨ ¯¥ç âì á®®¡é¥­¨ï(¨©) " +WT_WRITETO " ‘®åà ­¨âì ⥪áâ " +MI_DISKFILE "D D ‡ ¯¨á âì ¢ ä ©« " +MI_PRINTER "P P Žâ¯à ¢¨âì ­  ¯¥ç âì " +MI_CLIPBOARD "C C  ¯ª  ®¡¬¥­  " +MI_WRITETOHDRNO "H H ˆá¯®«ì§®¢ âì § £®«®¢®ª: …’ " +MI_WRITETOHDRYES "H H ˆá¯®«ì§®¢ âì § £®«®¢®ª: „€ " +MI_QUITWRITE "Q Q Žâ¬¥­  / ESC " +ST_MARKINGOPTIONS "‚뤥«¥­¨¥ á®®¡é¥­¨©" +WT_MARKWHAT " ‚ë¡¥à¨â¥ ªà¨â¥à¨© ¤«ï ¢ë¤¥«¥­¨ï " +MI_YOURMAIL "Y Y ‹¨ç­ë¥ ¯¨á쬠 " +MI_FROMTOSUBJ "H H ® § £®«®¢ªã (Žâ/Š/’¥¬ ) " +MI_TEXTHDR "T T ® ⥪áâã ¨ § £®«®¢ªã " +MI_THREAD "R R „¥à¥¢® ®â¢¥â®¢ " +MI_NEWMSGS "N N ®¢ë¥ á®®¡é¥­¨ï >⥪ã饣® " +MI_OLDMSGS "O O ‘â àë¥ á®®¡é¥­¨ï <⥪ã饣® " +MI_ALLMSGS "A A ‚ᥠᮮ¡é¥­¨ï " +MI_UNMARK "U U ‘­ïâì ¢ë¤¥«¥­¨¥ á® ¢á¥å " +MI_RANGE "M M „¨ ¯ §®­ (®â ¬ àª¥à  ¤® ⥪ã饣®) " +MI_MARKSTOGGLE "G G ˆ­¢¥àâ¨à®¢ âì ¢ë¤¥«¥­¨¥ " +MI_QUITMARKS "Q Q Žâ¬¥­  / ESC " +WT_ENTERMARKSTRING " ‚¢¥¤¨â¥ áâபã, ¯® ª®â®à®© ¡ã¤¥â ¯à®¨§¢®¤¨âìáï ¢ë¤¥«¥­¨¥ " +ST_SEARCHINGMSG "®¨áª ¢ á®®¡é¥­¨¨ %u ¨§ %u. ‚뤥«¥­®: %u" +WT_USERLISTNAME " ‚¢¥¤¨â¥ ¨¬ï ä ©«  ¤«ï § ¯¨á¨ ᯨ᪠ ¯®«ì§®¢ â¥«¥© " +IL_GENUSERLIST " ‘®§¤ ­¨¥ ᯨ᪠ ¯®«ì§®¢ â¥«¥© " +WT_FILEEXISTS " ” ©« áãé¥áâ¢ã¥â! " +MI_APPEND "A A „®¯¨á âì ¢ ª®­¥æ " +MI_OVERWRITE "O O ‡ ¯¨á âì ¯®¢¥àå " +MI_QUITEXIST "R R ‚¢¥á⨠¨¬ï § ­®¢® / ESC " +IL_WARNUNSENT " …„“…†„…ˆ…! â® á®®¡é¥­¨¥ ¥é¥ … ®â¯à ¢«¥­®! " +IL_WARNLOCKED " …„“…†„…ˆ…! â® á®®¡é¥­¨¥ § ¡«®ª¨à®¢ ­®! " +ST_CHANGEORIGIN "ˆ§¬¥­¥­¨¥ ®à¨¤¦¨­  ¯® 㬮«ç ­¨î" +WT_ORIGINS " ‚ë¡¥à¨â¥ áâப㠮ਤ¦¨­  " +ST_CHANGEUSERNAME "ˆ§¬¥­¥­¨¥ ¨¬¥­¨ ¯®«ì§®¢ â¥«ï" +WT_USERNAMES " ‚ë¡¥à¨â¥ ¨¬ï ¯®«ì§®¢ â¥«ï " +ST_CHANGEAKA "ˆ§¬¥­¥­¨¥  ¤à¥á  ¯® 㬮«ç ­¨î" +WT_AKAS " €¤à¥á  " +WT_LOOKUP " ®¨áª: %s " +WL_PHONE "’¥«¥ä®­" +WT_QUITGOLDED " ‚ë©â¨ ¨§ GoldED' ? " +MI_QUITYES "Y Y „ , ¯®à  ¨ ¯®à ¡®â âì " +MI_QUITNO "N N ¥â, ï ¯à®¬ § « " +MS_EDITCMD "¥¤ ªâ®à: %s" +IL_NOORIGDEFINED " Žà¨¤¦¨­ë ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOUSERDEFINED " ˆ¬¥­  ¯®«ì§®¢ â¥«¥© ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOAKADEFINED " €¤à¥á  ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOTPLDEFINED " "ë¡ë" ­¥ ®¯à¥¤¥«¥­ë.  ¦¬¨â¥ ª« ¢¨èã " +IL_NOTHREADLIST " ˆ§¢¨­¨â¥, ¤¥à¥¢® ®â¢¥â®¢ ­¥¤®áâ㯭®.  ¦¬¨â¥ ª« ¢¨èã " +MS_SKIPPINGTWIT "யã᪠¨¤¨®â᪨å á®®¡é¥­¨©..." +MS_KILLINGTWIT "“¤ «¥­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨©..." +IL_WRITINGCFG " Writing Configuration " +IL_COULDNOTOPEN " Couldn't open %s " +IL_WRITINGCFG " ‡ ¯¨áì ª®­ä¨£ãà æ¨¨ " +IL_COULDNOTOPEN " ¥¢®§¬®¦­® ®âªàëâì %s " +MS_PROMPT "‚¢¥¤¨â¥ ª®¬ ­¤ã \"EXIT\" çâ®¡ë ¢¥à­ãâìáï ¢ GoldED.\r\n" +IL_UNFINISHEDMSG " Ž¡­ à㦥­® ­¥§ ª®­ç¥­­®¥ á®®¡é¥­¨¥! " +ST_LOADUNFINISHED " ¦¬¨â¥ «î¡ãî ª« ¢¨èã ¤«ï ¯à®¤®«¦¥­¨ï ¨«¨ ¤«ï ®â¬¥­ë " +IL_READINGECHOLIST "—⥭¨¥ ä ©«  ᯨ᪠ íå" +IL_READINGADDRMACROS "—⥭¨¥ ¬ ªà®¯®¤áâ ­®¢®ª  ¤à¥á®¢" +IL_CHECKINGNODELISTS "஢¥àª  ­®¤«¨á⮢" +ST_CROSSPOSTING "Š®¯¨à®¢ ­¨¥ ¢ %s" +IL_TWITBLANKED " ’¥«  ¨¤¨®â᪨å á®®¡é¥­¨© ­¥ ®â®¡à ¦ îâáï " +IL_TWITSKIPPED " யã᪠¨¤¨®â᪨å á®®¡é¥­¨© ­¥ ¤«ï ‚ á " +IL_TWITIGNORESKIP " ˆ£­®à¨à®¢ ­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨© " +IL_TWITDISPLAYED " Žâ®¡à ¦¥­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨© " +IL_TWITKILLED " “¤ «¥­¨¥ ¨¤¨®â᪨å á®®¡é¥­¨© " +IL_STYLECODESNO " ‘⨫¥¢ë¥ ª®¤  ­¥ ¨á¯®«ì§ãîâáï " +IL_STYLECODESYES " ‘⨫¥¢ë¥ ª®¤  ¨á¯®«ì§ãîâáï " +IL_STYLECODESHIDE " ‘⨫¥¢ë¥ ª®¤  ¨á¯®«ì§ãîâáï ¨ ¢ë१ îâáï " +ST_GENCFMRECEIPT "‘®§¤ ­¨¥ ª¢¨âª  ® ¯à®ç⥭¨¨" +ST_LOOKUPINFO "ˆ­ä®à¬ æ¨ï ® ¯®¨áª¥ ¢ ­®¤«¨áâ¥" +MS_DATETIMEFMT "%d %b %y %H:%M:%S" +MS_DATEFMT "%d %b %y" +MS_TIMEFMT "%H:%M" +MS_ORIGINALLYIN "* Žà¨£¨­ « ­ ¯¨á ­ ¢ %s" +MS_CROSSPOSTEDIN "* ‘ª®¯¨à®¢ ­® ¢ %s" +ST_STATUSLINEHELP "F1 ®¤áª §ª " +HD_OF "¨§" +MS_ROBOTMSG "\r--- @longpid @version\r" +ST_STATUSLINETIMEFMT "%H:%M" + +WT_REPLIES " Žâ¢¥âë " +ST_SELECTREPLY "‚ë¡¥à¨â¥ ®â¢¥â, ª®â®àë© å®â¨â¥ ¯®á¬®âà¥âì" +IL_WAITOREXIT " ‚ë ¬®¦¥â¥ «¨¡® ¯®¤®¦¤ âì, «¨¡® ¢ë©â¨ ¨§ GoldEd'  ᮢᥬ - ˆ§¢¨­¨â¥! " +WT_REALLYEXIT " ‚ë©â¨ ¨§ ¯à®£à ¬¬ë? " +WT_CONFIRM " ®á« âì ª¢¨â®ª ® ¯à®ç⥭¨¨? " +MI_CONFIRMYES "Y Y „ , ¯®á« âì " +MI_CONFIRMNO "N N ¥â, ¨£­®à¨à®¢ âì § ¯à®á " +IL_CONFIRMINFO " €¤à¥á ­â âॡã¥â § ¯à®á  ® ¯à®ç⥭¨¨ (CFM) " +IL_FOUNDPERSONAL "  ©¤¥­® %u «¨ç­ëå á®®¡é¥­¨©%s ¢ %u 䮫¤¥à å%s " +IL_NOPERSONAL " ‹¨ç­ëå á®®¡é¥­¨© ­¥ ­ ©¤¥­® " +ST_ESCORCONTINUE "ESC - ¢ë室. Žáâ «ì­ë¥ ª­®¯ª¨ - ¯®¯ë⪠ ¯à®¤®«¦¨âì. " +MS_SPELLCHECKER "஢¥àª  ®à䮣à ä¨¨: %s" +WT_INS " ‚áâ " +MI_FILELISTFROM "‘¯¨á®ª ¨¬¥î饣®áï ã %s" +ST_INITIALIZING "ˆ­¨æ¨ «¨§ æ¨ï ..." +ST_CHECKING "஢¥àª " +ST_LOCKSHARECAP "%s ¢®§¬®¦­®á⨠ࠧ¤¥«¥­¨ï ä ©«®¢" +WT_TAGLINES " ‚ë¡¥à¨â¥ â £« ©­ " +ST_CHANGETAGLINE "ˆ§¬¥­¥­¨¥ â £« ©­  ¯® 㬮«ç ­¨î" +IL_NOTAGLINE " ’ £« ©­ë ­¥ § ¤ ­ë.  ¦¬¨â¥ ª« ¢¨èã " +WT_CHARSETS " „®áâã¯­ë¥ â ¡«¨æë ¯¥à¥ª®¤¨à®¢ª¨ " +ST_CHANGEXLATIMP "ˆ§¬¥­¥­¨¥ â ¡«¨æë ¯¥à¥ª®¤¨à®¢ª¨ ¯à¨ ¢áâ ¢ª¥" +IL_NOXLATIMPORT " ’ ¡«¨æë ¯¥àª®¤¨à®¢ª¨ ­¥ § ¤ ­ë.  ¦¬¨â¥ ª« ¢¨èã " +WT_N_A "n/a" +WT_WRITTEN " ¯¨á ­®" +WT_ARRIVED "®«ã祭®" +WT_RECEIVED "à®ç⥭®" +IL_NONODELIST " ˆ­¤¥ªáë ­®¤«¨áâ  ­¥¤®áâ㯭ë " +IL_NODELISTMISSING "Žâáãâáâ¢ã¥â ­®¤«¨áâ:" +IL_NODELISTOUTDATED "®¤«¨áâ ãáâ à¥«:" +MS_REPLYLINKER "‹¨­ª®¢é¨ª ®â¢¥â®¢: %s" +WT_ENTERMSGNO " ‚¢¥¤¨â¥ ­®¬¥à á®®¡é¥­¨ï " +IL_WAITUUDECODING " ®¤®¦¤¨â¥ - ¤¥ª®¤¨àã¥âáï UUE ¨§ ⥪ã饣® á®®¡é¥­¨ï " +IL_COMPLETEDUUDECODE " ‡ ª®­ç¥­® ¤¥ª®¤¨à®¢ ­¨¥ %s " +IL_NOTUUENCODED " ¨ç¥£® ¯®å®¦¥£® ­  UUE ­¥ ­ ©¤¥­® " +IL_UUEINVALIDPATH " ¥ª®à४â­ë© ¯ãâì ¤«ï § ¯¨á¨ ¤¥ª®¤¨à®¢ ­­ëå ä ©«®¢ - ä ©« ­¥ § ¯¨á ­ " +IL_PATHREPORT " ‘®§¤ ­¨¥ ä ©«  ¯ã⨠¯à®å®¦¤¥­¨ï á®®¡é¥­¨© " +IL_ERRORINSOUP " Žè¨¡ª  ¢ SOUP ¯ ª¥â¥ %s " +IL_WARNALREADYSENT " ।ã¯à¥¦¤¥­¨¥: â® á®®¡é¥­¨¥ 㦥 ®â¯à ¢«¥­®! " +IL_WAITLOCKED " ®¤®¦¤¨â¥: %s § ¡«®ª¨à®¢ ­ " +ST_RETRYORESC "%s ¯®¯ë⪠ (%lu).  ¦¬¨â¥ ESC çâ®¡ë ¢ë©â¨ ¨§ GoldED' ." +ST_RETRYLOCK "«®ª¨à®¢ ­¨¥" +ST_RETRYOPEN "Žâªàë⨥" +WT_TOUCHSEMAPHORE " ‚¢¥¤¨â¥ ¨¬ï ä ©« -ᥬ ä®à  ¤«ï ®¡­®¢«¥­¨ï ¤ âë " +WT_SELECTMARKS " ‚ë¡®à £àã¯¯ë ¢ë¤¥«¥­­ëå á®®¡é¥­¨© " +WT_SELECTMARKSEDIT " ¥¤ ªâ¨à®¢ ­¨¥ ®¯¨á ­¨ï ¢ë¤¥«¥­­ëå á®®¡é¥­¨© " +IL_DROPMARKSINFO " %s á®®¡é¥­¨© ¯®¬¥ç¥­® " +WT_DROPMARKS " ‘­ïâì ¢ë¤¥«¥­¨¥ á á®®¡é¥­¨©? " +MI_DROPALL "A A ‘­ïâì ¢® ¢á¥å 䮫¤¥à å " +MI_DROPMARKED "M M ‘­ïâì ¢ ¢ë¤¥«¥­­ëå 䮫¤¥à å " +MI_DROPCURRENT "C C ‘­ïâì ¢ ⥪ã饬 䮫¤¥à¥ " +MI_NODROP "N N Žâ¬¥­  / ESC " +WT_CATCHAREAS " ®¬¥â¨âì ª ª ¯à®ç⥭­ë¥? " +MI_CATCHALL "A A ®¬¥â¨âì ¢á¥ " +MI_CATCHMARKED "M M ®¬¥â¨âì ¢ë¤¥«¥­­ë¥ " +MI_CATCHCURRENT "C C ®¬¥â¨âì ⥪ãéãî " +MI_NOCATCH "N N Žâ¬¥­  / ESC " +WT_CROSSPOST " å®-ª®¯¨¨ " +MI_XCPROCESS "P P ®á« âì ª®¯¨¨ " +MI_XCIGNORE "I I ¥ ¯®áë« âì ª®¯¨¨ " +MI_XCLISTFMT "L L ‚ë¡®à ä®à¬ â  " +WT_XCLIST " ”®à¬ â " +MI_XCLISTRAW "K K Š ª ­ ¯¨á ­® " +MI_XCLISTVERBOSE "V V ˆ¬ï ¨  ¤à¥á ¢ á⮫¡¨ª " +MI_XCLISTLINE "N N ˆ¬¥­  ç¥à¥§ § ¯ïâãî " +MI_XCLISTREMOVE "R R “¡à âì " + +WT_ADDRESSBOOK " €¤à¥á­ ï ª­¨£  " +WT_ADVANCEDSEARCH "  áè¨à¥­­ë© ¯®¨áª " +IL_NOMOREMATCHES " ®«ìè¥ á®¢¯ ¤¥­¨© ­¥ ­ ©¤¥­® " +WT_HEADEREDITHELP1 " #F10: ­®¤«¨áâ " +WT_HEADEREDITHELP2 " F10:  ¤à¥á­ ï ª­¨£  " +WT_THREADLISTTITLE " „¥à¥¢® ®â¢¥â®¢ " +WT_ADVANCEDMARKING "  áè¨à¥­­®¥ ¢ë¤¥«¥­¨¥ " +ST_USERSTATUSLINE "€¤à¥á­ ï ª­¨£  GoldED'  - %d ¨§ %d (%d ®áâ «®áì)" +WT_USERHEADERNAME "ˆ¬ï" +WT_USERHEADERORG "Žà£ ­¨§ æ¨ï" +WT_USERHEADERAKA "€¤à¥á" +IL_USERWAIT " ®¤®¦¤¨â¥ - ¨¤¥â ¯®¨áª ¢  ¤à¥á­®© ª­¨£¥... " diff --git a/cfgs/config/simple.cfg b/cfgs/config/simple.cfg new file mode 100644 index 0000000..b282db8 --- /dev/null +++ b/cfgs/config/simple.cfg @@ -0,0 +1,150 @@ +////////////////////////////////////////////////////////////////////// +// +// GoldED 3.00 * Example Configuration File, Simple Edition. +// +// This configuration file demonstrates only the configuration +// keywords that are needed for typical GoldED setup. Most of the +// advanced features are not used. It is recommended to use the +// ADVANCED.CFG as a basic layout for your own configuration. +// +// A number of keywords are location dependent and must be placed in +// a particular oder to ensure correct operation. The exact list of +// location dependent keywords can be found in a chapter in the +// manual. This example configuration file shows the location +// dependent keywords in the recommended places. +// +// WARNING! YOU MUST EDIT THIS FILE FOR YOUR SETUP BEFORE USING IT! +// +// PLEASE NOTE: It is NOT advisable to use this configuration file +// with older versions! There are many new keywords and certain bugs +// in older versoins may surface if this configuration file is used. +// +// ------------------------------------------------------------------ +// last update on 98/08/12 (DAM) +////////////////////////////////////////////////////////////////////// + +// Your name and aliases and (misspellings). +USERNAME Your Name + +// Your FTN-style address and akas. +ADDRESS 2:236/77 ; A main node address. +AKA 2:236/77.1 ; A sysop point. +AKA 2:236/77.2@fidonet.org ; A point address with domain ("5D"). +AKA 2:236/77.999, 16077 ; A point address with fakenet ("3D"). +AKA 27:1345/118 ; An aka in another zone. + +// Your origin lines. +ORIGIN " ----> Default GoldED Origin <---- " + +// The path to your nodelists. +;NODEPATH R:\NODELIST\ + +// Filenames of your nodelists. +// If extention is ".*" or ".999", the newest is used automatically. +;NODELIST FDNET.PVT +;NODELIST FDPOINT.PVT +;NODELIST NODELIST.999 + +// Filenames of your userlists (FIDOUSER.LST format). +;USERLIST FIDOUSER.LST 2 ; Use Zone 2 for users without zone. +;USERLIST GOLDED.LST 2 + +// Path to the MSG*.BBS, LASTREAD.BBS and USERS.BBS files. +;HUDSONPATH M:\HUDSON\ + +// Path to the NETMAIL.BBS and ECHOMAIL.BBS files. +;HUDSONSYSPATH M:\HUDSON\ + +// Path to the MSG*.DAT, LASTREAD.DAT and USERS.DAT files. +;GOLDBASEPATH M:\GOLDBASE\ + +// Path to the NETMAIL.DAT and ECHOMAIL.DAT files. +;GOLDBASESYSPATH M:\GOLDBASE\ + +// Path where a Maximus/Opus format USER.BBS can be found. +;SQUISHUSERPATH R:\MAX\ + +// Path where the Ezycom msgbase and userbase can be found. +;EZYCOMMSGBASE R:\EZY\MSGBASE\ +;EZYCOMUSERBASE R:\EZY\USERBASE\ + +// Directory where NETMAIL.JAM and ECHOMAIL.JAM can be found. +;JAMPATH M:\HUDSON\ + +// Path where the PCBOARD.DAT file can be found. +;PCBOARDPATH R:\PCBOARD\ + +// FrontDoor semaphore for rescanning the netmail area. +;SEMAPHORE NETSCAN R:\FD\FDRESCAN.NOW + +// These files are for D'Bridge setups. +;SEMAPHORE NETSCAN DBRIDGE.RSN +;SEMAPHORE ECHOSCAN DBRIDGE.RSE +;SEMAPHORE EXPORTLIST ECHOMAIL.CTL + +// Name of file with areas to be scanned out by the mail processor. +// GoldED updates this file when you write messages. +;SEMAPHORE EXPORTLIST R:\MAX\ECHOSCAN.LOG + +// Scan these areas at startup. (Wildcards allowed). +AREASCAN * + +// Default path for AREAFILE's and semaphores. +AREAPATH R:\FD\ + +// GoldED can get area setup from many other programs. +// Uncomment and edit one of these for a quick and simple area setup. +;AREAFILE AdeptXBBS R:\ADEPT\ +;AREAFILE AreasBBS M:\HUDSON\AREAS.BBS +;AREAFILE DBridge R:\DB\ +;AREAFILE Dutchie R:\DUTCHIE\ +;AREAFILE Ezycom R:\EZY\ +;AREAFILE FastEcho R:\FASTECHO\ +;AREAFILE FidoPCB R:\FIDOPCB\ +;AREAFILE FMail R:\FMAIL\ +;AREAFILE FrontDoor R:\FD\ M:\HUDSON\AREAS.BBS +;AREAFILE GEcho R:\GECHO\ +;AREAFILE IMAIL R:\IMAIL\ +;AREAFILE InterMail R:\IM\ +;AREAFILE LoraBBS R:\LORA\ +;AREAFILE Maximus R:\MAX\ +;AREAFILE ME2 R:\ME2\AREADESC.ME2 R:\ME2\AREAS.BBS +;AREAFILE Opus R:\OPUS\ +;AREAFILE PCBoard R:\PCB\ +;AREAFILE Partoss R:\PARTOSS\ +;AREAFILE Portal R:\PORTAL\ +;AREAFILE ProBoard R:\PB\ +;AREAFILE QFront R:\QFRONT\ +;AREAFILE QuickBBS R:\QBBS\ R:\QBBS\AREAS.BBS +;AREAFILE RaEcho R:\RAECHO\ +;AREAFILE RemoteAccess R:\RA\ R:\RA\AREAS.BBS +;AREAFILE Squish R:\MAX\ +;AREAFILE SuperBBS R:\SUPER\ R:\SUPER\AREAS.BBS +;AREAFILE timEd R:\TIMED\ +;AREAFILE Termail R:\TERMINAT\TM\ +;AREAFILE TosScan R:\TS\ +;AREAFILE WaterGate R:\WG\ +;AREAFILE WMail R:\WMAIL\ +;AREAFILE xMail R:\XMAIL\ + +// Area definitions using the AREADEF keyword. +;Syntax: Echoid "Description" Groupid Type Format Path or board Aka (Attributes) "Origin" +;AREADEF NETMAIL "Netmails" 0 Net Opus M:\MSG\NETMAIL\ . (Loc Pvt) +;AREADEF NET_DEV "FidoNet Developers" I Echo JAM M:\JAM\INT\NET_DEV . (Loc) "If you love MSGID, set it free!" +;AREADEF C_ECHO "Int. C Discussion" I Echo Hudson 117 . (Loc) "C-king forever" +;AREADEF USR2USR "Online Users" B Local Squish M:\SQUISH\USR2USR . (Loc) "The Goldware BBS" +;AREADEF EZY_TEST "Testing Ezycom" E Echo Ezycom 711 . (Loc) "Ezycom Test Area" +;AREADEF TWILIGHT "Twilight Zone" Z Echo PCBoard R:\PCB\MAIN\TWZN7 7:77/777.7777 (Loc) + +// Area definitions using the AREA keyword. (Old format). +;Syn: Echoid "Description" FmtTyp Path or board Akano Attributes +;AREA NETMAIL "Netmails" ON M:\MSG\NETMAIL\ 0 Loc Pvt +;AREA NET_DEV "FidoNet Developers" JE M:\JAM\INT\NET_DEV 0 Loc +;AREA C_ECHO "Int. C Discussion" HE 117 0 Loc +;AREA USR2USR "Online Users" ML M:\SQUISH\USR2USR 0 Loc +;AREA EZY_TEST "Testing Ezycom" EE 711 0 Loc +;AREA TWILIGHT "Twilight Zone" PE R:\PCB\MAIN\TWZN7 7 Loc + + +---------------------------------------------------------------------- + diff --git a/cfgs/template/dansk.tpl b/cfgs/template/dansk.tpl new file mode 100644 index 0000000..c83bd49 --- /dev/null +++ b/cfgs/template/dansk.tpl @@ -0,0 +1,94 @@ +; ---------------------------------------------------------------------- +; Sample message template file for GoldED +; ---------------------------------------------------------------------- +; +@LoadLanguage GEDLNGDK.CFG +; +; ---------------------------------------------------------------------- +; Insert these lines if the message is a moved reply. +; ---------------------------------------------------------------------- +@Moved +@Moved*** Svar p† brev postet i omr†de @OEcho (@ODesc). +@Moved +; +; ---------------------------------------------------------------------- +; Insert these lines if the message is changed, and not from you. +; ---------------------------------------------------------------------- +@Changed +@Changed*** ’ndret af @CName (@CAddr), @CDate @CTime. +@Changed +; +; ---------------------------------------------------------------------- +; Insert these lines if the message is forwarded. +; ---------------------------------------------------------------------- +@Forward============================================================================= +@Forward* Forwarded af @CName (@CAddr) +@Forward* Area : @OEcho (@ODesc) +@Forward* Fra : @OName, @OAddr (@ODate @OTime) +@Forward* Til : @DName +@Forward* Emne : @Subject +@Forward============================================================================= +; +; ---------------------------------------------------------------------- +; If we are forwarding or changing, the original message is inserted +; here, with the @Message token. +; ---------------------------------------------------------------------- +@Message +; +@Forward============================================================================= +@Forward +; +; ---------------------------------------------------------------------- +; Normal template begins. +; ---------------------------------------------------------------------- +Hej @TFName! +; +; ---------------------------------------------------------------------- +; Insert extra empty line in new messages (non-replies). +; ---------------------------------------------------------------------- +@New +; +; ---------------------------------------------------------------------- +; Position cursor for the editor. +; ---------------------------------------------------------------------- +@Position +; +; ---------------------------------------------------------------------- +; If we are replying without quoting, add these lines. +; ---------------------------------------------------------------------- +@ReplySvar p† brev af <@ODate>, fra @OName til @DName: +@Reply@Position +; +; ---------------------------------------------------------------------- +; If we are comment-replying, add these lines. +; ---------------------------------------------------------------------- +@Comment@ODate kl.@OTime skrev @OName til @DName: +@Comment@Position +; +; ---------------------------------------------------------------------- +; If we are quote-replying, add these lines. +; ---------------------------------------------------------------------- +@Quoted@ODate kl.@OTime skrev @OName til @DName: +@Quoted@Position +; +; ---------------------------------------------------------------------- +; For the quotebuffer, add these lines. +; ---------------------------------------------------------------------- +@Quotebuf +@Quotebuf@ODate kl.@OTime skrev @OName til @DName: +@Quotebuf +; +; ---------------------------------------------------------------------- +; Insert quote of the original message here, if our message is a +; comment-reply or quote-reply. +; ---------------------------------------------------------------------- +@Quote + +; ---------------------------------------------------------------------- +; Sign the message with your first name. +; ---------------------------------------------------------------------- +@CFName + +; ---------------------------------------------------------------------- +; End of template. Confused? Me too! :-) +; ---------------------------------------------------------------------- diff --git a/cfgs/template/default.tpl b/cfgs/template/default.tpl new file mode 100644 index 0000000..846fa35 --- /dev/null +++ b/cfgs/template/default.tpl @@ -0,0 +1,30 @@ +; +; This is the internal default template used by GoldED when an external +; template file is not found. +; +@moved* Replying to a msg in @oecho (@odesc) +@moved +@changed* Changed by @cname (@caddr), @cdate @ctime. +@changed +@forward* Forwarded from @oecho by @cname (@caddr). +@forward* Originally by: @oname (@oaddr), @odate @otime. +@forward* Originally to: @dname. +@forward +@message +@forward +Hello @pseudo. +@new +@position +@replyReplying to a msg dated @odate @otime, from @oname{I}{you} to @dname{me}{you}. +@reply@position +@quoted@odate @otime, @oname{I}{you} wrote to @dname{me}{you}: +@quoted@position +@comment@odate @otime, @oname{I}{you} wrote to @dname{me}{you}: +@comment@position +@quotebuf +@quotebuf@odate @otime, @oname{I}{you} wrote to @dname{me}{you}: +@quotebuf +@quote + +@cfname + diff --git a/cfgs/template/email.tpl b/cfgs/template/email.tpl new file mode 100644 index 0000000..57ecf68 --- /dev/null +++ b/cfgs/template/email.tpl @@ -0,0 +1,25 @@ +@xlatexport latin1qp +@moved* Replying to a message in @oecho. +@moved +@changed* Changed by @cname, @cdate @ctime. +@changed +@forward* Forwarded from @oecho by @cname. +@forward* Originally by: @ofrom, @odate @otime. +@forward* Originally to: @oto. +@message +@forward +@new +@reply@ofrom wrote: +@reply@position +@comment@ofrom wrote: +@comment@position +;@quotedIn article @omessageid, @ofrom wrote: +@quoted@ofrom wrote: +@quoted@position +@quotebuf +@quotebuf@ofrom wrote: +@quotebuf +@quote + +@cname + diff --git a/cfgs/template/golded.cfm b/cfgs/template/golded.cfm new file mode 100644 index 0000000..4e0afbb --- /dev/null +++ b/cfgs/template/golded.cfm @@ -0,0 +1,12 @@ + +*** Confirmation Receipt Message *** + +Hello @TFName! + +This automatically generated message is a confirmation that your +message to @DName, dated @ODate @OTime, has in fact been read. If +your message requires an answer, @DFName will answer when time +permits. + +Have a nice day! + diff --git a/cfgs/template/golded.tpl b/cfgs/template/golded.tpl new file mode 100644 index 0000000..2925b3e --- /dev/null +++ b/cfgs/template/golded.tpl @@ -0,0 +1,94 @@ +; ---------------------------------------------------------------------- +; Sample message template file for GoldED +; ---------------------------------------------------------------------- +; +@LoadLanguage GEDLNGUS.CFG +; +; ---------------------------------------------------------------------- +; Insert these lines if the message is a moved reply. +; ---------------------------------------------------------------------- +@Moved +@Moved*** Answering a msg posted in area @OEcho (@ODesc). +@Moved +; +; ---------------------------------------------------------------------- +; Insert these lines if the message is changed, and not from you. +; ---------------------------------------------------------------------- +@Changed +@Changed*** Changed by @CName (@CAddr), @CDate @CTime. +@Changed +; +; ---------------------------------------------------------------------- +; Insert these lines if the message is forwarded. +; ---------------------------------------------------------------------- +@Forward============================================================================= +@Forward* Forwarded by @CName (@CAddr) +@Forward* Area : @OEcho (@ODesc) +@Forward* From : @OName, @OAddr (@ODate @OTime) +@Forward* To : @DName +@Forward* Subj : @Subject +@Forward============================================================================= +; +; ---------------------------------------------------------------------- +; If we are forwarding or changing, the original message is inserted +; here, with the @Message token. +; ---------------------------------------------------------------------- +@Message +; +@Forward============================================================================= +@Forward +; +; ---------------------------------------------------------------------- +; Normal template begins. +; ---------------------------------------------------------------------- +Hello @pseudo! +; +; ---------------------------------------------------------------------- +; Insert extra empty line in new messages (non-replies). +; ---------------------------------------------------------------------- +@New +; +; ---------------------------------------------------------------------- +; Position cursor for the editor. +; ---------------------------------------------------------------------- +@Position +; +; ---------------------------------------------------------------------- +; If we are replying without quoting, add these lines. +; ---------------------------------------------------------------------- +@ReplyAnswering a msg of <@ODate>, from @OName{me}{you} to @DName{me}{you}: +@Reply@Position +; +; ---------------------------------------------------------------------- +; If we are comment-replying, add these lines. +; ---------------------------------------------------------------------- +@Comment@ODate @OTime, @OName{I}{you} wrote to @DName{me}{you}: +@Comment@Position +; +; ---------------------------------------------------------------------- +; If we are quote-replying, add these lines. +; ---------------------------------------------------------------------- +@Quoted@ODate @OTime, @OName{I}{you} wrote to @DName{me}{you}: +@Quoted@Position +; +; ---------------------------------------------------------------------- +; For the quotebuffer, add these lines. +; ---------------------------------------------------------------------- +@Quotebuf +@Quotebuf@ODate @OTime, @OName{I}{you} wrote to @DName{me}{you}: +@Quotebuf +; +; ---------------------------------------------------------------------- +; Insert quote of the original message here, if our message is a +; comment-reply or quote-reply. +; ---------------------------------------------------------------------- +@Quote + +; ---------------------------------------------------------------------- +; Sign the message with your first name. +; ---------------------------------------------------------------------- +@CFName + +; ---------------------------------------------------------------------- +; End of template. Confused? Me too! :-) +; ---------------------------------------------------------------------- diff --git a/cfgs/template/newsgrps.tpl b/cfgs/template/newsgrps.tpl new file mode 100644 index 0000000..c553a25 --- /dev/null +++ b/cfgs/template/newsgrps.tpl @@ -0,0 +1,25 @@ +@moved* Replying to an article in @oecho. +@moved +@changed* Changed by @cname, @cdate @ctime. +@changed +@forward* Forwarded from @oecho by @cname. +@forward* Originally by: @ofrom, @odate @otime. +@forward* Originally to: @oto. +@message +@forward +@new +@reply@ofrom wrote: +@reply@position +@comment@ofrom wrote: +@comment@position +;@quotedIn article @omessageid, @ofrom wrote: +@quoted@ofrom wrote: +@quoted@position +@quotebuf +@quotebuf@ofrom wrote: +@quotebuf +@quote + +-- +signature signature signature signature signature signature signature +signature signature signature signature signature signature signature diff --git a/docs/StyleGuide b/docs/StyleGuide new file mode 100644 index 0000000..8346053 --- /dev/null +++ b/docs/StyleGuide @@ -0,0 +1,153 @@ +______________________________________________________________________ + + Goldware Source Style Guide + By Odinn Sorensen + 14. November 1998 + +______________________________________________________________________ + +Please learn from this example: + +=== Cut === +// ------------------------------------------------------------------ +// This is an example function + +int function(char* d, char* s, int i, int j) { + + if(not(i==2 or j<5) xor (i>5 and j<32)) { + switch(i) { + case 1: + printf("1\n"); + break; + default: + printf("whatever\n"); + } + } + else { + for(int n=0; n + +------------------------------------------------------------------------------- + +To compile GoldED+ and utilities you'll need: + + - GNU C++ newer than 2.8.x, gcc 2.95.2 recommended + - GNU make and GNU sed + - vi, emacs, or any other editor you like + - boldness ;-) + +First, edit GNUmakef.def for the preferrable compilation options. + +Now go to golded3 and áopy mygolded.__h to mygolded.h and adjust it for +yourself (put your name, FTN address and e-mail). Goto root again. + +Pray. + +Exec 'make'. Wait. (If your version of gcc does not support strftime format +checking you will need to manually comment __attribute__ definition on +strftimei function in goldlib/gall/gtimall.h.) + +ls bin/ + +You have to get ged{short-patform-name}, gn{short-patform-name}, and +rddt{short-patform-name}. If so, you did it! + diff --git a/docs/copying b/docs/copying new file mode 100644 index 0000000..60549be --- /dev/null +++ b/docs/copying @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/docs/copying.lib b/docs/copying.lib new file mode 100644 index 0000000..161a3d1 --- /dev/null +++ b/docs/copying.lib @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/docs/license.txt b/docs/license.txt new file mode 100644 index 0000000..3f77a17 --- /dev/null +++ b/docs/license.txt @@ -0,0 +1,76 @@ +______________________________________________________________________ + + GoldED + Goldware Utilities + The Goldware Library + Open Source Code License + 21. November 1998 +______________________________________________________________________ + + +License +------- + +GoldED and the Goldware Utilities are licensed under the GNU General +Public License (GPL), version 2. For the full text of the license, see +the file COPYING. + +The Goldware Library is licensed under the GNU Library General Public +License (LGPL), version 2. For the full text of the license, see the +file COPYING.LIB. If necessary to comply with GPL, the Goldware +Library is also licensed under GPL, version 2. + +Additionally, permission is hereby specifically given to link GoldED, +the Goldware Utilities and the Goldware Library with any software or +software library that meets the Open Source Definition, as given on +http://www.opensource.org. This includes GPL, LGPL, BSD, X Consortium, +Artistic, MozPL, QPL and most derivatives of MozPL. + +However, the author(s) of GoldED, Goldware Utilities and Goldware +Library reserve the right to refuse acceptance into the official +source tree of modifications that make the programs or library depend +on software or software libraries that is not licensed under GPL or +LGPL. + + +Comments +-------- + +The additional permission to link with non-GPL/LGPL software may be +slightly controversial. The intent is to allow developers a greater +freedom to create specialized versions of GoldED. Examples could be a +GUI "KGoldED" linked with QT, a "MozGoldED" mail/news component for +Mozilla using NGLayout for displaying HTML, a GoldED with an embedded +Perl scripting engine or whatever. However, we cannot allow the core +GoldED or Goldware Library to be dependent on these specialized +versions, so developers should take care to make their specialized +modifications modular and "stubifiable" if necessary. + +Parts of the Goldware Library is derived from the source of the old +Shareware CXL 5.2 library by Mike Smedley, from which I bought a +source license many years ago. I have made very extensive +modifications (for example, the original was DOS only), but much code +is essentially unchanged (gwin*.cpp). CXL was taken over from Mike +Smedley by Innovative Data Concepts (IDC), which renamed it TCXL and +continued development along somewhat different lines, which I did not +agree with (or at least not easily port GoldED to). However, it seems +that TCXL never really became successful. At least I could not find +anything new about TCXL and Innovative Data Concepts on the Internet +(as of 15. november 1998). I could not even find IDC's website, so in +this day and age where any succesful business has a website, I suspect +that they no longer exist. I even tried to find Mike Smedley, but +apparently he has vanished off the face of the earth, or has lost +interest in programming entirely. I did find some postings (on +DejaNews) on a sports newsgroup by a Mike Smedley, but I doubt that +it's the same guy. + +So, even though parts of the Goldware Library technically are still +copyrighted by Mike Smedley, I see so serious problems in using them. +If anyone should happen to know Mike Smedley and how to contact him, I +would very much appreciate to get the information, so we can clear up +this issue. + +Odinn Sorensen + +______________________________________________________________________ + diff --git a/docs/linux.txt b/docs/linux.txt new file mode 100644 index 0000000..0ab0145 --- /dev/null +++ b/docs/linux.txt @@ -0,0 +1,116 @@ +Hello world! + +This is a Beta release of GoldED for Linux. + +Please see the notework.txt file for release notes. + +There are some things you must know before trying out the Linux +version, especially if you are used to the DOS, OS/2 or Win32 +versions: + +* You should be familiar with GoldED for the other operating systems + and know your way around at least a basic golded.cfg. + +* Linux is an OS with CASE-SENSITIVE file systems. GoldED now uses + lowercase filenames internally, because this is costumary for Unix. + When accessing msgbases on case-insensitive file systems such as FAT + or HPFS under Linux, filenames might not be lowercase on the disk. + If this is the case, you must rename them so that they are (and hope + they stay lowercase). + + This will probably be the part that will give you the most grief if + you try to run a system with a mixture of Linux, DOS, OS/2, and/or + Win32 software. + + IF IT DOESN'T WORK OR COREDUMPS, TRY CHECKING IF ALL FILES ARE + LOWERCASE, BOTH ON THE FILESYSTEM AND IN THE CONFIGURATION FILES. + +* The directory separator (slash) char is '/', not '\'. However, + GoldED automatically translates the "wrong" slash char to the + "right" slash char in most cases, so you probably won't notice it. + +* Unix has no drive letters (C: etc), so you have to map DOS-style + paths to Unix-style paths using the MAPPATH keyword to make + AREAFILE's work. + +* If you want to use the same golded.cfg file for all platforms, you + can use the conditional statement "IF LINUX" or "IF UNIX" around + Linux specific parts of it, typically paths or filenames. + +* I recommend to start with a tiny golded.cfg (see below) with only + the basic setup and a few areas that you have a backup of. The + msgbase support of GoldED for Linux should work exactly as + 3.00.Beta3, which is NOT known to trash msgbases, but it's compiled + and built with a compiler and tools that I'm not very familiar with, + and there may be compiler quirks and flaws introduced in the porting + which may have affected otherwise working code. + +* Currently only the *.MSG, JAM, Squish and Hudson formats have been + tested, but it should work with the other formats too. + +* There is not yet any support for Unix-style mailboxes or news + spools. If you want to access those, you need to use a utility that + can create/unpack SOUP packets. GoldED can import/export those to + the msgbases that are supported (JAM or Squish is recommended for + this). + +* File attach may not work so well. + +* Sound support doesn't work. That's because Linux doesn't offer an + API to access the PC speaker. The .WAV file support is not yet + implemented. + +* Characters with ASCII values 0-31 are currently remapped to 'x' or a + visually similar character before being written to the screen. + +* The default XLATLOCALSET is LATIN-1 for the Linux version, as + opposed to IBMPC for the other OS'es. You should setup character + translation between IBMPC and LATIN-1 and use the correct XLATEXPORT + for each echo. See the GoldED manual for details. Most FidoNet + echoes assume IBMPC or another IBMPC-based sets as default if there + is no CHRS or CHARSET kludge. For areas where IBMPC is assumed, you + should set both XLATIMPORT and XLATEXPORT to IBMPC or CP850. + +* Screen color changes and cursor movements are made with ANSI + sequences similar to the way ncurses and slang does it. GoldED does + not use ncurses or slang, but has it's own windowing library which + works in a similar manner. GoldED for Linux will also work in X + terminals, but this is not recommended because of keyboard + limitations. Telnet sessions should work, if they support the ANSI + sequences and produce usable keycodes. + +* Standard distributions of Linux do not define all the keys that are + usually available on DOS, OS/2 and Win32. Specifically, cursor + movement (arrows, page, home/end) keys don't have separate keycodes + when combined with the shift, control or alt keys. It is possible + (in the keytable maps in /usr/lib/kbd/keytables) to define + non-standard keycodes to make Ctrl-PageUp, Alt-Left etc. work, but I + haven't had time to do this yet. + +* There may be odd quirks in the keyboard handling. Please report if + you find any. + +* The printing feature prints via a pipe to "/usr/dev/lpr". + +=== Cut, a basic golded.cfg === + +// example minimal configuration +username Odinn Sorensen +address 2:236/77 +areadef netmail "Netmail" 0 net opus /usr/ftn/msg/netmailx . (pvt loc k/s) +areadef net.fidoz2 "FidoNet Z2" 0 net squish /usr/ftn/squish/fidoz2 . (pvt loc) +areadef zzz.jtest1 "JAM test" 0 echo jam /usr/ftn/jam/test/jtest1 . (loc) + +// typical character translation +xlatpath /fileserv/com/golded/xlat/ +xlatimport ibmpc +xlatcharset ibmpc latin-1 ibm_iso.chs +xlatcharset latin-1 ibmpc iso_ibm.chs +xlatcharset latin-1 latin-1 iso_iso.chs +xlatcharset ibmpc ibmpc ibm_ibm.chs + +=== Cut === + +Greetings, + Odinn Sorensen + diff --git a/docs/ncurses.txt b/docs/ncurses.txt new file mode 100644 index 0000000..4f00e4e --- /dev/null +++ b/docs/ncurses.txt @@ -0,0 +1,73 @@ + +Random remarks about the ncurses support for GoldEd+ + by Jacobo Tarrio, 2:348/102.11@fidonet + +This version of GoldEd+ bears the second public release of the ncurses +implementation of its video code; it's still considered beta, so expect some +strange behaviour while it is being completed. + +It is being done in order to allow any Unix clone with ncurses installed +(and, probably, any implementation of curses) to run GoldEd+, independently +of the character set used by the system and of the terminal type; GoldEd+ +will run fine from the console with a cyrillic character set, from a xterm +with the iso-8859-1 character set, or from a monochrome VT-100 dumb +terminal. It might even be possible in the near future to use GoldEd+ +compiled for DOS, Win32 or OS/2, and linked with PDCurses. + +This file tries to list some already known bugs along with other nasty +"features" of the code. Expect most of these bugs to disappear and a lot of +fresh new ones to show up in the next public release of the ncurses support +:-) However, I do not always succeed, so old, already existing bugs are +marked with '!', whilst new ones are marked with '*'. + +If you find any bug not listed here, please report to Jacobo Tarrio, +2:348/102.11@fidonet ASAP to get it fixed soon, or, +better, fix it yourself and send me the patch :-) + +=== 2000-02-25: Second public release +Known bugs: + +! The splash screen looks a bit ugly :-) +! The cursor disappears every 30 seconds when editing a message +* Statusline displays a couple of odd characters (after GoldEd+'s name and + before the current time) +* Screen may become corrupted if someone other than GoldEd+ writes on the + terminal +* Messages from the program viewed before entering full-screen are not + displayed properly + +Notes: + +* I have "ment" the escape key affair (see below) by using some sort of + ncurses version detection and the so. If this misfeature (for I'm sure it + is going to give more trouble than good) annoys you, you can change the + delay after escape by modifying the "ESCDELAY = 50;" assignment at the + file 'goldlib/gall/gkbdbase.cpp', or by commenting it out. + + Anyway, you should perhaps be able, with this default setting, to "press" + ALT on terminals that don't have this, by pressing ESC and the desired key + very quickly :-) + + +=== 2000-01-25: First public release +Known bugs: + +* Tab key does not work properly +* Boxes are seen fine (at least with Latin-1) but lines are still drawn + with hyphens (-), plus signs (+), vertical lines (|) and the so. +* The splash screen looks a bit ugly :-) +* The box in the screensaver leaves traces when moving +* The cursor disappears every 30 seconds when editing a message + +Notes: + +* When pressing the escape key, you must wait for 1 second for GoldEd+ to + take action. This is due to the way most terminals send function keys and + keypad presses; they send ESC followed by some characters, and curses + waits for these characters to arrive. There is a way to shorten the + timeout to, say, 30ms, which is suitable for a 300-baud terminal and still + too fast for humans to notice, but it would make GoldEd+ dependant of a + particular implementation of curses, and of a particular version of that + implementation; also, it would make GoldEd+ unusable over a network or + with some dumb terminals or terminal emulators; this way you can press + ESC followed immediately by an A to "press" ALT-A. diff --git a/docs/notework.txt b/docs/notework.txt new file mode 100644 index 0000000..4dd4bbf --- /dev/null +++ b/docs/notework.txt @@ -0,0 +1,2809 @@ +______________________________________________________________________ + + --- === *** === --- + + GoldED+ + + --- === *** === --- + + +______________________________________________________________________ + + Notes for GoldED+ 1.1.4.3, February xx 2000 +______________________________________________________________________ + +- Fixed incorrect timestamps on messages. + ++ Implemented full access to Synchronet bases. Deleting implemented by + setting DEL attribute to the message. + +- Fixed bugs in origin and tagline selection menus. + +! A lot of GoldED+ internals was rearranged once again. + +- Fixed one more mistyping in TOPT/FMPT kludge fix. + +! Maximus 2.x is obsolete by Y2K, removed. + +- Fixed small bug in CC: processing. + +- Fixed small cosmetic bug in hexdump. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.4.2, February 10 2000 +______________________________________________________________________ + +! Alexander's charset patch replaced with the similar patch which + uses different mechanism: now if charset manually selected then + IgnoreCharset option automatically became active. To disable option + state you need to select "Auto" charset. + ++ Added new .lng file keyword MI_CHARSETAUTO, defaults to "Auto". + +! SWAPPATH removed since it useless. + +! GoldED+ no longer uses most of binary configuration files. The + required files are: goldhelp.ge?, goldrand.ge?, and goldxlat.ge?. + Some of them probably will be removed soon too. + +! Added Synchronet message base support in read-only mode. Could be + defined in configuration files by using SMB (AreaDef) and Y (Area) + identifiers: + + AREADEF SYNCHRO.TEST "" 0 Local SMB e:\ged\smb\smb\msgbase . (R/O) + + Please do not try to delete messages or reply in SMB areas, this not + implemented yet so the result is unpredictable. + +- Fixed partially implemented TOPT/FMPT kludges appearance after + copying/moving from squish message bases. + +- Right side slashes now used again when calling externutils. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.4.1, January 31 2000 +______________________________________________________________________ + +- GoldED+ now correctly recognizes RFC-style Date kludge which + contains 4 digits year field (not 2 digits as described in RFC-822). + +- When moving/copying messages from squish netmail to non-squish + netmail TOPT and FMPT kludges now added if required. + +- Fixed date handling in Hudson and GoldBase message bases. + +! The following keywords was renamed due to an internal collision: + + WT_HEADEREDITHELP1 WT_HEADEREDITHELP_1 + WT_HEADEREDITHELP2 WT_HEADEREDITHELP_2 + +- Fixed broken sound support in GoldED+/386. + +- Fixed set of bugs in fidoconfig parser (broken since moved to STL). + +- Fixed missed %E token in time format. + +- Fixed broken @cdate, @ctime macroses. + +- Added option "lame" to fidoconfig parser. This disables expansion of + backslashes as escape-sequences: + + Areafile fidoconfig -lame m:\y\lame\fidoconfig\is\here + ++ Added keyword BeepFactor, the default value is 1000. This used as + multiplier to sound lenght. + +- One more reason why GoldED+ could crashes at startup fixed. + ++ It is now possible to remove ftn address from the addressbook by + cleaning field, not by entering address 0: :-) + +- Wrapped RFC kludges now properly processed too. + +! Casted voodoo spell on STL =%-) Probably GoldED+ stands bit stable + now. + +- Fixed truncation of clipboard name on slashes. + ++ Integrated patches by Alexander Tsvyashchenko: + + Added new keyword SHOWDELETED to set status of "soft"-deleted + messages in Jam bases. Could be switched on the fly by AreaShowDel + (default assignment to Alt-F8) in golded.cfg. + + Added "magic" charset Auto. Now if user have choose translation + table manually (by Ctrl-J) GoldED+ will use selected page for + translation regardless of the CHRS and CHARSET kludge. If Auto + charset selected then GoldED+ will look at the CHARSET kludges + first. Please, add something like this to your config if you use + XLAT feature and want to use Auto feature: + + XLATCHARSET AUTO CP866 rus_rus.chs + +______________________________________________________________________ + + Notes for GoldED+ 1.1.4, January 14 2000 + Happy Old New Year! :-) +______________________________________________________________________ + +- Fixed bug in environment variable extension (introduced in 1.1.3). + ++ GermanKeyboard now also active by default for Polish locale. + ++ Added new template keyword @widepid which is expanded to X-Mailer + like string. + +- Fixed small unsignificant bug in installation procedure which causes + leaving zero-sized config if install was terminated. + +- Fixed memory leak in geline.cpp. + ++ Removed poor stack limitation in DPMI version. + +- Fixed set of small bugs in internal editor (especially in undo + feature). EDITUNDELETE now has same functionality as before GoldED+ + 1.1.2 been released. + +- Fixed two bugs which cause misterious crash in some circumstances + on startup. + ++ If TaskTitle defined to empty string then GoldED+/386 will not + change virtual machine name. + ++ Added %C in date macroses (short for "%a %b %e %H:%M:%S %Y"). If + strftime from RTL of compiler used for build your version of GoldED+ + supports undescribed in manual macroses you may use them also but + remember that language support via GoldED+ internals provided only + for %a, %A, %b, %B, and %C. + +! Warning: a lot of code was rearranged once again. This may cause + new bugs but it simplifies further development. + +- Fixed some date-parsing problems. + ++ Thanks to Jacobo Tarrio GoldED+ now have priliminary ncurses support + under Linux. It is probably will be easier to port (or even just + compile :)) GoldED+ to other x86 UNIX like OS'es. + +- Fixed bug which breaks creation of "To: bla-bla-bla" line using + information taken from addressbook in messages to be gated. + ++ If page from GoldHelp.cfg (the data between two *P identifyers) not + fit to single screen it now will be splitted on the window boundary + automatically. + ++ Tabulations in inserted text now properly replaced. Please note that + expanded lines should not exceed 2Kb boundary (I hope that's ok for + most users). + +- Repaired "Color Reader Hidden" keyword. If something still painted + in the regular kludge color please report. + ++ Added new option to "Write to" menu and new keyword for goldlng.cfg + file associated with this option: + + MI_WRITETOHDRONLY "H Use Header: ONLY " + + Now you may write only header to file/printer/clipboard if required. + +- Fixed nodelist index creation in GoldNode if one or more nodelist is + missed. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.3.3, December 25 1999 +______________________________________________________________________ + +- Fixed memory problems in screen handling of Linux and OS/2 versions. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.3.2, December 18 1999 +______________________________________________________________________ + +- Fixed bug in dir handler under Linux. + +- UNDO now bit properly restore screen after undone of "zap quotes + below" and importing file. + +- Fixed small bug in ZapQuotesBelow. + +! Hudson/Goldbase code was merged in single template. Please report + any new problem immediately. (For source code users: there is + probably no more chance to compile this code with anything except + GNU C) + +! Removed support for FastEcho < 1.42 (anyway all of them is not Y2K + compliant). + +- Fixed serious bug appeared somewhere in latest -asa's or first + GED+'s: if Areareplyto was defined to unexisted area or there was + problems with the first area definition then GoldED+ crashed while + saving echomail messages. + +- Probably completely fixed bug in handling netmail. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.3.1, December 06 1999 +______________________________________________________________________ + +- Fixed small bug in directory handling class. + +- Fixed bug in REPLYADDR/REPLYTO handling. + +- Fixed bug in ADDRESSMACRO keyword handling. + +- Fixed GoldNode timestamp checking. + +- Fixed small bug in InternetRFCBody processing (untested). + +- Fixed incorrect time of files in attach window (only Win32 version + was affected). + ++ Added support for Crashmail II areafile: + Areafile Crashmail c:\where\is\config.ext + +______________________________________________________________________ + + Notes for GoldED+ 1.1.3, November 27 1999 +______________________________________________________________________ + ++ A lot of memory leaks removed from window library. + +! RDDT ported to STL. + ++ Fidoconfig parser now could recognize Jam option. + ++ GoldNode now could compile as many nodelists/userlists as you want + and made bit faster. + ++ AREACOPYDIRECT no longer influence on forwarding. If you like old + behaviour there is new keyword AREAFORWARDDIRECT for you which could + be defined to Yes or No and used in Random System Group as well as + AREACOPYDIRECT. + +- CROSSPOST now defaults to Ask as promised before ;-) + +- Fixed creation of broken @CC kludge. + +! MS_LISTCC now defaults to "%s %s", ST_STATUSCC - "CC: %s of %s". + Please adjust it in your goldlang.cfg if you use it. + +! WARNING: Some basic internal classes (filebrowser, *.msg scanning + code, string class, crossposting, carbon copying, addressbook) was + redesigned or significantly changed. + +- Minor fixes in editor. + +! SoftCR now replaced in right place ;-) I mean it is replaced on + saving message to base, not at the moment of entering message. So + probably spellcheckers could be used more safely. Also this fixes + problem with replacing SoftCR under Linux. SoftCR not translated + in Subject field of Attach, Freq and UReq messages which looks to + be ok. SoftCRs now properly used in Squish message base with + DispSoftCR turned on (they was stripped at the beginning of new + line regardless of this keyword option). If EditHardTerm turned OFF + but DispSoftCR turned ON SoftCRs no longer produced in Ezycom bases. + This may broke something but I don't see any reason why this should + fail. I should also note that this feature is works ONLY in + combination with DispSoftCr Yes. Russian users may copy following + two lines to forget about SoftCR-problem completely: + -- cut here -- + DispSoftCr Yes + EditSoftCrXlat H + -- cut here -- + +______________________________________________________________________ + + Notes for GoldED+ 1.1.2, November 04 1999 +______________________________________________________________________ + ++ GoldED+ now have undo in internal editor. *BIG* thanx to Denis + Zavorotny (2:467/28) who implement it. Default assignment to + Alt-Backspace: + + @Backspace EditUndo + + NB! As undo stack is currently unlimited, to avoid unpredictable + behaviour when the top of stack reaches an item with freed line, the + kill-buffer (Ctrl-Y) was made unlimited also (i.e. EDITUNDELETE has + no effect in this version). + +- Fixed bug with incorrect handling of USER.BBS file. + +- #Del now supported in goldkeys.cfg under DOS, Win32, and OS2. + +- Added new keyword CROSSPOST to configure query appearence before + crosspossting, defaults to Ask. Possible values: Yes, No, and Ask. + +- Added LOCALAREA support to fidoconfig parser. + +- Canceling nodelist browser while lookup carbon copies to unexisted + address no loner produce letters to your address. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.1.2, September 20 1999 +______________________________________________________________________ + +- Fixed 'unfreed memory' error message appearence (broken in 1.1.1.1). + +______________________________________________________________________ + + Notes for GoldED+ 1.1.1.1, September 08 1999 +______________________________________________________________________ + +- Fixed pasting from clipboard broken since 1.1.1. + +- Squish config parser once again uses -$ at the beginning as + identifier of squish format for echo. This behaviour confirmed by + Scott Dudley so Partoss users should use -f flag at the end if they + uses groups (-$g) or descriptions (-$n) for Fido-style bases. + +- I forgot to mention that there are new goldlang keyword added: + + MS_CCTO "* Carbon copied to %s" + + Thanks to Andrew again :-) + +______________________________________________________________________ + + Notes for GoldED+ 1.1.1, August 16 1999 +______________________________________________________________________ + +- Fixed triming of spaces when pasting from clipboard. + +- Probably fixed appearence of AREA: kludge on crossposting / carbon + copying when AreaYouWroteTo used. + +- Fixed memory overrun in CHS table reader. + +! Added three new tokens that could be invalidated: cc, xc, xp. This + lines only invalidated when message forwarded or text inserted via + EDITRead menu. + +- Probably fixed memory overrun that appeared while invalidating. + +- Fixed incorrect cc: processing in Names mode ("CC: " was missed in + first line). + +- Fixed bug in USERNAME parser. + +- Fixed bug in crosspost hiding. + +- Fixed bug with missed headers in written messages. + +______________________________________________________________________ + + Notes for GoldED+ 1.0.0, July 15 1999 +______________________________________________________________________ + +- Actually print device should be left open so I just broke printing, + sorry :( + ++ Added powerful uu/xx/mime/binhex multi-messages decoder using uulib + from well-known uudeview by Frank Pilhofer. Please note that it + writes all selected messages to disk before decoding so selecting + whole base simultaneously is not a good idea ;-) + ++ Fixed bug rarely appeared while uudecoding messages (caused by long + filepathes). + +- Fixed quoting that was broken in 1.1.0 version. + ++ Added new keywords to Goldkeys.cfg: EditCopy, EditCut, EditDelete, + EditPaste, EditBlockPgUp, EditBlockPgDn, EditBlockHome, + EditBlockEnd, EditBlockUp, EditBlockDown, EditBlockLeft, + EditBlockRight. + ++ Added keyword AreaCFMReplyTo to send CFM messages to particular + area. + +______________________________________________________________________ + + Notes for GoldED+ 1.1.0, July 07 1999 +______________________________________________________________________ + ++ Added new keyword GermanKeyboard , defaults to autodetect. + Processed only by Win32 version, ignored by others. When active + right Alt key will be processed as AltGr, otherwise it will have + same functionality as left Alt. This keyword replaces command-line + switch -R. + +! Removed support for Netname keyword since it breaks our primary FTS + standarts. + +- Kludge ROUTE actually looks like #ROUTE. Fixed. + ++ Fixed crossposting to 5D FTN addresses. + +- Fixed destruction of various long wrapped kludges (mostly relies to + Internet kludges). Please report if there's something new broken ;-) + +- Fixed fix intended for long kludges wrapping problem resolving. + ++ Added new keyword FormFeedSeparator. Switched off by default, when + enabled inserts Form Feed (0x0c) character between messages while + saving to file. + +- Fix bug which causes printer device left open after printing. + ++ It is now possible to write multiple messages to clipboard. + +- @d*name, @dpseudo tokens now accept third parameter to specify + "all" name, this feature replaces previously announced feature with + automatic conversion Whoto to lowercase. + +- Fixed stupid bug in sqafix config parser which broke it completely. + +- Slightly changed keyboard behaviour in DOS and OS/2 versions: if + NUMLOCK is active then numpad keys pressed together with shift-keys + treated just like grey keys (without shifts). Now it is common + behaviour for OS/2, DOS and Win32 versions. Linux version only + missed... Till 1.0.2 hopefully ;-) + +- Fixed entering of russian letter 'p' (0xe0) in OS/2 version on + extended keyboards, and entering of dot from numpad in Win95. + +! Changed name of product to GoldED+, naming convention for archives + now: gpPABCCC.ext, where gp stands for GoldED Plus, P - platform ID + (x - DOS32, w - Win32, o - OS/2, l - Linux, s - sources, and + m - manual), A - major version, B - middle version (odd for stable, + even for unstable), CCC - minor version. + +- Fix in Squish config parser: according to documentation -$mXXX + implicitly turns on -$ switch. + +- Fixed endless loop when answering on message with Area kludge + pointed to current area. + +______________________________________________________________________ + + Notes for 3.0.1-asa10 beta3, June 30 1999 + (Happy Birthday, Svetik & Kira! ;-)) +______________________________________________________________________ + +! Due to limitations of Windows 9x Title in /386 version works only if + GoldEd runned from DOS console application and not from within Win32 + console application. Bit improved. + ++ Some new language configuration keywords added: + + MS_ORIGINALLYIN "* Originally in %s" + WT_CROSSPOST " Crosspost " + MI_XCPROCESS "P Process XC's " + MI_XCIGNORE "I Ignore XC's " + MI_XCLISTFMT "L List Format " + WT_XCLIST " XC List " + MI_XCLISTRAW "K Keep " + MI_XCLISTVERBOSE "V Verbose " + MI_XCLISTLINE "L Line " + MI_XCLISTREMOVE "R Remove " + WT_ADDRESSBOOK " Addressbook " + WT_ADVANCEDSEARCH " Advanced Search " + IL_NOMOREMATCHES " No more matches found " + WT_HEADEREDITHELP1 " #F10: Nodelist " + WT_HEADEREDITHELP2 " F10: Addressbook " + WT_THREADLISTTITLE " Message Thread List " + WT_ADVANCEDMARKING " Advanced Marking " + ST_USERSTATUSLINE "GoldED's Address Book - %d of %d (%d left)" + WT_USERHEADERNAME "Name" + WT_USERHEADERORG "Organization" + WT_USERHEADERAKA "Address" + IL_USERWAIT " Wait - Browsing Address Book... " + ++ It is possible to make carbon copies directly from echo to + AreaReplyTo area if this area is netmail. + +- Added experimental support for QEcho by Eugene Sorochinsky (with JAM + messagebases) AreaList file. Specifying primary address by number is + not supported. If location is not specified then GoldEd takes + default value /etc/qecho/AreaList (untested). + AREAFILE qecho /etc/qecho-jam/AreaList + ++ Added support for DZ echolist format: + AREAFILE echolist echo5020.lst -dz + +- Fixed small bug in sqafix arealist parser. + +- Fixed buggy feature of squish parser that forces area to squish + format as long as it parses -$ at the beginning of switch (now exact + token -$ should be present). + +- If typing over selected block in internal editor selected text will + be killed. + +- Locale now supported in djgpp and emx verions. Please note, that + to use locale in DOS you should have COUNTRY properly configured in + config.sys. + +! Removed support for GIF kludge. + +- Fixed output of attribute window if it out of screen bounds. + +- Removed fix of output in non-standart screen modes ;-) + +- Fix origin line in carbon copies. + +! If first lines in message begins with From: or To: such lines will + be parsed like an internet address. + +- A lot of fixes / features related to carbon copies creation: it is + possibe now to use addressbook and addressmacro (subject and + attributes not changed though) with it, if replying on internet + originated message it is possible now to override address, To: lines + in carbon copies used only when appropriate, it is now possible to + specify full name of addresse in internet carbon-copies (for + example, cc: "Alexander S. Aganichev" ). + +______________________________________________________________________ + + Notes for 3.0.1-asa10 beta2, June 21 1999 +______________________________________________________________________ + +- Fix problem with hiding stylecodes after hexdump viewing. + +- Fix problem painting stylecodes while editing. + +- Fix incorrect behaviour of RcvDisablesCfm in some cases. + +- Fix EditChangeDate Always behaviour. + +- Fix/cleanup D'Bridge, EzyCom, FMail 0.98, GEcho prior to 1.20, + IMail, InterMail, LoraBBS, Maximus 3.xx, Opus, PCBoard, ProBoard, + Portal of Power, QuickBBS, QFront, QWK, RemoteAccess, RA-Echo, + SuperBBS, TosScan, WMail, XMail, and XBBS config parsers. + +- Fixed output in non-standart screen modes (i.e. in 72x25: GoldEd + sometimes outputs characters out of screen range). + ++ Added support for ANSIPLUS clipboard under DOS (untested). + ++ Added Title support in /386 version under Win9x. + ++ Golded now will prompt before crossposting. + +! Invalidation of tearline, origins, and seen-by's also done at + savetime. Please note that if you don't like quotation of tearline + and/or origin you should use QUOTECTRL keyword and not INVALIDATE + keyword. + +- Kludge ROUTE added to default list of known kludges. + +! Keyword IFMAILGATES replaced with ADDRESSLOOKUPFIRST with possible + values MSGID and Origin. + ++ Added keyword QUOTECTRL with possible list of values Yes, No, + Tearline, and Origin. Default Yes. This keyword could be used in + random system groups. + +______________________________________________________________________ + + Notes for 3.0.1-asa10 beta1, June 13 1999 + (Happy Birthday, Lubashka! ;-)) +______________________________________________________________________ + ++ Added keyword RcvDisablesCfm (default yes) that controls checking of + Cfm and RRq flags on mail with Rcv one. + +- Fix Fileattach-problem in Linux-version (filenames got uppercased) + ++ GoldED now produces a more standard-conforming and informative + X-Mailer string, like i.e. "GoldED 3.0.1-dam3 (Linux 2.2.9 i586)". + The information is (of course) calculated at runtime rather at + compile time. + +! A '%' in the domainpart of the Message-ID (internet part) caused some + braindead spamfilters to activate. Therefore it is now again replaced + by a dot, as ever before. Note that you can configure the domain-part + by using INTERNETDOMAIN! + Most users won't care about it, however. + +! X-Mailer seems to be more often used than X-Mailreader. So GoldED now + also sets X-Mailer instead of the second one. + +- Don't automatically add new entries to the addressbook if + - name is an email address + - address is a MAILINGLIST sender address + +! Made the "Organization" coloumn a little bit smaller, so + address coloum is larger (useful for inet-style addresses) + +! Fidoconfig now parsed more properly and even properly than with + original library by Matthias Tichy. I don't think that someone + should continue using fidoconfig library due to a lot of bugs and + incompletions in it. On some unexplainable reasons comments in + fidoconfig stripped from the back, so following line broke parser: + + Sysop Test line # with bug # and " features + + The only supported version is 0.15 since Matthias ignore my question + about backward compatibility of configuration files. + +______________________________________________________________________ + + Notes for 3.0.1-asa9 SR3, June 8 1999 + (Win32 binary only) +______________________________________________________________________ + +- Fixed bug in FrontDoor config parser. + ++ Added support for Fidoconfig (HPT). + +- Fixed bug in text selection when cursor wrapped at the beginning or + end of line. + +- Due to reinstalling system there are no support for sound in Mingw32 + binary. It will return as soon as I upgrade libraries. + +______________________________________________________________________ + + Notes for 3.0.1-asa9 SR2, May 28 1999 + (diffs to 990518 snapshot) +______________________________________________________________________ + +- Fixed bug in clipboard handling in /386 version under windows. + +______________________________________________________________________ + + Notes for 3.0.1-asa9 SR1, May 28 1999 + (binary release DOS/386g, win32, diffs to 990518 snapshot) +______________________________________________________________________ + +- Fixed bug with broken TZUTC. + +______________________________________________________________________ + + Notes for 3.0.1-asa9, May 28 1999 + (binary release DOS/386g, win32, diffs to 990518 snapshot) +______________________________________________________________________ + ++ Multimedia now supported in Mingw32 version (requires dirty hacks in + standart headers. If you don't like hacks you could disable support + in gall/gsnd.cpp and wait for a new version of headers. + ++ Timestamps in Mingw32 version now compatible with other versions. + Old timestamps now used again. + ++ Locale now used where available, so at least Win32 version will + properly handle case conversion. + ++ IfmailGates (yes/[no]) - do not use address from Origin. + ++ TaskTitle "string" - window title (Win32 and OS/2 only). + ++ TitleStatus ([yes]/no) - adds brief description to title. + ++ GedHandshake ([yes]/no) - hides handshake in statusline. + ++ UseTZUTC (yes/[no]) - activates TZUTC kludge. (NB! This keyword + makes TimeZoneOffset obsolete. You should also set up timezone. + Probably you should add TZ variable to your environment. At my + system (Moscow, Russia) it setted up to: + + TZ=MSK-3MSD,M3.5.0/02:00,M10.5.0/03:00 + ++ AreaYouWroteTo now could be used in random groups. + ++ Subjects now autoconverted from mime encoding. + ++ Golded now uses system clipboard in internal editor. + ++ If clipboard not provided by OS or not supported (DOS, OS/2 without + PM, UNIX'es) GoldEd use fake clipboard, so you still able to copy + mail from area to buffer and then insert it in your message. + ++ Fixed crashes on viewing some messages and hexdump appeared since + -asa8 release. + ++ Fixed insertion of lines sized 79-80 chars without from + clipboard that was broken in early -asa. + ++ Fixed painting of wrapped kludges. + ++ Fixed wrapping of quotes that was broken in early -asa. + +- Removed obsolete keywords: AREAAUTOFREQ, AREABADMSGS, AREASORT, + AUTOATTACH, BEEPFACTOR, BLANKTIME, BOARDNOS, CCATTRIB, CCLIST, + CFMATTRIB, CHANGEDATE, CHANGEPROMPT, CHARSET, CLEARKEYS, COLOUR, + COMMENTNOISE, COOKIEFILE, CRLFTERM, DELORIG, DISPMSGLIST, + DISPMSGLISTFAST, DISPSTYLECODES, ECHOATTRIB, ECHOINFO, EDITMARGIN, + ELIMSNOW, ESCSET, EXCLAREA, EXPORTCHARSET, EXTKEYS, FIELDCLEAR, + FILECHECK, FILECHECKCALL, FREETEAR, GOLDEDCFM, GOLDEDLOG, GOLDEDLST, + GOLDEDMSG, GOLDEDNAM, GOLDEDPRN, HARDLINE, HARDLINES, HWMARKS, + INCLAREA, INTERNALEDITOR, LASTREAD, LASTREADUSER, LISTWRAP, + LOCALATTRIB, LOCALCHARSET, LOCALHIGHLIGHT, LOCALINFO, LOCALNOISE, + MATCHAKA, MAXCOLS, MAXMSGSIZE, MAXROWS, MIXCASE, MULTIQBBS, + NETATTRIB, NETINFO, NETTEAR, NEXTAREA, NEXTMSGS, NOISEFACTOR, + OVERLAYEMS, OVERLAYEXT, PAGEBAR, QBBSINCRESCAN, QBBSPATH, + QBBSREBUILD, QBBSSCAN, QMSGPATH, REALMSGNO, REBUILD, RENAREA, + REPLYRE, RIGHTMARGIN, SAVEMENU, SAVETIME, SAYBIBI, SCANAREA, + SHADOWS, SHARE, SHOWTWITS, SPACEQUOTES, SPELLCHECKER, STACKKEYS, + STARTECHO, SWAPALL, SYSOP, TABSIZE, TIMESLICEDV, UNDELETELINES, + USEBIOS, and XPLIST. + ++ SqaFix configuration parser added: + + AreaFile EchoList -sqafix c:\fido\mail\squish\sqafix.cfg + ++ It is possible now to use Shift-... with clipboard. + +______________________________________________________________________ + + Notes for 3.0.1-asa7 build 2, April 05 1999 + (binary release DOS/386g, win32. diffs could be provided on request) +______________________________________________________________________ + +- Now UsePID actually works. It was a bad idea to save two bytes on + brackets ;) + +- Major fix to strlwr, strupr appeared in many places in DJGPP version + introduced in -asa7 + +- Fixed clipboard handling in DJGPP version + +______________________________________________________________________ + + Notes for 3.0.1-asa7, March 31 1999 + (binary release DOS/386g, win32) +______________________________________________________________________ + ++ Next experiment on stylecodes. + +- Fixed problem with long ImportBegin and ImportEnd lines by cutting + to display margin. + ++ Global Macro now supported while in edit mail header mode. + +- Fixed bug with missed sound support in DJGPP version + ++ Proper charset ID now used in encoded e-mail headers + +- Fixed serious bug in Windows clipboard handling in Win32 version + introdused in -asa6 + ++ Incorporated patches by Igor Vanin: + + ExternUtils did not work if compiled using Watcom C++ 10.0b for OS/2 + because of using spawnvpe() RTL-call instead of system(). Fixed. + + Added new keywords into configuration file: + + USEPID (default = yes) + If disabled, the PID kludge is not inserted in messages (for those, + who does not like many kludges in messages). + + USECHARSET (default = yes) + If disabled, the CHRS kludge is not inserted in messages (for those, + who does not like many kludges in messages). + + Added/fixed system clipboard support in OS/2 version. + Menu commands: Import -> From clipboard, Write to -> Clipboard. + + Function gposixdir::open did not work because of backslash at the + end of path (compiler WC/2 10.0b). Fixed (as in 3.0.0). + + There were problems with cursor size in non-standard _fullscreen_ + video modes (for example, 80x30) in OS/2 version. Fixed. + +______________________________________________________________________ + + Notes for 3.0.1-asa6, March 22 1999 + (binary release DOS/386g, win32) +______________________________________________________________________ + +- Fixed bug in Windows clipboard handling + +- Fixed old bug with quoting text after long kludge. + ++ Added keyword EncodeEMailHeaders (default Yes). If No then RFC + header will not be encoded with quoted-printable. + +- @changed in default template fixed to use @cname instead of + @fpseudo. + +- Little fix to stylecodes detection. + +- Little fix in origin/tearline detection. + ++ It is possible now to use Windows 3.x / Windows 9x clipboard in + DOS/386g version. + ++ @*addr now use internet addresses if required. + ++ GoldNODE can now compile more than 65500 nodes + (only 32-bit versions). + +______________________________________________________________________ + + Notes for 3.0.1-asa5, March 09 1999 + (binary release DOS/386g) +______________________________________________________________________ + +- GoldEd no longer lookups pseudonyms in addressbook if not required. + +- Fixed DJGPP compiled version output interface to work properly under + Windows NT. I don't know if it properly works under DESQView now. + +- Fixed small bug with importing unterminated long lines. + +- Little fix to stylecode-detection to skip marking of c:* c:\*.*, + also could be done by STYLECODESTOPS/STYLECODEPUNCT in config. + ++ FSC-0032 compliant quote-check, except for space after '>'. Bound + is set to 10 chars. + +- Bugfix in @*pseudo handling. I've stupidly copied portion of code... + Sorry to all ;( + +- Bugfix in origin detection. + ++ New stylecode-detection algorithm. /usr/sbin/ftpd and *.* no longer + will be marked. Please report any problems to or + 2:5020/604.19 + ++ READaddressbookadd now checks for the marked messages. + ++ CROSSPOSTLIST now could be defined to YES to produse more compact + lines. Also there are little fix to missed name of current echo in + lists. You still be able to hide it's name if put # in front of it + in first line with xc: + +- Repaired STYLECODES keyword (gccfgg0.cpp, gdefs.h, gutlmisc.cpp). + Valid options are YES (show and mark), NO (show and do not mark), + HIDE (strip and mark). + ++ New macroses (gemsgs.cpp): + + @faddr Current address. + @ffname Current first name. + @flname Current last name. + @fname Current name. + @_faddr Current address (fixed width: 19 chars). + @_fname Current name (fixed width: 34 chars). + + @f* is differ from @c* in that fact, that it's actual "From:" + + @?pseudo pseudonym (see addressbook), or @?fname, where ? is one + of the "dotfc". + ++ DJGPP version now support long filenames (if provided by OS), you + could disable it by setting environment variable LFN to N. + +- small bug in USERNAME, which added an invalid aka if there was + a comma in the parameter. + +! Because of the linux paths which may start with a "/", AREAFILE + options parser has changed. Previously, it inofficially accepted a + slash as a starting charactor for an option (note this wasn't + documented!). Now, options may only start by an "-". Please adjust + your config, if you used such undocumented behaviour! + + Example: + + Change + + AREAFILE Imail c:\im /NoChk + + to + + AREAFILE Imail c:\im -NoChk. + +- @origin, @tearline and @tagline tokens weren't replaced by random + lines when using them in a template file. Fixed. + +______________________________________________________________________ + + Notes for 3.0.1, February 7 1999 + (binary version release) +______________________________________________________________________ + ++ GoldNODE can now handle IF/ELSE/ENDIF conditional and INCLUDE + directives in configuration file. + ++ Extended syntax of the following template tokens: + @oname, @ofname, @olname, @dname, @dfname, @dlname. You can now + add up to two replacement tokens according to the following sheme: + + @oname{I}{You} wrote a mail to @dname{me}{you}: + + GoldED will select the right replacement strings. You can specify + empty braces, like @oname{}{You} or @oname{I}{} (shorter, but + equivalent variant is @oname{I}). Note that the new syntax is of + course optional, you can use @oname like before and don't care + about this new feature. + ++ Added READaddressbookadd, defaults to Ctrl-B. When using this key, + GoldED will add the current writer of the mail to the addressbook, + unless it's already known to it. + ++ Added packing of Addressbook. Default key-assignment (which cannot + be changed at the moment) is ALT-P. When you call that function, + GoldED will remove all "soft" deleted (by pressing ) entries + physically on disk. With other words, there is no undo, so be care- + ful with it! + ++ Addressbook now uses filesharing. That means to can work simultan- + eously in two different GoldED instances and editing in both the + addressbook. + ++ Added new keyword NICKNAME to define a nickname for main USERNAME. + Keyword can be used globally and in random user groups. + +- GoldED/Lnx: Don't reset to 80x24 on exit (xterm only). + +- GoldED/Lnx: For those who had problems with the screen output, + those problems should be now gone. If not, please report. + ++ Added INTERNETDOMAIN , default "username%domain.de", + which is taken from INTERNETADDRESS "username@domain.de". Here you + can define what domain the outgoing mails should represent in the + Message-ID headerline. If you don't know what I'm talking about, + leave it as default, simply ignore it. It's for those who want to + tweak GoldED to be maximum RFC1036 compatible. + +! Again adjusted the "message origiating" AKA guessing code. See + ChangeLog (as always) for details. + +- GoldED/W32: Due to another bug in the Windows API, GoldED cannot + really hide the cursor if it is in window mode. So the cursor will + be moved to the lower left of the screen, where it's tolerable. + [Odinn: This fix was not good - commented out in the release] + +- Fixed SOUPEXPORTMARGIN-Bug. You can now set it back to the default + again. + +- Several fixes to the W32 keyboard code, thanks to Leonid Lisovsky. + +- When using MAPPATH in connection with AREAFILE Squish, GoldED some- + times couldn't read the squish.cfg correctly. Fixed. + +- GoldED/W32: Fixed "Escape-key" bug under WinNT, and also some other + keyboard mapping problems (Leonid Lisovsky ). + +! GoldED now knows the "Mailing-List" headerline. It ignores the line, + however. + +- The MSGID/REPLY crc values of SOUP imported emails was incorrectly + calculated. Fixed. + +- GoldED/Lnx: Fileattach-filenames won't be translated to upper-case + any more. + +- The fileattach-filebrowser now also works in Linux-version, thanks + to patches by Leonid Lisovsky ! + +- There was a Y2K bug in the filebrowser fileyear display routine. + (Yes, is difficult to explain). Fixed. + +- PMSCANning in *.msg-areas didn't check the newest msg in the area. + +- READmarkingoptions/Mark your personal mail was broken. + +- Fixed small quirks in Goldnode/Lnx code. + +- Goldnode crashed when it was unable to read even a single NODELIST. + +- Goldnode/Lnx was unable to handle wildcards in NODELIST file names. + +- GoldED/Lnx wrote wrong REPLIES-files during soup-exporting. Fixed. + +- GoldED crashed while accessing the addressbook. Fixed. + +______________________________________________________________________ + + Notes for pre-3.0.0-1, December 27 1998 + (first open source release) +______________________________________________________________________ + +- Goldnode/Lnx couldn't access paths as they were converted to upper + case during config read. Fixed. + +- When SOUP importing, the mailing list feature also processed newsgroup + articles instead of only emails as it should. + +! Removed the following GOLDKEYS.CFG commands, as they're already + replaced by newer ones since years: + + (old keyword) (replacement) + READgotodownlink READgotoreplyprev + READgotouplink READgotoreplies + READgotoreply1st + READgotoreplynext + + Please adjust your config files. + +- GoldED didn't update goldlast.lst when doing soupimport/soupexport + and using the -noscan cmdline parameter. + +- GoldED had not always read the goldlast.lst file correctly, + especially if the user removed one or more areas between two + sessions. + +- The advanced search feature didn't find all occurences. Previously, + GoldED did a "shortcircuit"-evaluation to speed up the search, that + means GoldED stopped scanning a mail before all branches of a + boolean condition were evaluated under certain conditions. Now, + GoldED will search a "hit" mail again completely to mark all + occurences of search-patterns. + +! Because some users complained that the popping-up "Wait" - window + during autosaving is irritating them too much, the window has been + now replaced by a small statusline message. + +- The following goldlang.cfg keywords were incorrectly documented: + + MI_WRITETIHDRYES "H Use Header: YES " + MO_NODROP "N No Drop / ESC " + + Of course, they are in fact called: + + MI_WRITETOHDRYES "H Use Header: YES " + MI_NODROP "N No Drop / ESC " + +- If you used Goldnode, USERLIST statements and accessed these entries + in the GoldED nodelist browser, it was likely that GoldED crashed. + This is now finally fixed. + +! Raised the maximum nodelist limit to 45 lists in goldnode. + +- Fixed a very serious bug in GoldNode, that caused mysterious + crashes, misbehaviour or broken index files when compiling. This bug + has been existing since years in Goldnode, and is most probably the + cause for any misbehaviour GoldNode users reported in the past time. + +- When using "XC: *" or similiar commands, GoldED tried to crosspost + also to the area separators. Fixed. + +- GoldED sometimes jumped to the second marked area after startup when + using AREAAUTONEXT YES. Hopefully fixed all cases. + +- The READthreadtree didn't allow to mark more messages than one + screensize, because GoldED stopped to advance the cursor-position at + the end of the window. + +! Changed the "INVALIDATE Tearline" default back to the value like it + was in older days: + + INVALIDATE Tearline "---" "-+-" + + Because of a changed INVALIDATE-handling, the old default work- + around default setting isn't needed any longer and caused other + problems. + +! The @pseudo will now also be used in the default internal template + instead of @tfname. + +- The @pseudo-token was not always expanded correctly, i.e. when + quote-replying a mail without using the addressbook during + header-editing. + +- Fixed a bug in Hudson areas where GoldED set the "Snd" flag even if + Rcv flag was set. + +- Fixed '5' key if NUM LOCK was turned off. + +- The screen got garbled when doing a addressbook-lookup while editing + the header and pressing a key that changed a message attribute. + +- GoldED didn't set CHRS-kludge correctly if charset translation level + was != 2. + +______________________________________________________________________ + + Notes for Beta5, August 16 1998 +______________________________________________________________________ + +* The Linux version is now compiled with pgcc c++ 1.0.3a with Pentium + optimization (will still run on 386/486) and is statically linked. + +- Fixed Ctrl-J keyboard bug when running the W32 version on NT. + +- When using XLATIMPORT IBMPC, XLATEXPORT LATIN-1 and XLATLOCALSET + LATIN-1 (typical setup for GoldED/Lnx users), GoldED set a wrong + charset kludge when changing the header of mails. Fixed. + +- GoldED will no longer insert the Reply-To: headerline in News/Email + areas if it is the same as From: headerline. + +! During SOUPimport, GoldED will no longer kill mails which are from + INTERNETADDRESS. Instead, GoldED will now honour the k/s flag during + SOUPexport, which means that GoldED will delete your selfwritten + mails after export if you set the k/s flag. + +- When using the AREAcatchup key with "marked areas", GoldED did not + always update the display correctly. Fixed. + +- Fixed printing bug. + ++ The advanced search features are now also available for marking + messages via the Alt-S marking menu in the reader. See the Beta4 + notes for details on the capabilities. + ++ Implemented better support for tossing mailing list emails to + different areas. The syntax of the MAILINGLIST keyword was + inadequate to support pattern matching, so a new keyword MAILTOSS + has been added, which is actually MAILINGLIST in disguise with the + parameters reordered and enabling the full set of pattern matching + as in the new advanced search feature. The syntax of the new keyword + is: + + MAILTOSS + + Note that the contribution address is required. The pattern can be + written exactly as if in the prompt for the advanced search feature + (see notes from Beta4). + + Any number of MAILTOSS lines can be given for a particular list, if + for some reason there is no single way to identify the list. + + When determining the contribution address, the first MAILTOSS (or + MAILINGLIST) that matches the echoid is chosen. + + MAILTOSS and MAILINGLIST can both be used at the same time and for + the same lists. MAILINGLIST is always the faster, because it looks + only at specific headerlines. MAILTOSS uses much more complex + pattern matching and can even match based on message body content. + + Some examples: + + MAILTOSS list.xircon xircon@xircon.com : "[XIRCON]" + (match in the subject) + + MAILTOSS list.qmail djb-qmail@koobera.math.uic.edu > "djb-qmail" + (match in the to/cc/bcc field) + ++ Added very limited support for the headerlines Cc: and Bcc:. They + are now stored internally so that they can be used for the MAILTOSS + feature. When matching on the To: field, Cc: and Bcc: are checked + too, if To: doesn't match. + +- If F10 was used during editing the header, GoldED did not always + filled the header fields with correct values. + +! GoldED will now jump to the first area with unread mail even at + startup if using AREAAUTONEXT YES. + +- In *.msg netmail areas, but probably at other places too, GoldED + showed incorrect originating akas if there were no Origin line given + in the msg. Fixed. + +! The GoldED/386 version is released in two editions, one GED386.EXE + compiled with Watcom and requiring DOS4GW as in versions before + Beta4. The other is GED386G.EXE, which is compiled with DJGPP (gcc + 2.8.1) and requiring DPMI memory (CWSDPMI.EXE is included to provide + this service, as DOS4GW does it for the Watcom edition). + +- Fixed one cause of the unfreed allocations in geline.cpp. This + happened during SOUP import, if there were msgs from your + INTERNETADDRESS. This bug was introduced in Beta3. There may still + be another cause for the unfreed allocations, since many of the + reports did not deal with SOUP import. Please check your GOLDED.LOG + sometimes after starting to run Beta5, to see if these unfreed + allocations still occur. Don't worry too much about them, they are + just fairly harmless memory leaks. + + NOTE: BEFORE REPORTING, PLEASE CHECK THE ECHOES FIRST AND SEE IF THE + PROBLEM HAS ALREADY BEEN REPORTED! + +- Fixed a small bug that could cause a crash during startup when using + the COLOR config keyword incorrectly. + ++ It's now possible to use during editing the header, which + allows browsing the addressbook to select a dest name and address. + +- COLOR HEADER BTYPE 7 didn't work. Fixed. + +! Ged/Lnx: The ESCDELAY will now be only around 100ms, so you probably + won't notice it any more. + +- Fixed another "UNREG UNREG" issue. + +- GoldED will no longer auto-add new users to the addressbook if the + user's name matches one or more of the following conditions: + + 1) It's a USERNAME + 2) It's a ROBOTNAME + 3) It's the same as WHOTO + 4) Aka/Address is unknown + +! There are now again built-in defaults for ROBOTNAME and FRQEXT as in + all previous versions. + +- When selecting the same addressbook-entry for editing twice, GoldED + showed wrong values the second time. Fixed. + +- Under some circumstances, GoldED jumped to the end-of-list instead + of just one page down when pressed PgDwn in the arealist-screen. + Fixed. + +! The "scaled down echoid feature" in the arealist-screen has been + removed again, until it's possible to make it configurable using + AREALISTFORMAT. + +! GoldED will now try to use a valid fido-aka taken from the origin + line (if existing) before using a valid fido-aka taken from the + msgid as the originating aka. This is experimental code, please + report if there are any disadvantages using this method. + +! If an area was excluded from pm-scanning, and the user performed a + pm-scan, the area will now scanned normally. Previously, GoldED + didn't scan the area at all. + +- When forwarding a mail, GoldED selected the origin-line of the + forwarded message as the origin line of the forwarder message. + Fixed. + +- Keyboard commands on key '5' did only work if Num lock was enabled. + Probably fixed. + +! BEEPFACTOR is now obsolete and has no function any more. + +- GoldED did not write GOLDED.MSG if it already existed and the user + selected External Editor for editing. Fixed. + +- GoldED/386 (DJGPP port) did always report "xxx reports error 0: no + error" when error-exiting. Fixed. + +- If ESC was pressed during adding a new addressbook entry, the cursor + bar disappeared and the program was no longer useable. Fixed. + +- If EMPTYTEARLINE YES was used, GoldED filled the tearline with + garbage. Fixed. + +- Fixed a memory overrun problem which occured under some + circumstances when working with *.MSG areas. It was reported in the + log as "Pointer error exit at [gmofido1.cpp,112]". + +- The addressbook was not properly portable between the Win32 and OS/2 + versions. + +______________________________________________________________________ + + Notes for Beta4, July 12 1998 +______________________________________________________________________ + +! GoldED/386 is now compiled with DJGPP (GCC 2.8.1). Because of this, + DOS4GW.EXE is no longer necessary for GoldED/386. + +! In this version, there are no built-in defaults for ROBOTNAME and + FRQEXT. See the manual for lists that you can include in your + GOLDED.CFG, if you need these definitions. + +- Fixed a bug that could cause the "Could not find anything to + uudecode in this message" even for valid uuencoded content in a + message. + +- Fixed keyboard code in the Win32 version to work properly with + Windows 98. + ++ Implemented advanced searching features. Currently as an extended + edition of the find function (alt-f, alt-z), but later a search + manager (similar to those seen in other programs) and other + improvements. + + The advanced search is used in much the same way as the old find + function, but many more options are available and there is some + changes in behavior. + + Highlights of the new features: + + * Four different pattern matching algorithms to chose from: + Plain (same as always). + Shell-style wildcard matching (using * and ?). + Regex. Uses the FSF extended regular expression library. + Fuzzy matching. Like plain, but allows one or more mismatches. + + * Logic expressions with "and", "or", "not" can be used. + + * Spaces and option characters can be included in patterns. + + * Exclude or include kludges, tagline, tearline, origin, signature. + + - Search backward. Must be first character, if used. + + Search forward (default). Must be first character, if used. + ! Logic not (match when NOT found). + & Logic and (match this AND that). + | Logic or (match this OR that). + < Match "from" header field. + > Match "to header field. + : Match "subject" header field. + # Match message body (but not any control lines). + . Match tagline. + _ Match tearline. + * Match origin line. + @ Match signature. + % Match kludges/headerlines. + = Match case-sensitive (defaults to not case-sensitive). + ' Do not match. Place after an option. + ^ Toggle match. Place after an option. + ?p Plain search (default). + ?r Regex search. + ?w Wildcard search. + ?f Fuzzy search with one mismatch allowed. + ?f2 Fuzzy search with two mismatches allowed. + ?f3 Fuzzy search with three mismatches allowed. + + You can enclose a pattern string with double ("") or single ('') + quotes if you want to match a sentence with spaces or which contains + option characters. + + The backslash is a literal-escape character. If a backslash is + found, the next character is treated as part of the pattern, not as + an option character. Use this for example to search for a sentence + with quotes and spaces. + + Spaces are used as separation characters and are ignored, except + when enclosed in quotes. + + The first set of option characters on a search expression line is + used as the "global default". The next set of option characters is + bound to the following pattern. A pattern is completed by the end of + the line or by the logic options '&' or '|'. + + If none of the options '<', '>' or ':' are used in the global + default part, the default is to search all three. + + Some examples: + + To search for the authors name, allowing most common misspellings: + ?f1 odinn (matches odin, odinn, oddin, odiin etc) + + To search for OS/2 and Warp 4: + OS/2 & "Warp 4" + + To search for any occurrance of Odinn or Dirk in the from-line: + < Odinn | Dirk + + To search for zip file announcements using wildcard matching: + ?w "*.zip*" + + To search case-sensitive for some string: + = "All Comes To Those Who Wait" + + Some regular expression searches: + ?r "Warp *4" (matches both "Warp 4" and "Warp4") + ?r "OS/*2" & "Warp *4" + + Due to the many different matching algorithms, the search highlight + can no longer highlights a matching word, but will instead highlight + the whole line. + + NOTE: A common mistake will be to forget to escape or quote-enclose + option characters in pattern strings. For example, what's + wrong with this, if you want to search for zip files: + + ?w *.zip* + + Nothing, but the first '*' is interpreted as if you want to + search in origin lines, which is not what you want. + +- If echoid of an area was longer than 45 chars and no description was + given, GoldED was unable to access the area. Fixed. + ++ The Echoid's in the arealist screen will now be "scaled down" to + the maximum available width instead of just being cut off. + +- The WaZOO style filerequests didn't work in the Linux-version + because GoldED used the wrong slashes for the directories. Hopefully + fixed now. + +- FILEALIASes didn't work when using READmakepathreport. + +- Fixed write-to-file. When there was an existing file of the same + name as you wanted to write to, append did not work, but overwrote + instead. Because of this bug, writing several marked msgs to a file + did not work either. + +- Fixed a bug that could cause the GoldED Win32 version to crash when + writing to a file. + +- Fixed a bug that caused mis-formatted GOLDAREA.INC output. + ++ Added AREAFILE Watergate . Reads WaterGate v0.93 and newer. + Currently none of the imported areas have any group assigned, + because the group system WaterGate uses is incompatible to GoldED's. + Suggestions are welcome. + ++ Added template expansion token @pseudo. It contains the nick name + (address book feature) of the destination user if available, else + @tfname. + + Example: + + Hello @pseudo! + +! GoldED will now check SEMAPHORE EXITNOW before any (re-)scanning + semaphores. This gives you the chance to restart GoldED first before + scanning the areas (for the case that a new area has arrived). + +- GoldED sometimes showed the wrong help category when pressing F1. + This is now fixed. + ++ Added an Address Book for GoldED. It's contents is stored in a file + named GOLDUSER.LST in the GoldED directory. To list it's contents, + press ALT-F10 while reading mails. If you press Enter on an entry, + you can view/edit it. If you press , you can manually add a new + user. + + GoldED will use the aka/address you specified when writing mails. + [description not complete] + +! Changed the default keyboard layout: + + Previously: + @F10 READtogglemarkread + now: + @F10 READuserbase + +- GoldED sometimes tried to enter an AREASEP area immediately after + startup. Fixed. + +! GoldED will no longer add an AREA-Kludge in crossposted mails. + ++ Updated some menus based on ideas posted in GOLDED.BETA echo. + +- Fixed a bug in the Internet address parsing routines that may caused + crashes. + +- the @tmpfile had wrong file modes under GoldED/Lnx. Fixed. + +- Previously, it was impossible to save a mail to a file in the + GoldED/Lnx version. Fixed. + ++ It's now possible to use XLATEXPORT ASCII in Email/News areas. + GoldED will now create appropiate headerlines. + ++ Added a very rough mime header encoding routine. + +- If GoldED were run in unregistered mode, the statusbar product + identifier did contain one space too much under some circumstances. + Cosmetical bug, which is now fixed. + ++ Added a new golded.cfg configuration keyword: + + AREAYOUWROTETO + + GoldED will automatically copy mails written by you to the specified + area during saving the mail. GoldED will also add an AREA-Kludge so + you can see from where the mail originally is copied from. + ++ Added a new golded.cfg configuration keyword: + + ADDRESSBOOKADD + + Setting it to ALWAYS means that GoldED will always add unknown users + to the addressbook. If you set the value to YES, GoldED will add + them only if it's a netmail/email. ADDRESSBOOKADD NO will never + automatically add a user. + +! Temporarily disabled the Zon-Attribute adding in the JAM-Messagebase + routines. Please report if there are now problems. + +- Hopefully fixed a keyboard code bug that caused detecting a "Esc" + keypress instead of the i.e. cursor keys. If GoldED will detect an + Esc now, it waits up to half an second if there is in fact a + different key pressed or not. + +- Fixed a bug that caused GoldED to hang/crash when a mail with "?=?" + in the subject line is read. + +- Fixed a bug that caused absolute paths to appear where only + filenames where requested in the GoldED/Lnx Version. (i.e. the + @file-token in connection with IMPORTBEGIN). + +- Fixed a small bug in search-routines that may cause crashes. + ++ Added optional switch /G to AREAFILE Squish. You can now define a + default group for areas that are imported from squish.cfg by + configuring + + AREAFILE Squish c:\squish\ /g=G + AREAFILE Squish c:\squish2\ /g=#103 + +- Fixed a Test Error Exit at [geedit.cpp, 112] if the quote string got + longer than (EDIT)QUOTEMARGIN. + ++ The READchangetemplate menu will now also display the matching aka + for every template file if defined. + +- If one or more AREASEP's but no mail areas where defined, GoldED + hung in an infinite loop after startup. Fixed. + +- Fixed a crash if msgbase rescanning was performed while selecting a + destination area for copy/move/forward. + +- Fixed Zap Area / Heat Area functionality. + +! The arealister will now automatically go one line down after + pressing AREAtoggle. + ++ Advanced the AREAcatchup feature. It'll now display a menu where you + select whether to catch-up all areas, all marked areas or only the + current area (default). + ++ Added EDITtabreverse, default to #Tab. It's simply the opposite to + EDITtab. + ++ Added AREAdropmsgmarks, default to ^M. [description not complete] + +- If the contents of SEMAPHORE EXPORTLIST changed while GoldED was + running, mail could have been left unscanned in the msgbase. Fixed. + GoldED will now also try infinite if it can't update one of the + below mentioned files because of a sharing violation. This is more + secure than before. If you had problems with unscanned mails in the + msgbase with older versions, then please try this version and report + if it works. It should. ;-) + +! GoldED will now only update NET/ECHOMAIL.JAM, GOLDQWK.LST, + GOLDSOUP.LST or SEMAPHORE EXPORTLIST file if it's really necessary. + This is actually a bugfix in connection with AREAFILE IMail, but + also may speed up scanning with other tossers. + ++ Added sound event EDITCOMPLETION, which happens after a completion + was done in the internal editor. + +! Since it seems that increasing the thread priority for the Win32 + version is a mixed blessing, the default is now to NOT increase the + priority. Added new commandline option -P to increase the priority + (Win32 only). + +- Fixed keyboard bug in the Win32 version running under NT, where + Ctrl-Enter did not work. + +! For the SOUP feature, the filenames (AREAS, *.MSG etc.) are now + again uppercase, since it seems that certain programs such as UQWK + rely on that. + +- Fixed "Generate Userlist" feature. + +- Fixed a Test Error Exit when crossposting from and into + AREAREPLYDIRECT YES areas. + ++ Added two new functions to the READthreadtree feature, currently + hardcoded on ^PgUp/^PgDown and /. They jump to the + prev/next new thread. Please make suggestions what you would also + like to have in the READthreadtree feature. + +- Under some rare circumstances, GoldED inserted a space between "---" + and the tearline text. Fixed. + +- When exporting a message from EMail/News areas, the exported header + wasn't correct. Fixed. + +- If GoldED searched for a string and found one exact matching line, + it didn't detect it as matching. Fixed. + +- Fixed several small problems in the filerequest filename detection + routine. + +- When using EDITSPELLCHECK, GoldED reset the cursor position to 1,1 + after re-importing the file into the internal editor. Fixed. + +- When forwarding a msg with tagline to an area with disabled + TAGLINESUPPORT, GoldED inserted a random tagline. Fixed. + +- Fixed some minor problems in the arealist screen. + ++ Added rough Clipboard support in W32 and OS/2-versions. I'm sorry, + but "pasting" from Clipboard is currently not possible in OS/2 + version. + ++ Added support for 80x28 mode in DOS versions. It's enabled by + setting SCREENSIZE 28 in GOLDED.CFG + +- Fixed two minor problems with INVALIDATE. + +- Fixed two minor Squish msgbase problems. + +- GoldED sometimes always showed Snt attribute in local hudsonbase + areas. Fixed. + +! GedLnx: AREAFILE filenames should be now all in lowercase. + +- Fixed a bug in GoldNODE if german POINTS24 format was used. + +- Fixed a bug if STYLECODES NO was set and ToggleStyles was used. + +- Fixed display of multiple Replies selection menu in Internet style + areas. + ++ It's now possible to use DOS/4DOS style wildcards for crossposts, + i.e. "XC: GOLDED*". + +- GoldED showed the Internet-address of self-written mails in the + message lister if MSGLISTFAST YES was set in internet areas. This is + now fixed for new written mails. + +- Previously, GoldED Mime-Header-translated the real name in the mail + header, but the template @ofrom token contained the non-translated + variant. Fixed. + +! Mime-Header decoding will now also be done in the Replies window, in + the messagelist and in the threadlist. + +! SOUPEXPORTMARGIN will now also be used int the internal editor in + Internet-areas. This has been added for more WYSIWYG in the editor. + Note that is still recommended to set EDITHARDTERM NO if + Soup-Exporting is done via GoldED. If you use a third party software + for that job, you should set EDITHARDTERM YES for those areas. + +! AREACOPYADDID YES: GoldED will now insert an ^aAREA Kludge instead + of the old AREA: - so called "kludge". In addition it won't insert a + kludge if the destination is a netmail area. This is because of some + problems with mails containing an "AREA:" line. + +- When Deleting marked messages that had DEL and Loc/Uns attributes + set, GoldED asked for confirmation. Fixed. + +- Fixed two bugs in AREALISTSORT in connection with the AREASEP + feature. Now sortspecs like "GE" or "GTE" should work as expected. + + Note: If "T" is one of the primary sortings (i.e. prior to "G"), + + AREASEP X "desc" 0 Net + + means that this Area-Separator is sorted in front of the first + Netmail area, regardless which group it has. + + Otherwise, if "G" is one of the primary sortings (prior to "T"), + + AREASEP Y "desc 2" 0 Echo + + means that this Area-Separator is sorted in front of the first area + without group (Groupid = '0'). If "T" is one of the secondary + sorting types, the Area-Separator is sorted in front of the first + area with group = 0 and Type = Echo. If there's an area with group=0 + and type=Net, the Area-Separator is sorted below that area, i.e.: + + AREADEF NETMAIL "..." 0 Net [...] + AREASEP Y "..." 0 Echo + AREADEF ECHO1 "..." 0 Echo [...] + ++ Added AREAselectmarks. Default is ALT-R. [description not complete] + +- AREACOPYADDID YES/NO didn't work if globally defined. + +- Fixed a crash if -INSTALL was used and no AREAFILE was detected. + ++ MAPPATH can now remap up to 127 chars long paths. + +- Hopefully fixed NODELISTWARN YES bug. + ++ Added functions for deletion of left/right words in the header edit. + You can use them by pressing ^Backspace and ^T. + +- GEDLNX -? didn't work. Fixed. + +- Fixed some problems with the new format of GOLDLAST.LST. + +- GoldED did not always show the size of attached files correctly if + MAPPATH was used. Fixed. + +- If AREAPMSCAN * wasn't in golded.cfg, ALT-P, A in the + arealist-screen didn't work. Fixed. + +! The READtogglestyles-menu has been removed and replaced by a variant + similar to the Toggle Twits dialog. + +! Changed the handling of the Toggle Twits dialog. You can now browse + through it by pressing READtoggletwits several times. Previously, + after you accidently came over "Kill Twit msgs", they were killed. + You can now select a mode by waiting around 3 seconds of by pressing + Enter. + +- The strings for "Twit displayed " and "Twit killed" in the Toggle + Twits dialog were swapped. Fixed. + +- The arrived/received date wasn't updated during saving the mail. + Fixed. + ++ EDITSOFTCRXLAT-translation is now also done in the header. + +- Fixed some problems in Stylecodes-detection. + +- There were several problems in the updated fast-filerequest feature + of Beta3. They're now fixed. Note if you still have problems or if + GoldED doesn't detect something/detects something wrong, please + report it! + +- If you were in the "attach files" dialog and tried to toggle a + header message attribute, the screen was garbled. Fixed it by + disabling editing the attributes while you're in this dialog. Note + that it still works during editing the header, so there should be no + problem. + ++ Added a new menu to the Import File - dialog in the internal editor. + You can now import binary files as base64 encodings. It's now also + possible to select the charset the imported file has. (i.e. if you + import a text that was written in a Windows-application or under + Linux, you should select "LATIN1 -> IBMPC" translation). + ++ GoldED will now write messages to the file "golded.txt" if you + entered in fact a directory. + +- Fixed NetName-detection in origin if a message was changed. + +- If you changed the attributes of a message, the MSGID was changed. + Fixed. + +- If you used a random origin/tearline/tagline, it wasn't expanded + under every circumstance. Fixed. + +- Fixed unfreed allocation at [gecmfd.cpp,304]. + +- Fixed unfreed allocation at [gerand.cpp,163]. + +- If you were in FromNode/DestNode Lookup (F10/#F10) and pressed ^Q, + Golded didn't quit. Fixed. + +! READthreadtree has now keyboard default '#', to be compatible to the + german point program "Crosspoint". + +- GoldED didn't detect changes to GOLDED.KEY. Fixed. + ++ Added global switch AREACATCHUPREAD . Default is YES. If set + to NO, GoldED won't reset new messages to read if HIGHLIGHTUNREAD + YES is used and AREAcatchup is executed. + +- Fixed wrong paths in NET/ECHOMAIL.JAM in Linux-version. + +- Fixed GoldNODE-Index lookup in Linux-version. + +- Fixed Logfile-Dump of Linux-version. Previously, GoldED just + wrote "Linux 0.00 reports error 0: no error" ;-) + +- Fixed a bug in the " Exit Area? " menu. + +- GoldED set the ReCeiVed attribute on messages with empty to:-lines + if INTERNETADDRESS wasn't set. + +! Replaced the stylecodes - menu by a variant similiar to the + ToggleTwitsettings menu as requested by some users. + ++ Added the following help categories to GOLDHELP.CFG: + + 1010 menu READchangexlatimport + 2007 menu AREAdropmsgmarks + 2008 menu AREAcatchup + 3015 menu READgotouplink + 3016 READreplythread lister + 5003 menu when importing files in the internal editor + 6000 addressbook users lister + 6001 menu when editing an addressbook user + +- The LOOKUPNET NO fix was broken. Fixed. + +- Fixed several small bugs in the UUCP-mails handling that were + introduced in Beta3 and before. + +! Changed the STYLECODES YES code to be less restrictive. If it fails, + please report the error. + +- If INTENSECOLORS NO was set, GoldED didn't toggle on the blinking + attribute. Fixed. + +! It's now again possible to forward messages from areas that were + defined with AREAREPLYDIRECT YES. + +- Fixed a GoldED-SOS-Dump when using AREAcatchup with a Hudsonbase + area that contained only one (new) message. + +- Fixed crashes and faulty display in the arealist screen. + +! Removed the following GOLDLANG.CFG keywords, as they are no longer + used: + + ST_MARKINGCHAIN + WL_MOVEFILEBAR + WL_TOGGLEFILE + WL_ACCEPTFILES + WL_SELECTALLFILES + WL_ABORTFILES + MS_FROMTWIT + MI_DISKFILENOHDR + MI_PRINTERNOHDR + ++ Added the following GOLDLANG.CFG keywords with the given defaults: + + MI_GOTONEXTNEW "U Yes, Next Unread Area. " + WT_FORWARD " Use FWD kludges? " + MI_FORWARDYES "Y Yes Please. " + MI_FORWARDNO "N No! " + IL_WARNLOCKED " WARNING! This message is LOcKed! " + IL_NOTHREADLIST " Sorry, no thread available. Press key " + IL_STYLECODESNO " Stylecodes disabled " + IL_STYLECODESYES " Stylecodes enabled " + IL_STYLECODESHIDE " Stylecodes enabled and stripped " + IL_UUEINVALIDPATH + " Invalid path for uudecoding - file not written " + IL_PATHREPORT " Generating PATH report " + WT_IMPORTTXT " Import " + MI_IMPORTTXTTEXT "T File as Text " + MI_IMPORTTXTQUOTE "Q File as Quote " + MI_IMPORTTXTUUE "U Binary as UUE " + MI_IMPORTTXTMIME "M Binary as MIME " + MI_IMPORTTXTCLIP "C From Clipboard " + MI_IMPORTTXTXLAT "s Use Charset.. " + MI_IMPORTTXTQUIT "N Nothing / Quit " + MS_HIDINGTWIT "This is a Twit Message - Press to read." + MS_KILLINGTWIT "Killing Twit Message..." + WT_SELECTMARKS " Select Mark " + WT_SELECTMARKSEDIT " Edit Mark Description " + MI_WRITETOHDRNO "H Use Header: NO " + MI_WRITETIHDRYES "H Use Header: YES " + MI_CLIPBOARD "C Clipboard " + IL_DROPMARKSINFO "%s Messages Are Marked " + WT_DROPMARKS " Drop Msg Marks " + MI_DROPALL "A Drop All " + MI_DROPMARKED "M Drop Marked " + MI_DROPCURRENT "C Drop Current " + MO_NODROP "N No Drop / ESC " + WT_CATCHAREAS " Catch-Up Areas " + MI_CATCHALL "A Catch All " + MI_CATCHMARKED "M Catch Marked " + MI_CATCHCURRENT "C Catch Current " + MI_NOCATCH "N No Catch / ESC " + +! The 16-bit DOS version was too large to compile, so to be able to + continue to release it at all, I had to remove some of the least + used msgbase formats. This means that the 16-bit DOS version no + longer has support for Ezycom, PCBoard, WildCat! and Goldbase. If + you need these msgbase formats, please use the 32-bit DOS version or + another platform. + + Even with these msgbase formats removed, the 16-bit DOS version + still doesn't have much free memory to work with, and you will + probably experience "out of memory" often. You should seriously + consider switching to one of the 32-bit versions instead. + +______________________________________________________________________ + + Notes for Beta3a, March 21 1998 +______________________________________________________________________ + +- Fixed crash when trying to decode malformed RFC2047 encoded words. + +- Under some circumstances, FTN addresses could appear in the header + display when in an area marked as email or news. This would happen + in cases where there was no To: or From: header. Cosmetic. + +- When entering a msg in echomail or local areas, a date was shown in + the to-line in the header editor. Cosmetic. + +- Fixed a crash in the arealist when there were not enough areas to + fill the window. + +- Fixed AREAFILE Squish, which did not find Squish areas if there was + no "-$" on its own in NETAREA/ECHOAREA lines. + +- Through a horrifying mistake, the AdeptXBBS msgbase code was in fact + never included in Beta1, 2 and 3. Fixed. SORRY!!!!!!!!! + +______________________________________________________________________ + + Notes for Beta3, March 17 1998 +______________________________________________________________________ + +! The 16-bit DOS version is now compiled in the "huge" memory model. + This was necessary to be able to compile it at all. Unfortunately + this decreases performance and bloats the EXE, and you still need + quite a lot of free DOS memory to run it for any length of time. You + should be prepared that this is probably near the end of the line + for the 16-bit DOS versions :-( + +- Fixed a bug that caused problems if you were overriding an area with + one echoid with another with the same echoid, but a different + msgbase type. + ++ Added commandline option -exportsoup. If used, GoldED exports + mail/news to SOUP at startup. If both -exportsoup and -importsoup is + used, import is performed first, then export. + ++ Added commandline option -noscan. If used, the startup scan (if any) + is skipped. This is useful for automated SOUP import/export in a + batch file. For example "-noscan -importsoup @x y" imports SOUP then + exits. + +- Fixed a bug in the JAM-routines that garbled messages if they were + copied from and to JAM-areas. Some kludges (like REPLYTO, REPLYADDR + and many others) were removed from the subfields. This caused + problems with third-party utils that accessed the copied mails. + +- DateReceived will now be set to the current local time when a + self-written mail is saved the first time. If the msgbase doesn't + support DateReceived, DateProcessed will be set instead. This + prevents some problems with stupid msgbase-maintenance utils. + +- If a mail was copied from an non-squish-area to a squish-area, it + was scanned out again as a duplicate message. Fixed. + +- Fixed "Snd"-Attribute - detection in Hudson/Goldbase areas. If a + mail was copied from an Hudson/Goldbase area to another, it was + scanned out again as a dupe message. Fixed. + +- FRQWAZOO YES has been updated to handle the "dir" attribute + correctly. + +- If LOOKUPNET NO was used, it had been impossible to enter a + destination address in netmail areas. Fixed. + ++ Added AREAFILE Partoss . Note that "filespec" must be the + full path to and including "partoss.cfg", because AREAFILE ParToss + currently calls the same config reader as AREAFILE Squish. + ++ AREAFILE Squish has been updated to interpret the following flags in + area definitions: + + -$gX Set group of area to 'X'. 'X' may be 'A'..'Z'. + -$n Set desc of area to 'desc'. 'desc' must be enclosed by + '"'s if it contains spaces. + + ParToss, a Squish-clone written by Serge V. Koghin (2:5030/177), can + handle and inserts these flags. + +! AREAFILE Squish can now also handle the case when + points to a file, not to a directory, i.e. + + AREAFILE Squish d:\path\mysquish.cfg + + The previously used syntax: + + AREAFILE Squish d:\path -c=mysquish.cfg + + has been removed. + +- Fixed shelling in the Linux version. + +- Fixed printing in the Linux version. + +- Fixed the disappearing cursor in the Linux version. + +- Fixed faulty right borders in the Linux version. + +- Fixed Tab key in the Linux version. + +- Fixed mangling of highbit characters in the Linux version after an + overlaying window was closed. + +- Fixed a quoting bug that caused quoted text to disappear. This + happened if there was a long kludge just before the normal line to + be quoted. + ++ Improved speed of the Win32 version by increasing the thread + priority for the program. + ++ AREAFILE IMail is now ready for v1.87. NOTE: This version of IMail + was not yet available at the time of writing. + +- Fixed some problems with Path-Mapping. It's now possible to use + AREAFILE IMail in connection with MAPPATH (didn't work before). + +! Keyword MAPDRIVE has been replaced by MAPPATH. The old keyword + MAPDRIVE is now obsolete, please remove it from your config! + + The new syntax is: MAPPATH . + + e.g. + + MAPPATH C: J: ; compatible to MAPDRIVE + MAPPATH C:\ /mnt/dos/c/ ; For GoldED/LNX AREAFILE's. + +- Fixed INVALIDATE handling. + +- Fixed ADDRESSMACRO in connection with EMail-areas. It is now + possible to use the following: + + ADDRESSMACRO dam,dirk.mueller@rhein-neckar.de (Dirk A. Mueller),, + +- Fixed a small bug during header-edit if an EMail was written in a + netmail area. Note that is currently impossible to reply a + gated-EMail into an EMail-area. This will be done in a future + release. + +- Fixed a bug if a gated EMail was PGP-encrypted. Previously, the + To:-Line was also encrypted and was missing afterwards. This is now + fixed. Note that is defined behaviour that the To:-line is inserted + during _saving_ the mail, not before editing the text, as before. + + If you need to change the destination address, you can do it in the + header-edit. + +- GoldED hung the computer if "Toggle all marks" was used and around + the half of all msgs were marked. Fixed. + ++ GoldED will now store the message-marks (and Personal Mails) between + sessions. + +! Changed the format of GOLDLAST.LST. You _/should/_ delete GOLDLAST.* + in your GoldED-directory (if AREAKEEPLAST YES) before starting this + new version. + ++ GoldED's statusline-clock won't stop any longer if a popup-warning + is on the screen. + +- During header-edit, GoldED inserted it's PID in every message. + Fixed. + +! SQUISHDIRECT YES will now strip Cra+Hld attribute during header + display. This may be confusing to you at first, but it is much more + intentional. + +- Fixed several "incarnations" of the charset-translation bug. GoldED + did not always translate correctly during crossposting, editing + header attributes and exporting to the quotebuffer. + +- Fixed a bug with "AREA:"-Kludge in netmail-areas. + +- It was impossible to write a mail with "@position" in the mailtext. + Fixed. + +- Fixed another charset-translation bug if READchangeattrs was used. + +- Fixed "unfreed allocation" at geread.cpp. This caused crashes if + READgotonextunread/READgotoprevunread was used multiple times. + +! If READnewarea is pressed in the message-list, the lastread-pointer + is no longer updated. This is much more intentional. + +- It is now possible to use the following Keyboard assignments: + + Esc LISTmacro LISTselect READnewarea + Esc READmessagelist + + If enabled, you can go to the message-lister by pressing ESC and can + jump from the messagelister directly to the arealist-screen by + pressing ESC _again_. + +! Screen output is now much faster in W32-versions. In addition, the + new code is smaller than the old one. + +- If READgotonextarea or READgotoprevarea was used, GoldED sometimes + assumed wrong options. Fixed. + ++ GoldED won't ask for "Zonegating yes/no?" any longer if Cra or Hld + attribute is set. + ++ Added a new menu option in the "Newarea"-Menu. Now you can go to the + arealist-screen by pressing or , or immediately jump to + the next area with new mail by pressing . + ++ Added support for the ^AENCLFILE kludge. This is only used in + JAM-Areas. However GoldED doesn't add it in new mails. + ++ Improved the Filerequest-Feature. It should be now much more + reliable and it should also display the filesize of the requestable + files, if given in the announcement. Please tell me if GoldED + detects something wrong. + ++ Added error-messages if there was an error during Shelling out. + ++ Added a warning if a commandline > 125 chars is used for Externutils + in the GoldED- and GoldED/386 version. + +- If no area was marked in the arealist-screen, and the cursor was + just above a separator, AREAjump jumped on the separator. Fixed. + ++ Added READthreadtree. There is currently no default key assignment + for it, please make suggestions. This feature is not yet finished, + please tell me if you have any ideas to improve it. + ++ Added a menu READtogglestyles. Default assignement: CTRL-H. Toggles + stylecodes-options. The default is "Stripping", if STYLECODES YES is + used. + +- "USERNAME Odinn Sorensen, 2:236/77" caused GoldED to crash if no + other ADDRESS/AKA was given. Fixed. + +- Fixed SYS3175 if undefined AKA was used in AREA or AREADEF. + +- SQUISHSCAN API didn't work. Fixed. Note if you experience wrong + values in the arealist-screen after area-scanning, you should use + this switch. If SQUISHSCAN QUICK works under you setup, then use it, + as it is faster. + +! The memory debugging code has been re-activated. It'll work also in + the Linux version now. PLEASE NOTE: The debug code caused the EXE to + grow about 100k larger and you should expect some performance + decrease. + +- OS/2: After shelling out, CTRL-S didn't work any longer. Fixed. + +- W32: After shelling out, keyboard input was echoed to screen under + some circumstances. Fixed. + +! The following obsolete keywords have been removed. Please replace + them with the newer, valid variant if you still have them in your + config: + + old new + BOARDNOS AREALISTNOS + CHANGEPROMPT DOSPROMPT + CLEARKEYS KEYBCLEAR + DELORIG ASKDELORIG + DISPSTYLECODES STYLECODES + ELIMSNOW SCREENELIMSNOW + EXTKEYS KEYBEXT + HWMARKS FIDOHWMARKS + LISTWRAP DISPLISTWRAP + LOCALHIGHLIGHT DISPLOCALHIGH + LOCALNOISE BEEPLOCALMSG + MATCHAKA AKAMATCHNET + NEXTAREA AREAAUTONEXT + NEXTMSGS DISPAUTONEXT + PAGEBAR DISPPAGEBAR + REALMSGNO DISPREALMSGNO + SAYBIBI BEEPNOISES + SHADOWS SCREENSHADOWS + SPACEQUOTES QUOTESPACING + USEBIOS SCREENUSEBIOS + ++ GOLDED.CFG: Literal strings can now also contain string delimiters. + That means you can declare something like: + + AREADEF GOLDED "About the message reader \"GoldED\" and tools" [...] + + This will be now parsed correctly everywhere. + +- If a mail with "MSGID 1:234/567@OS/2-Net" was read by GoldED, it + showed "1:234/2" in the header and not, as it should be, + "1:234/567". Fixed. However, note that only alphanumeric chars are + allowed inside domains! + +! GoldED will now also look for "NODEX.SDX" if using the V7-index. + This has been added for greater compatibility with Fastlst 2.xx. + ++ Added SEMAPHORE EXITNOW . GoldED will exit immediately if + this semaphore file is found and it is idle in the arealist screen. + +- Previously, it was impossible to overlay a key with an default + assignment with a user-macro. This is fixed now, so there should be + no need for KEYBDEFAULTS NO any longer! + +- Fixed a reflow-bug in the internal editor; if a line with maximum + length was reflowed, GoldED did delete the last character. + +- Fixed some small problems with SOUP signatures. + ++ Added a warning if you want to delete a message with LOK attribute + set. + +- Fixed "Mark thread" function. It will mark now all mails of the + current thread, not just a chain as before. However, the + implementation is yet quick'n'dirty. + +- Fixed "Nodelist out of date" warning if the browser was first + accessed. + +- Fixed several "wrong aka/akamatching" problems. + +! GoldED will now automatically save the arealist data to GOLDLAST.LST + after a semaphore-rescan has been performed. This is much more save + and useful. + +- Fixed a reflow-bug in connection with mails from "Crosspoint" users. + +! GoldED will no longer strip leading spaces from quotes. Before, + GoldED reformatted + + XX> y = x^2 + XX> lim x -> oo + + to this: + + XX>> y = x^2 + XX>> lim x -> oo + + Now, it will reformat it to the following: + + XX>> y = x^2 + XX>> lim x -> oo + + Please report if this is ok or if there are any new problems / + problems left. + ++ Added "path report" feature. New Keyboard command + READmakepathreport, defaults to Ctrl-K. The output file can be + processed by a new "RDDT" (Route Diagram Drawing Tool) utility, + which will be available separately. [documentation not complete]. + +- MAPDRIVE will be now also used when writing ECHOMAIL.JAM / + NETMAIL.JAM. This allows you again to use these files if you need + MAPDRIVE for reading the AREAFILEs correctly. + +! All global on/off switches in the GOLDED.CFG will now be parsed by a + general cfg reader class. There should be _no_ difference for you as + a user. The current implementation is just smaller and somehow + faster. It is the first step to a better config reader. + ++ AREAcatchup (ALT-C in the arealist-screen) will now also set all + messages to "read" if HIGHLIGHTUNREAD is enabled. Note that GoldED + won't reset the complete msgbase but only those messages after the + lastread-pointer, just for speed reasons. + ++ Added COLOR READER QUOTE2. The default is White on black. GoldED + shows now quotes with different "quote-levels" in different colors. + To disable this feature, set COLOR READER QUOTE2 to the same value + as COLOR READER QUOTE. + ++ Added support for SOUP-signatures. GoldED will now detect if a + template contains a signature and will handle it correctly. + +- Fixed Shift-F10 in the header-edit. + +- If TWITMODE KILL was set, GoldED didn't allow to toggle the twitmode + in the reader. Fixed. + ++ Added the goldlang.cfg keyword "IL_TWITKILLED". The default is + " Twit Msgs Killed ". + +- When forwarding a message, GoldED sometimes used a "random" + template. Fixed. + +- When forwarding a message and changing the Subject line, GoldED + replaced the template token "@subject" by the new subject instead of + the old one. Fixed. + ++ It is now possible to use "replacement" tokens inside "command + tokens" in templates. Example: + + @forward@forcesubj[FWD] @subject + + If you forward a message, GoldED will now automatically insert + "[FWD] " in front of the old subject line. + +! New entered mails are now always considered as read. + +! The "generate userlist" functionality has been changed based on + ideas of Thomas Keusch (Thank you!!). GoldED will now use the aka of + the latest message of each user in the area (Think of situations + where the aka of a user has changed) and it will be now + case-sensitive ("MICHAEL MUELLER" and "Michael Mueller" are now two + different users). As a side-effect, this routine is now MUCH faster. + :-) + +! GoldED won't import SOUP messages if they are from INTERNETADDRESS + any longer. This is a workaround for the problem that SOUPER re-gets + news that are written by the user and therefore all self-written + news are stored twice in the messagebase. + +! GoldED will now update the "DateProcessed" timestamp in JAM-soup + email/news when exporting mails. + +- GoldED will now use MAPDRIVE when displaying mails with files + attached to it. + ++ GoldED can use now a file as a list for crossposting. This was + considered as a bug, because this is already documented (?), but it + was in fact never implemented. ;-) The stuff has now been added. + +! GoldED will now insert an AREA-kludge in crossposts _if_ + AREACOPYADDID is enabled in the individual destination area. A + "Youwrote" - function will be added in a later release. + +! GoldED will now show the INTERNETADDRESS in the header if the area + is a SOUP area instead of the current aka. This is only cosmetical + and has no effect. ;-) + +- Fixed a crash if subject-line is longer than 500 chars. This can + only happen in internet-areas, and has in fact happened with a + subject line of 900 chars. ;-) + ++ Improved the keyboard code in the Win32 version to give much better + speed and to work better under both Win95 and NT. + ++ Added support for the new version 4 keysystem. A version 4 key is a + file named GOLDED.KEY, which must be in the same directory as + GOLDED.CFG. The first line of a version 4 key file contains an + identifier and the name of the registered user. This name must be in + your list of USERNAME's or REGISTERNAME. + +- GoldED wasn't able to update the timesread-field in *.MSG areas if + the Lok-attribute was set. In this case it displayed " is + locked. Wait..." forever. Fixed. + +- The destination-lookup invoked in the header by pressing Shift-F10 + didn't work. It didn't take over the selected aka. Fixed. Note that + GoldED won`t open the browser window if there's only one entry + matching the current to-name. + +- If the user has entered a fuzzy search string in the arealist-screen + and invoked "Zap/Heat areas", GoldED started to behave strangely and + maybe stop working completely. Fixed. + +- If SEMAPHORE IDLETIME was used, GoldED didn't start the + screenblanker in the arealist-screen any longer. Now, both the + screenblanker and the scanning-semaphores will work again together. + +- GoldED did export SOUP-messages even if they have had a DEL-(JAM) or + Lok-flag. Fixed. + +- Fixed a bug that caused V7-NODEFLAGS to be wrong. + ++ Added COLOR READER SIGNATURE. This color is used for the internet-style + signatures. The default is DGrey on Black. + +- Fixed all (?) "skipping separator" - problems in the arealist. + +- Fixed crash at startup if SEMAPHORE IDLETIME was used. + +- Fixed the "stuck template" problem. + +- Fixed sort order AREALISTSORT GO, when arealist separators (such as + AREASEP !A "A" A Local) where defined as Local, causing them to be + sorted after the areas in their group. + +- Fixed AREAFILE AdeptXBBS for the "no areas" bug and added support + for AdeptXBBS areas in Squish, Fido and JAM formats. OS/2 only. + +______________________________________________________________________ + + Notes for Beta2 +______________________________________________________________________ + +- Fixed several bugs in connection with FIDOUSERLIST that may cause + crashes or strange behaviour. + +- Fixed ADDRESSMACROs so that they work in EMail-areas again. + +- Fixed crash when SoupExporting and XLATEXPORT was not set to + MNEMONIC, LATIN1QP or LATIN1. + +- Fixed probably most of the AREASEP-sorting problems. If there are + still any left, please report them. + +- Fixed broken "End/Home" in the arealist-screen if first/last area + was a AREASEP-line. Note that the wraparound-bug (no wraparound + possible if first/last area is AREASEP, although DISPWRAPAROUND is + enabled) is not yet fixed. + ++ During editing in the header, it is now possible to do a NL-lookup + by pressing SHIFT-F10. In addition, the To-Name/Addr-fields will be + updated if the user selected a different destination in the browser. + +- GoldED didn't translate MIME-codes in the header in fido (gated + newsgroups) echos. Fixed. Now, if MSGLISTFAST NO is set, GoldED will + also translate the mime-headers while viewing them in the + messagelister. + +- Fixed the multiple " UNREG" in tearline problem. + ++ Added support for the "X-Mailing-List:" - RFC headerline. The + MAILINGLIST keyword will recognize it. + ++ GoldNODE can now handle up to 30 nodelists. The previous limit was + 20, otherwise it crashed. GoldNODE will now print an error message. + ++ GoldNODE can now read the german POINTS24-format directly! You can + now remove your 3d -> 4d converter. + +- Fixed some GoldNODE problems. + +- GoldED will now also know lines beginning with "Resent-" as valid + kludge lines (SOUP). + +- "RFC: x lines" wasn't detected as a known kludge. Fixed. + +- Fixed "cannot decode" if UUDECODEPATH wasn't set. + +! GoldED will no longer use the Autoattach-Feature if "a:" or "b:" is + at the beginning of the subject line. + +- Fixed bug that NODEV7MODEM b0 was not displayed even if correctly + configured. + ++ Added support for V7+. It's automatically used if your NODEPATHV7 is + set correctly. If GoldED shows "xxxx / NODEX.DTP" at the bottom of + the browser window, the displayed information is taken from the raw + nodelist entry. + +- V7 / FD / FU - Nodelist-access will now also work under GoldED/LNX. + ++ Added new "catch up" command in the arealist. Key command + AREAcatchup, default assignment Alt-C. The effect of this command is + to point the lastread pointer to the last message in the current + area. + +- Fixed some more bugs in the filerequest function. + ++ Added new keyword ATTACHPATH . It sets the default path for + fileattaches. + +- Fixed some bugs in filerequest function if many files were requested + and/or FRQOPTIONS NOWAZOOMSG wasn't used (FRQWAZOO YES). + ++ Added new functionality to "Select Reply" window. Now unread replies + are marked and the cursorbar is positioned on the first unread reply + by default. + +! Previously it wasn't possible to use '^h EDITmacro "^h"' because of + a bug in the internal editor. This is now fixed. + +- Fixed bug in the RFC822 Date: header parser, which caused a hang if + the header was not 100% correct. Changed the implementation to a + robust one and also changed the *.MSG date parser to a robust one, + just in case. + +- Added GID as a known kludge. + +- Fixed PCBoard crossposting bug that caused empty messages to be + crossposted. + +- The origins from AREAFILE's were ignored. + +- The AREAFILE Maximus reader was not working for Maximus 2.xx. Not + tested. + +- Fixed a bug that caused strange problems if GOLDED.CFG contained + tabs instead of spaces. + +- Fixed bug in the personal mail feature. If there were multiple areas + with personal mails, GoldED didn't always start with the first + unread personal mail but somewhere in between. + +- Fixed "Message is already sent" problems in *.MSG-areas (type=echo). + +- Fixed "fuzzy search" bug in the arealist-browser. + +- Fixed "wrong row in statusline" while editing in the internal + editor. + +- Fixed editor range check warning if browsing over the end-of-file + marker. + +- Fixed garbage at the right corner in the internal editor if + DISPMARGIN < 80. + +- Fixed garbage on screen if DISPMARGIN is bigger than allowed. + +! The default wildcard for the filebrowser was "*.*". Changed to "*", + as it should be. + +- AREACOPYADDID was only active if enabled in the -area. Now it + is active for the area the mail is copied TO, as it should be. In + addition it does no longer inserts an AREA-kludge if the destination + area is a netmail-area. + +- Fixed wrong color "painting" in the fileattach-menu after pressing + Ctrl-Enter. + +- Fixed faulty extended keyboard detection in the DOS-versions. + +- Fixed wrong version in the PID. + +______________________________________________________________________ + + Notes for Beta1 +______________________________________________________________________ + ++ Implemented a different memory debugging feature to GoldED/2. The + feature is enabled with the commandline option -X. When enabled, + GoldED switches to allocating memory directly with DosAllocMem and + places the data so that overruns (access beyond the end of allocated + memory) will cause an immediate SYS3175. If you suspect a bug, + please try running GoldED with this feature enabled for a while. + NOTE: When this feature is enabled, GoldED uses a lot more memory + (for example 8192 bytes per line in a msg), so be sure to have + plently of swapspace. + +- GoldED/2 crashed when trying to file attach with wildcards. + +- When move-replying a msg from an "AREAREPLYDIRECT YES" area to + another area, and the msg didn't contain an AREA: kludge, GoldED + crashed. If it *did* contain an AREA: kludge, the @oecho and @odesc + template tokens were not correct. + +- If a very long WT_NEWAREA language text was used and a long fuzzy + string was entered (such as pressing 'A' continuously), the screen + was garbled and GoldED crashed in some cases. + +- You could not enter the '^' character in the normal manner in the + Win32 version. + ++ The Win32 version now sets the window titlebar text. Also added a + bit more orderly shutdown when ctrl-break is pressed. + +- Fixed bug in the internal editor. When backspacing from column one, + the Linux version crashed. + +- The Linux version did not react properly to Ctrl-Q and Ctrl-S keys. + ++ Optimized screen access for the Linux version a bit more, and added + support for alternate charset, so that border lines etc. are drawn + using highbit characters, not ugly ascii. NOTE: If you see a lot of + strange characters instead of nice lines, you are most likely using + setfont or something else that destroys the screen mapping that + allows alternate charsets to work. GoldED uses basically the same + method for switching charsets as ncurses and slang, so you would + have the same problems with programs built with those libraries. + ++ In the arealist, GoldED now automatically skips past area separator + lines when moving over them. + ++ GoldED now decodes MIME (RFC2047) encoded headers (you know, the + ugly =?ISO-8859-1?Q?bl=ABla?= things). Note: The charset is + currently ignored. This is okay for most msgs. Will be done properly + in a later version. Encoding is not supported. + +- Fixed MIME quoted-printable support for SOUP export. During export, + the header lines were also quoted-printable encoded. + +- When using ALT-Z (EDITzapquotesbelow) and there were only quotes + below the cursor until the end of the mail (nothing else), GoldED + hung or crashed. + +- After using ALT-Z (EDITzapquotesbelow) and there was no "normal" + selfwritten line between the cursor-position and the end of the mail + but only a origin/tearline/tagline-line, GoldED displayed these + lines in the wrong color. + +- GoldED will no longer crash when importing a 1-byte SOUP message to + a JAM area. + +- When exporting news from a Squish area, GoldED forgot to set the Scn + attribute, so the articles afterwards appeared with the attributes + "Snt Uns Loc". + +! The FRQOPTION USEFLOFILE option is now permanently on. You can + remove that option from your configuration, if you have it. + ++ Changed the MAILINGLIST feature so that it also looks at the From: + line instead of just the Sender: line. + ++ GoldED now knows about the Squish "Lok" attribute with attribute + value 0x40000000. + +- When changing attributes on a msg in an area like the BAD_MSGS area, + the AREA: line was moved to a position where the mail processor + couldn't find it. + ++ In areas marked as e-mail or newsgroups, GoldED now allows full + editing of both name and internet address when in the header editor. + ++ Instead of AREAFILE TMail, you can now use AREAFILE Termail. It + calls the same config reader. + +- Fixed CARBONCOPYLIST NAMES when using a large amount of CC's (i.e. + taken from a file). GoldED created netmails for all cc-members, but + only inserted the first line of "CC: , , , + "-text and forgot the others. + +- Cutting out a large block in the internal editor caused a range + check error message. + +- GoldED crashed when copying, moving or forwarding to the same area. + +- Fixed crash if the description column "D" was not defined in + AREALISTFORMAT. + ++ New feature: GoldED can now jump to the next or previous unread msg + (unread being defined as having timesread = 0). Added the new key + commands READgotonextunread and READgotoprevunread for this feature. + + The default key assignements are: + + @U READgotonextunread ; Like in Yuppie + @Left READgotoprevunread + @Right READgotonextunread + + This feature is very useful when using the reply-linking to read a + complete thread and afterwards switch to the next unread mail + automatically. + ++ Added new keyword: SOUPEXPORTMARGIN . Defaults to 76. This + is the margin that GoldED will hard-wrap to when exporting to SOUP + packets. If you're getting complaints that your lines are too long, + you may want to set this to 70 or 60. NOTE: You should NOT enable + EDITHARDTERM in email and newsgroups that are exported to SOUP. If + you do, your messages will probably be exported with short line + "droppings" after the wrapping margin. + +- The various semaphore files are now deleted *after* performing the + desired action instead of before. + +- MAILINGLIST areas were not automatically changed to type "EMail". + ++ GoldED now also highlight the to-field if it contains the + INTERNETADDRESS. + ++ Added an end-of-message indicator line in the internal editor. It's + a line from left to right and has COLOR READER BORDER. + +- GoldED didn't write the correct entry in the .REQ file, when writing + the following in the subj-line of a wazoo-filerequest: + + GEOA1026.ZIP $365000 + + The $-stuff is now saved on the same line as the filename, similiar + to the password - '!' functionality. + +- If there were a ^B (0x02) character somewhere in the message, GoldED + also deleted the succeeding character when saving the mail. + +- The current LOADLANGUAGE (global or in a group) is now reloaded + after posting a message. This prevents "stuck" language. + +- Fixed template-matching bug. It could cause a template to be falsely + matched when entering a new message or a comment-reply in an + echomail or local area. + ++ Default colors have now been assigned to the stylecode highlighting: + + COLOR STYLECODE ALL White on Black + + Remember to enable the DISPSTYLECODES keyword if you want to see + any effect of this. + +- If you used CTRL-N/CTRL-P while reading messages to go directly to + the next area and there was a AREASEP-definition in between, GoldED + crashed. + +- In quoted-printable encoded messages, if there was an encoded TAB + character, it was decoded wrongly and the next character was lost. + +- When doing large amount of copying/moving that takes a while, GoldED + immediately switched the screensaver on after finishing the job. + Fixed. + ++ When using "ORIGIN @path\filename.lst", GoldED now shows a pretty + [filename.lst] in the origin selection menu instead of the whole + ugly thing. This will also be done for the other menus later. + +- Fixed a bug that caused a certain form of dates in internet msgs to + be stored incorrectly during SOUP import. + +- Fixed wrong file permissions in the Linux version. + +- Fixed various bugs that caused core dumps in the Linux version. + +- Removed a 500 files limit in the internal editor file selector. + ++ Updated AREAFILE TMail support to Terminate 4.00 level (should also + work for 5.00). Not tested much. + ++ Added support for numeric Re's ("Re^n:") in the subject when + replying. This is controlled with the EDITREPLYRE keyword, which you + can now set to "NUMERIC" to enable the feature. Stripping of numeric + Re's is also supported, when EDITREPLYRE is set to NO (the default). + + Example: (with EDITREPLYRE NUMERIC) + + Subj: Hello. + Subj: Re: Hello. + Subj: Re^2: Hello. + Subj: Re^3: Hello. + etc. + ++ Enabled EDITREPLYRE to work in groups as well as globally. Not + tested. + +- In newsgroups and e-mail areas, GoldED now *forces* the use of "Re:" + in reply subjects, regardless of the EDITREPLYRE setting. The reason + why it is forced in these areas, is because that is the standard for + internet mail/news. + +! The default logfile name is now GOLDED.LOG for all platforms. + +- Fixed the zero-bytes SOUP replies file. This happened when your + email/news areas were defined as local areas (to prevent being + scanned out by the mail processor) in, for example, Fastecho, but + redefined with SOUPEMAIL, AREAISEMAIL, AREAISNEWS and/or + SOUPNEWSRCFILE. Not tested. + +- Fixed crash when commandline option -N was used. + +- Fixed zero bytes allocation at [gmxbbs4.cpp,332]. + +- When the Imm attribute was toggled on, the Hld attribute (if any) + was not cleared, and vice versa. + +- COLOR READER CURSOR now works again. + +- The menu to select origins/taglines from a file, named with + @filename, didn't work well if there were long lines. Additionally, + the CR/LF characters were not properly stripped. Not tested. + +- During the first nodelist lookup, the statusline said "Checking + nodelists ...", but the previous statusline was not recovered after + checking. Not tested. + ++ Added SEMAPHORE SCANNETMAIL/PMSCANNETMAIL . If GoldED finds + this semaphore, it will scan or pmscan all netmail areas. + +- Fixed -install and AREAFILE Squish for the situation when SET SQUISH + points to a filename. Works only partially. + +- With FRQOPTIONS FAST and AREAFREQDIRECT YES, GoldED did not create + more than one frq message when there were more files than could fit + in one subject. + +- Some bugs were introduced as a consequence of the separated msgbase + code: EDITMSGSIZE didn't work. DISPSOFTCR didn't work in JAM areas, + the -Y debugging commandline parameter didn't work in Hudson, + Goldbase, JAM, Squish and Fido areas. Logging of msgbase errors and + warnings was fatally flawed - GoldED would simply crash if such an + event occurred. + +- Fixed the annoying charset translation problem that caused erratic + translation of ASCII 225 (german sharp s) and other characters, when + in the presence of LATIN-1. Specifically, the characters were + translated wrongly when you entered a new message while "on" a + message with kludge "^aCHRS LATIN-1 2". + +- Fixed sound support in GoldED/2. If enabled, it caused a crash + (SYS3175) when attempting to play a sound, typically the startup + sound. Not tested. + ++ Added support for the new Fastecho 1.46 groups 1-6. + ++ In addressmacros and in NAMES.FD, the '@' character is now allowed + in the macro name. + +- Fixed unfree'd allocation at [geread2.cpp,242]. + +- In the msglist, there were circumstances when double lines appeared + below the list of messages. + +- The replies window was deformed when there was many replies. + ++ Added new color definitions for highlightning of unread and unsent + mail in the messagelist: + + COLOR MENU UNREAD When a msg is unread. + COLOR MENU UNREADHIGH Additional highlight of to/from. + COLOR MENU UNSENT When a msg is unsent. + COLOR MENU UNSENTHIGH Additional highlight of to/from. + + If a msg is both unread and unsent, the unsent colors are used. + + The definition of "unread" in this case is a message where the + "timesread" field contains the value 0 (zero) or some kind of "seen" + attribute is not set. See also the description of the new + HIGHLIGHTUNREAD keyword. + + In msgbases where there is no timesread field or "seen" attribute, + GoldED currently fakes it and always returns a 1 (one) in the + timesread field, so that msgs won't be listed as unread all the + time. + + If the HIGHLIGHTUNREAD keyword is set to NO, the UNREAD colors are + deactivated. + + These are the defaults: + + COLOR MENU UNREAD Green on Black + COLOR MENU UNREADHIGH White on Black + COLOR MENU UNSENT LGrey on Black + COLOR MENU UNSENTHIGH LRed on Black + ++ Added new keyword HIGHLIGHTUNREAD . Defaults to NO. If set + to YES, GoldED updates (increases) the "timesread" field in each + message that you read. If set to NO, it doesn't touch the message. + The YES setting causes a slight performance decrease, because the + header of each message has to be read, the timesread field updated + and the header written back to disk. The update happens immediately + after the message is displayed, so you may not notice it at all. A + message is only updated if the timesread field contains the value 0 + (zero). + + This keyword only works in the following msgbase formats: Fido + (*.MSG), Hudson, Goldbase, JAM, Squish, Ezycom and AdeptXBBS. In + Squish and Ezycom, there is no timesread field, but I have annexed a + reserved message attribute (in Squish, 0x00080000, now called + MSGSEEN; in Ezycom, extattr 0x80) for the purpose of marking a + message as read at least once. The other formats (PCBoard, WildCat) + have no timesread field, but they have reserved fields or attributes + which *could* be used. Let me know if you want this. + +- A bug caused the area description to be used instead of the path in + a few situations: The GOLDAREA.INC file, the quotebuffer file, + PCBoard. + +______________________________________________________________________ + + The above notes are added since Alpha5 +______________________________________________________________________ + diff --git a/docs/readme.txt b/docs/readme.txt new file mode 100644 index 0000000..e38db9f --- /dev/null +++ b/docs/readme.txt @@ -0,0 +1,15 @@ +______________________________________________________________________ + + The Goldware Library + June 20, 1998 + READ ME +______________________________________________________________________ + + +Please read LICENSE.TXT for the license for The Goldware Library and +other source code by Odinn Sorensen. + +For installation instructions, read INSTALL.TXT. + +______________________________________________________________________ + diff --git a/docs/rusfaq.txt b/docs/rusfaq.txt new file mode 100644 index 0000000..f464250 --- /dev/null +++ b/docs/rusfaq.txt @@ -0,0 +1,121 @@ +This file mostly duplicates tips.txt but also answers on some russian specific +questions. The codepage used is koi8-r. Please read this before asking for +assistance! +>============================================================================== + + F.A.Q. ÐÏ ÉÓÐÏÌØÚÏ×ÁÎÉÀ GoldED+ × ËÁÒÔÉÎËÁÈ (tm) + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +>óÏÄÅÒÖÁÎÉÅ +>~~~~~~~~~~ + + 1. õÓÔÁÎÏ×ËÁ GoldED+. + 2. ìÏËÁÌØÎÙÅ ÕÓÔÁÎÏ×ËÉ. + 3. úÁÍÅÎÁ SoftCR (ÒÕÓÓËÏÊ ÂÕË×Ù "H"), ËÁË ÜÔÏ ÄÅÌÁÅÔÓÑ × GoldED+ ÐÒÁ×ÉÌØÎÏ. + 4. íÁËÒÏÓÙ ÉÌÉ ËÁË Hå ÎÁÄÏ ÍÅÎÑÔØ ÒÕÓÓËÕÀ ÂÕË×Õ "H". + 5. óÔÉÌÅ×ÙÅ ËÏÄÙ. + 6. CUA. + 7. KÁË ÎÅ Ë×ÏÔÉÔØ ÔÉÒÌÁÊÎ É ÏÒÉÄÖÉÎ × GoldED+. + 8. çÄÅ ×ÚÑÔØ GoldED+. + 9. ðÏÉÓË ÓÌÏ×: ÞÔÏ-ÔÏ ÎÅ ÔÁË... +10. þÔÏ ÚÁ ÌÅ×ÉÚÎÁ × ÁÄÒÅÓÁÈ ËÒÏÓÓÐÏÓÔÏ×, ÎÁÞÉÎÁÑ Ó 1.1.3? +11. á ÐÏÞÅÍÕ GoldED+ ÔÁË ËÒÉ×Ï ÐÏÄÄÅÒÖÉ×ÁÅÔ hpt-ÛÎÙÅ ËÏÎÆÉÇÉ (ÎÅ ÐÏÄ UNIXÁÍÉ)? +12. ðÏÞÅÍÕ ÎÅ ××ÏÄÉÔÓÑ ÒÕÓÓËÁÑ "ü" ÐÏÄ Win95? +13. çÌÀËÉ ÏÔÏÂÒÁÖÅÎÉÑ ÐÏÄ Windows 2000. +14. ôÉÐÁ ÜÔÁ... á ÐÉÓÁÔØ ËÕÄÁ Á×ÔÏÒÕ? ;-) + +>============================================================================== + +*Q:* á ×ÏÔ Ñ ÄÏÓÔÁÌ GoldED+, ËÁË ÅÇÏ ÓÔÁ×ÉÔØ-ÔÏ? +*A:* ðÒÏÞÉÔÁÊÔÅ Notework.txt, ÔÁÍ ÍÎÏÇÏ ÉÎÔÅÒÅÓÎÏÇÏ ÎÁÐÉÓÁÎÏ. ïÓÏÂÅÎÎÏ ÐÏÌÅÚÎÏ + ÅÇÏ ÞÉÔÁÔØ, ÅÓÌÉ ÞÔÏ-ÔÏ ÒÁÂÏÔÁÅÔ ÎÅ ÔÁË. åÓÌÉ ÎÅ ÚÎÁÅÔÅ ÁÎÇÌÉÊÓËÏÇÏ, ÎÏ + ÚÎÁÅÔÅ, ËÁËÏÅ ËÌÀÞÅ×ÏÅ ÓÌÏ×Ï ÇÌÀÞÉÔ - ÐÏÉÝÉÔÅ ÅÇÏ, 3 ÐÒÅÄÌÏÖÅÎÉÑ ÐÅÒÅ×ÅÓÔÉ + ÓÏ ÓÌÏ×ÁÒÅÍ ×ÓÅÇÄÁ ÍÏÖÎÏ. é ×ÏÏÂÝÅ: ÞÉÔÁÊÔÅ ÄÏËÉ - ÏÎÉ ÒÕÌÅÚ. + +*Q:* á Õ ÍÅÎÑ ÒÅÇÉÓÔÒÏÎÅÚÁ×ÉÓÉÍÙÊ ÐÏÉÓË ÇÌÀÞÉÔ É ×ÒÅÍÑ × e-mail'ÁÈ É TZUTC + ÎÅÐÒÁ×ÉÌØÎÏÅ. +*A:* þÔÏÂÙ GoldED+ ÇÌÀÞÉÌ ÐÏÍÅÎØÛÅ, ÎÁÄÏ ÎÁÓÔÒÏÉÔØ ÒÅÇÉÏÎÁÌØÎÙÅ ÕÓÔÁÎÏ×ËÉ: + ÄÌÑ DPMI32: country.sys, ÐÅÒÅÍÅÎÎÁÑ TZ + ÄÌÑ Win32: control panel + ÄÌÑ OS/2: [ÎÅ ÚÎÁÀ ÇÄÅ ÎÁÓÔÒÁÉ×ÁÅÔÓÑ, ÎÏ ÒÅÇÉÏÎÁÌØÎÙÅ ÎÁÓÔÒÏÊËÉ - Ó×ÏÉ], ÐÅÒÅÍÅÎÎÁÑ TZ + ÄÌÑ UNIX: ÐÅÒÅÍÅÎÎÙÅ LANG É TZ. + +*Q:* á ËÁË ÖÅ ×ÓÅ-ÔÁËÉ ÐÒÁ×ÉÌØÎÏ ÍÅÎÑÔØ SoftCR ÐÒÉ ÎÁÂÏÒÅ É ÉÍÅÔØ Ó ÜÔÉÍ + ÍÅÎØÛÅ ×ÓÅÇÏ ÐÒÏÂÌÅÍ? +*A:* þÔÏÂÙ ÚÁÍÅÎÑÔØ SoftCR (ÄÌÑ ÞÁÊÎÉËÏ× - ÜÔÏ ÂÏÌØÛÁÑ ÒÕÓÓËÁÑ ÂÕË×Á "H") + ÞÅÍ-ÎÉÂÕÄØ ÎÁÄÏ ÐÏÌØÚÏ×ÁÔØÓÑ ËÌÀÞÅ×ÙÍ ÓÌÏ×ÏÍ EDITSOFTCRXLAT. ðÒÉ ÜÔÏÍ + îåïâèïäéíï (Ó ×ÅÒÓÉÉ 1.1.3) ÉÍÅÔØ DISPSOFTCR ÏÐÒÅÄÅÌÅÎÎÏÅ × yes. ÷ÓÅ + ÏÓÔÁÌØÎÙÅ ×ÁÒÉÁÎÔÙ ÚÁÍÅÎÙ GoldED+ ÎÅ ÎÕÖÎÙ, Á úáíåîá þåòåú MACRO É + ×Ï×ÓÅ ðòïôé÷ïðïëáúáîá! (ÓÍ. ÓÌÅÄÕÀÝÉÊ ×ÏÐÒÏÓ). + +*Q:* á ÐÏÞÅÍÕ ÔÁË ÓÔÒÁÎÎÏ ÒÁÂÏÔÁÅÔ ÚÁÍÅÎÁ ÞÅÒÅÚ MACRO, EDITMACRO, É ÐÒ.? +*A:* óÉÍ×ÏÌÙ ÉÚ ×ÅÒÈÎÅÊ ÞÁÓÔÉ ASCII-ÔÁÂÌÉÃÙ (ÄÌÑ ÞÁÊÎÉËÏ× - ÒÕÓÓËÉÅ ÂÕË×Ù) × + ÍÁËÒÏÐÏÄÓÔÁÎÏ×ËÁÈ ÎÙÎÞÅ ÒÁÓÃÅÎÉ×ÁÀÔÓÑ ËÁË ÒÅÇÉÓÔÒÏÎÅÚÁ×ÉÓÉÍÙÅ, ËÁË ÜÔÏ + ×ÓÅÇÄÁ ÂÙÌÏ ÄÌÑ ÓÉÍ×ÏÌÏ× ÎÉÖÎÅÊ ÐÏÌÏ×ÉÎÙ ASCII-ÔÁÂÌÉÃÙ (ÌÁÔÉÎÓËÉÈ ÂÕË×). + ðÒÏÂÌÅÍÁ ÍÁÌÅÎØËÏÊ ÒÕÓÓËÏÊ "Î" ÒÁÓÔÅÔ ÏÔÓÀÄÁ. + +*Q:* á ËÁË ÉÚÍÅÎÉÔØ ÐÏ×ÅÄÅÎÉÅ ÓÔÉÌÅ×ÙÈ ËÏÄÏ×? +*A:* GoldED+ ÐÏ-ÕÍÏÌÞÁÎÉÀ ÐÏËÁÚÙ×ÁÅÔ ÓÉÍ×ÏÌÙ ×ÙÄÅÌÅÎÉÑ ÓÔÉÌÅÊ ÔÁË ÖÅ, ËÁË ÜÔÏ + ÂÙÌÏ × GoldED 2.50. åÓÌÉ ÜÔÏ ÎÅ ÕÓÔÒÁÉ×ÁÅÔ, ÔÏ ÐÏÞÉÔÁÊÔÅ ÐÒÏ ËÌÀÞÅ×ÏÅ + ÓÌÏ×Ï STYLECODES. + +*Q:* á ÇÄÅ ÏÂÅÝÁÎÎÏÅ CUA? +*A:* þÔÏÂÙ ÉÓÐÏÌØÚÏ×ÁÔØ CUA ÐÒÉ ×ÙËÌÀÞÅÎÎÏÍ KEYBDEFAULTS ÎÁÄÏ ÅÇÏ ÏÐÒÅÄÅÌÉÔØ. + èÏÔÑ ×ÓÑËÉÅ #Left ÎÅ ÏÐÉÓÁÎÙ × ÄÏËÕÍÅÎÔÁÃÉÉ, ÏÎÉ ÆÉÚÉÞÅÓËÉ ÅÓÔØ ×ÓÀÄÕ, + ËÒÏÍÅ ×ÅÒÓÉÉ ÄÌÑ Linux. óËÏÒÅÅ ×ÓÅÇÏ CUA ÐÏÄ Linux'ÏÍ (É × ÐÌÁÎÁÈ BSD) + ÂÕÄÅÔ ÒÁÂÏÔÁÔØ ÔÏÌØËÏ ÎÁ ÉËÓÏ×ÏÊ ËÏÎÓÏÌÉ, ÐÏÓËÏÌØËÕ ×Ù×ÏÄ ÎÁ ÜËÒÁÎ ÂÕÄÅÔ + ÐÏ×ÒÁÐÌÅÎ × ncurses. + +*Q:* á ÞÔÏ ÚÁ ÐÒÏÂÌÅÍÙ Ó INVALIDATE "" ""? ðÏÞÅÍÕ ×ÓÅ-ÒÁ×ÎÏ Ë×ÏÔÉÔÓÑ? +*A:* üÔÏ ÏÐÑÔØ ÎÅÄÏÞÉÔÁÎÎÁÑ ÄÏ ËÏÎÃÁ ÄÏËÕÍÅÎÔÁÃÉÑ. éÓÐÏÌØÚÕÊÔÅ ËÌÀÞÅ×ÏÅ ÓÌÏ×Ï + QUOTECTRL, ËÏÔÏÒÏÅ, ËÓÔÁÔÉ, ÍÏÖÅÔ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ É × Random System Group. + ôÉÒÌÁÊÎÙ ÐÒÁ×ÉÌØÎÏ ÉÎ×ÁÌÉÄÉÒÕÀÔÓÑ ÐÏ ÔÒÅÍ ÍÉÎÕÓÁÍ, GoldED+ ÓÁÍ ÚÎÁÅÔ, ÞÔÏ + ÐÏÓÌÅ ÎÉÈ ÄÏÌÖÅÎ ÂÙÔØ ÐÒÏÂÅÌ ÉÌÉ ÐÅÒÅ×ÏÄ ÓÔÒÏËÉ. + +*Q:* á ÇÄÅ ÍÏÖÎÏ ×ÚÑÔØ GoldED+? á ÍÏÖÎÏ ÐÏÉÍÅÔØ ÉÓÈÏÄÎÉËÉ? á ÞÅÍ ÐÏÔÏÍ + ÓÏÂÉÒÁÔØ? +*A:* òÏÄÉÎÁ GoldED+ ÎÁÈÏÄÉÔÓÑ ÎÁ http://asa.i-connect.com. ôÁÍ ÖÅ ×Ù ÍÏÖÅÔÅ + ÎÁÊÔÉ ÓÐÉÓÏË ÍÉÒÒÏÒÏ× É ×ÚÑÔØ ÉÓÈÏÄÎÉËÉ. óÏÂÉÒÁÔØ ÎÁÄÏ GNU C/C++ (ÎÅ ÎÁÄÏ + ÂÒÁÔØ ÎÅÞÔÏ ÄÒÅ×ÎÅÅ 2.8.x, ÌÕÞÛÅ ×ÓÅÇÏ ËÁËÕÀ-ÎÉÂÕÄØ Ó×ÅÖÕÀ ×ÅÒÓÉÀ) É ÅÇÏ + ÐÒÏÉÚ×ÏÄÎÙÍÉ (djgpp, emx, mingw32). äÒÕÇÉÅ ËÏÍÐÉÌÑÔÏÒÙ ÂÏÌÅÅ ÎÅ + ÐÏÄÄÅÒÖÉ×ÁÀÔÓÑ. þÔÏÂÙ ×ÓÅ ËÏÍÐÉÌÉÒÏ×ÁÌÏÓØ ÂÅÚ ËÁËÉÈ-ÌÉÂÏ ÐÒÏÂÌÅÍ - ÂÅÒÉÔÅ + ÞÔÏ-ÔÏ ÎÏ×ÅÅ gcc 2.95 (ÉÌÉ ÔÅ egcs, × ËÏÔÏÒÙÈ #pragma implementaion, + #pragma interface ÕÖÅ ÂÙÌÉ obsolete). ÷Ï×ÓÅ ÎÅ ÎÁÄÏ ËÏÍÐÉÌÉÒÏ×ÁÔØ ×ÓÅ + ËÏÍÁÎÄÏÊ "make 2>&1 | mail -s VERSION asa@eed.miee.ru", ×ÓÅ ÒÁ×ÎÏ Ñ ÜÔÏ + ÞÉÔÁÔØ ÎÅ ÂÕÄÕ - ÍÎÅ ÌÅÎØ ÒÁÚÂÉÒÁÔØ ÜÔÏÔ ÓÐÁÍ. + +*Q:* á ËÁË-ÔÏ ÐÏÉÓË ÎÅÔÒÉ×ÉÁÌØÎÏ ÒÁÂÏÔÁÅÔ... +*A:* á ×Ù Õ×ÅÒÅÎÙ, ÞÔÏ ÐÒÏÞÉÔÁÌÉ Notework.txt ÄÏ ÐÒÅÄÙÄÕÝÅÊ ×ÅÒÓÉÉ, × ËÏÔÏÒÏÊ + ×ÓÅ ÒÁÂÏÔÁÌÏ? HÁÞÉÎÁÑ Ó 3.00b4 ×ÓÅ ÓÉÌØÎÏ ÐÏÍÅÎÑÌÏÓØ. K ÔÏÍÕ, ÞÔÏ ÔÁÍ + ÏÐÉÓÁÎÏ, ÍÏÖÎÏ ÄÏÂÁ×ÉÔØ, ÞÔÏ GoldED+ ÐÒÁ×ÉÌØÎÏ ÐÏÎÉÍÁÅÔ ÐÏÉÓË ËÏÍÂÉÎÁÃÉÊ + ÔÉÐÁ "A & B | C & D & E" Ó ÐÒÉÏÒÉÔÅÔÏÍ & ÎÁÄ | É ÞÔÏ ÒÕÓÓËÉÅ ÓÌÏ×Á ÍÏÖÎÏ + ÉÓËÁÔØ ÔÁËÉÍÉ ËÏÍÂÉÎÁÃÉÑÍÉ: "?r [Ðn][Òp][Éu][×B][ÅE][ÔT]", ÇÄÅ ÐÅÒ×ÁÑ + ÂÕË×Á ÒÕÓÓËÁÑ, ×ÔÏÒÁÑ ÌÁÔÉÎÓËÁÑ (ËÁ×ÙÞËÉ ××ÏÄÉÔØ ÎÅ ÓÌÅÄÕÅÔ). + +*Q:* þÔÏ ÚÁ ÌÅ×ÉÚÎÁ × ÁÄÒÅÓÁÈ ËÒÏÓÓÐÏÓÔÏ×, ÎÁÞÉÎÁÑ Ó 1.1.3? +*A:* ÷ goldlang.cfg ÐÏÍÅÎÑÌÓÑ ÆÏÒÍÁÔ ÄÌÑ ÓÌÏ× MS_LISTCC ("%s %s") É + ST_STATUSCC ("CC: %s of %s"). ðÒÏ×ÅÒØÔÅ Ó×ÏÊ ËÏÎÆÉÇ! + +*Q:* ðÏÓÔÁ×ÉÌ ÓÅÂÅ hpt. é ÞÔÏ ÜÔÏ ÚÁ ÌÁÖÁ ÐÒÉ ÞÔÅÎÉÉ ËÏÎÆÉÇÏ×? +*A:* á ×Ù Õ×ÅÒÅÎÙ, ÞÔÏ ×Ù ÞÉÔÁÌÉ ÄÏËÕ ÎÁ Ó×ÏÊ hpt? ÷ ÄÏËÅ Ñ×ÎÏ ÎÁÐÉÓÁÎÏ, ÞÔÏ + "\" ÉÎÉÃÉÉÒÕÅÔ escape-ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ. GoldED+ ÞÅÓÔÎÏ Å£ ÏÂÒÁÂÁÔÙ×ÁÅÔ, + × ÏÔÌÉÞÉÉ ÏÔ ÔÅÈ, ËÔÏ ÏÂÅÝÁÌ... ÷ ÐÒÉÎÃÉÐÅ, × 1.1.4.1 ÐÏÑ×ÉÌÓÑ ËÌÀÞÉË + -lame, ÏÔËÌÀÞÁÀÝÉÊ ÐÁÒÓÉÌËÕ ÏÂÒÁÔÎÙÈ ÓÌÜÛÅÊ, ÐÏÐÒÏÂÕÊÔÅ. ÷ÏÔ ËÏÍÍÅÎÔÁÒÉÉ + Ó ËÏÎÃÁ ÓÔÒÏËÉ Ñ ÔÏÞÎÏ ÐÁÒÓÉÔØ ÎÅ ÂÕÄÕ!!! :-) + +*Q:* ðÏÞÅÍÕ ÎÅ ××ÏÄÉÔÓÑ ÒÕÓÓËÁÑ "ü" ÐÏÄ Win95? +*A:* ðÏÓÔÁ×ØÔÅ ÔÉÐ ËÌÁ×ÉÁÔÕÒÙ 101 ËÌÁ×ÉÛÎÙÊ óûá, ÓËÏÒÅÅ ×ÓÅÇÏ ÐÏÍÏÖÅÔ. åÓÌÉ ÎÅ + ÐÏÍÏÖÅÔ - ÐÏÓÔÁ×ØÔÅ ÓÅÂÅ ÎÏÒÍÁÌØÎÙÊ ÒÕÓÓÉÆÉËÁÔÏÒ: ÜÔÏ ÚÁÏÄÎÏ ÓÐÁÓÅÔ ÏÔ + ËÒÉ×ÏÊ ×ÓÔÁ×ËÉ ÔÅËÓÔÁ ÉÚ ËÌÉÐÂÏÒÄÁ × DOS-×ÅÒÓÉÉ ÐÒÉ ÎÅÓÏ×ÐÁÄÅÎÉÉ ÑÚÙËÁ + ÔÅËÓÔÁ É ÓÏÄÅÒÖÉÍÏÇÏ ËÌÉÐÂÏÒÄÁ. + +*Q:* çÌÀËÉ ÏÔÏÂÒÁÖÅÎÉÑ ÐÏÄ Windows 2000. +*A:* òÅÛÁÀÔÓÑ ÓÍÅÎÏÊ ÛÒÉÆÔÁ ÎÁ Lucida ÉÌÉ ÇÒÑÚÎÙÍÉ ÈÁËÁÍÉ registry ÎÁ ÐÒÅÄÍÅÔ + ÐÅÒÅÓÔÁÎÏ×ËÉ ÑÚÙËÏ× Ó 1250/1252 ÎÁ 1251. + +*Q:* ôÉÐÁ ÜÔÁ... á ÐÉÓÁÔØ ËÕÄÁ Á×ÔÏÒÕ? ;-) +*A:* ðÉÓÁÔØ ÌÕÞÛÅ ×ÓÅÇÏ × Ru.GoldED. äÁÖÅ ÌÕÞÛÅ ÓÎÁÞÁÌÁ ÅÇÏ ÐÏÞÉÔÁÔØ, ÐÏÔÏÍ + ÐÉÓÁÔØ. åÓÌÉ ÕÖ ÓÉÌØÎÏ ÐÒÉÓÐÉÞÉÔ, ÔÏ ÍÏÖÎÏ ÐÉÓÁÔØ ÎÁ asa@eed.miee.ru, + 2:5020/201.58 ÉÌÉ 2:5049/49.50, ÎÏ Ñ ÓÏ×ÓÅÍ ÎÅ ÇÁÒÁÎÔÉÒÕÀ, ÞÔÏ Ñ ÏÔ×ÅÞÕ. + +>============================================================================== diff --git a/docs/tips.os2 b/docs/tips.os2 new file mode 100644 index 0000000..379f858 --- /dev/null +++ b/docs/tips.os2 @@ -0,0 +1,113 @@ +------------------------------------------------------------------------------ +-- Recommendations for using Golded+ and other VIO-Applications ---------- +------------------------------------------------------------------------------ +[Falls Du an einer deutschen Version interessiert bist, melde dich und ich + werde es "=FCbersetzen".. ;)] + +The aim of this textfile is to give a suggestion on running Golded (and other +VIO-apps) in a very useful and aesthetic way. Give it a try and after getting +used to it you will love it that way. +I am using the great OS/2 Warp 4 on my system and so this text is mainly +directed to OS/2 users, but the main message should also be useful for all +other operating systems. +To get the mentioned programs just take a look at the end of this text. + +------------------------------------ + the right size +------------------------------------ + +This is my batch in which Golded+ is started on my system (by using +an hotkey assigned through PC/2 - it is really great btw to switch to tasks +that you use often by just typing ctrl-alt-g or something similar): + +------------------------ +-+--[golded2.cmd]------- +------------------------ +@echo off +rem ** change window size to 100 columns, 50 rows. +mode CON1 CO100,50 + +rem ** maximize window and make the borders thinner (3 pixel). +console -or+ -b3,3 +rem ** center the window on the desktop. simply calls 'winto.cmd hcenter top', +rem ** where winto.cmd is a batch file which comes along with console (see +rem ** above). +call center + +cd\utils\golded +gedemx.exe +------------------------ +-+--[/golded2.cmd]------ +------------------------ + +I use the 14x8-font for my VIO-windows with a graphic resolution of 1024x768. +To set the font of textwindows in OS/2 select the system menu of a window, +chose 'font size', change it to your needs and then 'save' it. All windows +will now use the new size. + +In winto.cmd (from console) which is called by center.cmd I made the following +settings: +------------------------ +-+--[winto.cmd]--------- +------------------------ +[...] + /* modify this depending on your settings */ + ScreenW =3D 1024 /*800*/; + ScreenH =3D 742 /*600*/; /*'742' because of WarpCenter*/ +[...] +------------------------ +-+--[/winto.cmd]-------- +------------------------ + +With this you get a VIO-window which gives me as many informations as it could +(100*50=3D5000 characters, 80*25=3D2000 chars) and looks as great as it could. + +All mentioned files can be frequested via FTN on my system at 2:2432/337 +(V34+, X75). + + CONSO010.ZIP 147K 24.10.97 Console Version 0.1.0 by Andrew Pavel + Zabolotny, Copyright (C) 1997 by FRIENDS + software. This utility addresses a problem + IBM is ignoring since first release of OS/2. + The problem is, you can define the default + size and position for *ALL* console win + Should be also on http://hobbes.nmsu.edu/pub/os2/ + + PC2V219C.ZIP 863K 15.11.99 PROGRAM COMMANDER/2 V2.20 for OS/2 + Copyright (C) by Roman Stangl November, 1999 + + PC/2 is a WPS enhancement or replacement, + that features a program + launcher, Virtual Desktops, Hotkey support, + Sliding focus, Advanced + Marking, Dynamic Menu Selection, Environment + Spaces, WIN95 key support, + QuickSwitch and SessionBar window, Hardware + Panning support, TitleBar + Smarticons, Lockup and Password protection + support, Scheduler, WPS + extraction and a Spooler Control Window + (which enables spooling even + when running PC/2 as a WPS replacement). + + Running PC/2 as the WPS replacement can save + about 4 MB precious RAM, + even on well equipped machines you can + notice decreased swapper size + and activity giving you a performance boost + compared to running the + WPS (due to the much smaller memory + requirements compared with the WPS). + + For those of you who want to know the + "tricks" used in PC/2, the full + source (requires long filename support) is + included, however it can be + The authors page: http://www.geocities.com/SiliconValley/Pines/7885/PC2/ + + +------------------------------------ +written by daniel hahler, 20.01.2000 + FidoNet: 2:2432/337 + email: tq@thequod.krysius.com + url: http://thequod.de (german) diff --git a/docs/tips.txt b/docs/tips.txt new file mode 100644 index 0000000..cacdddf --- /dev/null +++ b/docs/tips.txt @@ -0,0 +1,32 @@ +Tips and tricks +~~~~~~~~~~~~~~~ + +1. Don't you forgot that instalation of new version requires reading of + notework.txt? + +2. GoldED+ requires that your system environment properly configured for your + local rules: you should have properly configured locale (with country.sys, + Control Panel or LANG environment variable) and timezone info (with TZ + environment variable or Control Panel). + +3. To replace SoftCR with something on typing you should use EditSoftCRXlat + and DispSoftCR keywords. Starting from the version 1.1.3 you shouldn't + expirience significant problems with it. + +4. "Hi-ASCII-Char ...Macro ..." no longer works in old fashion due to + 'Hi-ASCII-Char' considered as case-insensitive character like it always + was done for ASCII characters. + +5. GoldED+ displays stylecode chars like GoldED 2.50 by default. If you don't + like this behaviour then take a look at StyleCodes keyword. + +6. To use CUA with "KeybDefaults No" you should define it. Though various + #Left is not described in manual they present ;-) I'll describe it when + it will be implemented in Linux version. + +7. Having problems with HPT? According to fidoconfig specification "\" + initiates escape-sequence which is properly processed by GoldED+ and not + processed by original fidoconfig library. You may consider using of + '-lame' option :-) + +8. If you want add something to this file - feel free to contact me. diff --git a/docs/todowork.txt b/docs/todowork.txt new file mode 100644 index 0000000..8d195bc --- /dev/null +++ b/docs/todowork.txt @@ -0,0 +1,76 @@ +______________________________________________________________________ + +This file is not up to date, some wishes still in my netmail/email +folders. +______________________________________________________________________ + +GoldED+ plans. As always I don't guarantee order of implementing +features and that to do list will be implemented at all. Any help will +be appreciated. +______________________________________________________________________ + +To do: + +* Deleting Synchronet messages, forward reply linking. +* Add Synchronet message base support (aim for 1.1.5). +* AreaYouWroteTo should be able to store copy of mail after change. +* Optionally add complete set of fidonet kludges to AreaIsEmail. +* E-mail/news signature support (or it already present? :)) +* SMTP support. +* Refresh message header after calling externutil. +* Try to save position in message after printing, changing xlat table, + etc. +* Wrapping /lnx screen output to ncurses (almost done). +* Major xlat/recode engine update (in progress). +* CUI in /lnx and input prompts. +* Activating built-in MIME-QP convertor by key (on whole message). +* Postpone. +* Highlight up to 3 groups of users by different color. +* Implicit address completion in addressbook. +* Addressbook sorting in various ways. +* Addressbook <-> macrofile synchronization +* Mouse support +* Better threading support. +* Read unread messages (either will be done via selection of unread + messages or when storing of unread status will be implemented). +* Add separators to Arealistformat, i.e. Arealistformat "A|E|G". +* Entering to locked area should allow to select another area instead. +* CODEPAGE kludge support. +* Message text preprocessing with externutil. +* Add *.* to attach path if not specified. +* Marking messages with reply in lister. +______________________________________________________________________ + +To fix: + +* Test SOS sound in DOS version. +* UUdecoder not 100% reliable: any volunteers for uulib maintaining? +* Adding e-mail's to addressbook from UUCP gated messages. +* QUOTEHARDTERM is always NO. +* Under sertain circumstances quotes incorrectly reflowed (seems like + it depends on QUOTEMARGIN keyword). +* Need some workarounds on -install feature under Linux (UNIX). +* Win32 (only when runned under Win9x) version does not support case + insensitive search of regexp's for high part of ASCII table. That's + a limitation of Microsoft CRTL, I can't do anything easy for that + but probably someday I provide a huge patch (I wonder if Microsoft + accept patches? =))... +______________________________________________________________________ + +Known wishes that not currently planned (any volunteers?): + +* FREQ catcher (not 100% reliable detects files) +* Interactive Twit-list edition. +* Pass areaname, message number, etc. to external utility. +* Hide empty areas / areas without new messages from arealist. +* NNTP support. +* Forward multiple messages. +* Peeking up message from area while in edit mode. +* Screen grabber. +* Language support for menu (ReadMainMenu). +* Mark areas with unsent mail. +* Trashcan for mail. +* Selection of codepage for outgoing message. +* Ability to change directory in attach picker. +* Any of your suggestion may be placed here ;-) +______________________________________________________________________ diff --git a/goldlib/gall/Makefile b/goldlib/gall/Makefile new file mode 100644 index 0000000..aee4c79 --- /dev/null +++ b/goldlib/gall/Makefile @@ -0,0 +1,22 @@ +# -*- makefile -*- + +TOP=../.. +TARGET=gall +INCS=-I$(TOP)/goldlib/gall +ifeq ($(findstring EMX, $(PATH)), EMX) +INCS+=-I$(TOP)/goldlib/glibc +else +ifeq ($(TERM),cygwin) +INCS+=-I$(TOP)/goldlib/glibc +endif +endif + +include $(TOP)/GNUmakef.inc + +ifeq ($(PLATFORM),emx) +ifeq ($(AR),emxomfar) +AR += -p32 +endif +endif + +include $(TOP)/GNUmakef.lib diff --git a/goldlib/gall/gall.all b/goldlib/gall/gall.all new file mode 100644 index 0000000..52d5abd --- /dev/null +++ b/goldlib/gall/gall.all @@ -0,0 +1,164 @@ + +## ------------------------------------------------------------------ +## The Goldware Library. Copyright (C) Odinn Sorensen. +## ------------------------------------------------------------------ +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## ------------------------------------------------------------------ +## $Id$ +## ------------------------------------------------------------------ +## Master build file. +## ------------------------------------------------------------------ + +## CRC and hash calculation. +gcrc16tb cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrc32tb cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrchash cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrckeyv cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrcm16 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrcm32 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrcs16 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gcrcs32 cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Compression +glzh cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Debugging. +gdbgerr cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gdbgexit cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gdbgtrk cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Directory handling. +gdirposx cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Expression evaluators. +geval cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gevalhum cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gevalrpn cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## File handling. +gfile cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gfilport cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gfilutl1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gfilutl2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## FTN address classes. +gftnaddr cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Nodelist index access classes. +gftnnl cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gftnnlfd cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gftnnlfu cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gftnnlge cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gftnnlv7 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Keyboard. +gkbdbase cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gkbdgetm cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gkbdunix cpp all nov lnx +gkbdwait cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Logfile class. +glog cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Misc. memory stuff. +gmemdbg cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmemutil cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Mouse. +gmoubase cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Message attributes. +gmsgattr cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Message handling. +ghdrmime cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## GoldED printer definition strings. +gprnutil cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## UNIX signals. +gsigunix cpp all nov lnx + +## Sound. +gsnd cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gsndwrap cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Strings. +gstrbags cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gstrctyp cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gstrmail cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gstrname cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gstrutil cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Time related. +gtimjuld cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gtimutil cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Text searching. +gbmh cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gfuzzy cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gregex cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwildmat cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gsearch cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gsrchmgr cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Text processing. +gtxtpara cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## BBS userbase access. +gusrbase cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrezyc cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrgold cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrhuds cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrmax cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrpcb cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrra2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gusrxbbs cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Miscellaneous utility. +gutlclip cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gutlcode cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gutlgrp cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gutlmisc cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gutlmtsk cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gutltag cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gutlvers cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## OS specific utilities +gutldos cpp all djg +gutlos2 cpp all bco wco emx +gutlos2m cpp all bco wco emx +gutlwin cpp all bcx cyg +gutlwinm cpp all bcx cyg + +## Low-level text video +gvidbase cpp all nov bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gvidinit cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## Text windowing. +gwinbase cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwindow cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinhlp1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinhlp2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwininit cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinline cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinmenu cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinmnub cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinpckf cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinpcks cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinpick cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gwinput2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +## ------------------------------------------------------------------ diff --git a/goldlib/gall/gasmamis.h b/goldlib/gall/gasmamis.h new file mode 100644 index 0000000..d97d207 --- /dev/null +++ b/goldlib/gall/gasmamis.h @@ -0,0 +1,42 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gasmamis_h +#define __gasmamis_h + + +// ------------------------------------------------------------------ + +struct amis_signature { + char manufacturer[8]; + char product_name[8]; + char product_description[64]; +} __attribute__((packed)); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gbmh.cpp b/goldlib/gall/gbmh.cpp new file mode 100644 index 0000000..17b0089 --- /dev/null +++ b/goldlib/gall/gbmh.cpp @@ -0,0 +1,134 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Boyer-Moore-Horspool pattern match. +// ------------------------------------------------------------------ +// Based on Public Domain version by Thad Smith 7/21/1992, based on a +// 7/92 public domain BMH version by Raymond Gardner. +// With fixes found by Jeff Dunlop 10/21/93. +// ------------------------------------------------------------------ + + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +gbmh::gbmh() { + + pat = NULL; +} + + +// ------------------------------------------------------------------ + +gbmh::~gbmh() { + + throw_deletearray(pat); +} + + +// ------------------------------------------------------------------ + +void gbmh::init(const char* pattern, bool ignorecase) { + + ignore_case = ignorecase; + patlen = strlen(pattern); + + pat = new char [patlen+1]; + throw_new(pat); + + // Copy pattern + strcpy(pat, pattern); + if(ignore_case) + strupr(pat); + + // initialize skip array + int i; + for(i=0; i<256; i++) + skip[i] = patlen; + for(i=0; i= 0) + return false; + + buffer += buflen; + + while(1) { + + while((i += skip[buffer[i]]) < 0) + ; + + if(i < (INT_MAX - buflen)) + return false; + + i -= INT_MAX; + int j = patlen - 1; + const char* s = buffer + (i - j); + + if(ignore_case) { + while(--j >= 0 and toupper(s[j]) == pat[j]) + ; + } + else { + while(--j >= 0 and s[j] == pat[j]) + ; + } + + if(j < 0) + return true; + + if((i += skip2) >= 0) + return false; + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gbmh.h b/goldlib/gall/gbmh.h new file mode 100644 index 0000000..8fb086c --- /dev/null +++ b/goldlib/gall/gbmh.h @@ -0,0 +1,65 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Case-Insensitive Boyer-Moore-Horspool pattern match +// ------------------------------------------------------------------ + +#ifndef __gbmh_h +#define __gbmh_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class gbmh { + +protected: + + int skip[256]; // skip-ahead count for test chars + int skip2; // skip-ahead after non-match with matching final char + char* pat; + int patlen; + bool ignore_case; + +public: + + gbmh(); + ~gbmh(); + + void init(const char* pattern, bool ignorecase); + bool find(const char* string); + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gcmpall.h b/goldlib/gall/gcmpall.h new file mode 100644 index 0000000..6cf8d84 --- /dev/null +++ b/goldlib/gall/gcmpall.h @@ -0,0 +1,111 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Compiler dependent definitions. +// ------------------------------------------------------------------ + +#ifndef __gcmpall_h +#define __gcmpall_h + + +// ------------------------------------------------------------------ + +#define GOLD_CANPACK +#define NW(x) x=x + + +// ------------------------------------------------------------------ + +#if !defined(__MSDOS__) + #if defined(MSDOS) + #define __MSDOS__ MSDOS + #elif defined(__DOS__) + #define __MSDOS__ __DOS__ + #endif +#endif + +#if !defined(__OS2__) + #if defined(OS2) + #define __OS2__ OS2 + #elif defined(__EMX__) && !defined(__WIN32__) + #define __OS2__ __EMX__ + #endif +#endif + +#if !defined(__WIN32__) + #if defined(_WIN32) + #define __WIN32__ _WIN32 + #elif defined(__NT__) + #define __WIN32__ __NT__ + #endif +#endif + +#if !defined(__UNIX__) + #if defined(__linux__) + #define __UNIX__ __linux__ + #endif + #if defined(__FreeBSD__) + #define __UNIX__ __FreeBSD__ + #endif + #if defined(__OpenBSD__) + #define __UNIX__ __OpenBSD__ + #endif +#endif + +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +#error You definetly need to upgrade your gcc at least up to 2.8.x +#endif + + +// ------------------------------------------------------------------ +// Check if type "char" is unsigned or signed + +#if '\x80' < 0 +#error Goldware Library requires -funsigned-char to operate properly +#endif + + +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) || defined(__OS2__) || defined(__WIN32__) +#define __HAVE_DRIVES__ +#endif + + +// ------------------------------------------------------------------ +// System-wide constants + +//#define GOLD_MOUSE 1 // Enable mouse code + +#define GTHROW_LOG +#define GTHROW_DEBUG +#define GTHROWCHKPTR_ENABLE +#define GFTRK_ENABLE + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gcrc16tb.cpp b/goldlib/gall/gcrc16tb.cpp new file mode 100644 index 0000000..1679877 --- /dev/null +++ b/goldlib/gall/gcrc16tb.cpp @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing +// ------------------------------------------------------------------ + + +#include + + +// ------------------------------------------------------------------ +// Quickie table for CRC-16 calculations +// +// This CRC-16 table was originally calculated by Mark G. Mendel, +// Network Systems Corporation. +// ------------------------------------------------------------------ + +word __crc16_table[256] = { + + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gcrc32tb.cpp b/goldlib/gall/gcrc32tb.cpp new file mode 100644 index 0000000..8c7bde7 --- /dev/null +++ b/goldlib/gall/gcrc32tb.cpp @@ -0,0 +1,157 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Quickie table for CRC-32 calculations +// +// Copyright (C) 1986 Gary S. Brown. You may use this table as +// desired without restriction. +// +// First, the polynomial itself and its table of feedback terms. The +// polynomial is +// +// X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 +// +// Note that we take it "backwards" and put the highest-order term in +// the lowest-order bit. The X^32 term is "implied"; the LSB is the +// X^31 term, etc. The X^0 term (usually shown as "+1") results in +// the MSB being 1. +// +// Note that the usual hardware shift register implementation, which +// is what we're using (we're merely optimizing it by doing eight-bit +// chunks at a time) shifts bits into the lowest-order term. In our +// implementation, that means shifting towards the right. Why do we +// do it this way? Because the calculated CRC must be transmitted in +// order from highest-order term to lowest-order term. UARTs transmit +// characters in order from LSB to MSB. By storing the CRC this way, +// we hand it to the UART in the order low-byte to high-byte; the +// UART sends each low-bit to hight-bit; and the result is trans- +// mission bit by bit from highest- to lowest-order term without re- +// quiring any bit shuffling on our part. Reception works similarly. +// +// The feedback terms table consists of 256, 32-bit entries. Notes: +// +// 1. The table can be generated at runtime if desired; code to do +// so is shown later [ED: Nope]. It might not be obvious, but the +// feedback terms simply represent the results of eight shift/xor +// operations for all combinations of data and CRC register +// values. +// +// 2. The CRC accumulation logic is the same for all CRC polyno- +// mials, be they sixteen or thirty-two bits wide. You simply +// choose the appropriate table. Alternatively, because the table +// can be generated at runtime, you can start by generating the +// table for the polynomial in question and use exactly the same +// "updcrc", if your application needn't simultaneously handle +// two CRC polynomials. (Note, however, that XMODEM is strange.) +// +// 3. For 16-bit CRCs, the table entries need be only 16 bits wide; +// of course, 32-bit entries work OK if the high 16 bits are +// zero. +// +// 4. The values must be right-shifted by eight bits by the "updcrc" +// logic; the shift must be unsigned (bring in zeroes). On some +// hardware you could probably optimize the shift in assembler by +// using byte-swap instructions. [ED: But we let the compiler +// worry about the details in this implementation...] +// +// 5. The CRC-32 polynomial value is: 0xEDB88320. +// +// ------------------------------------------------------------------ + +dword __crc32_table[256] = { + + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, + 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, + 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, + 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, + 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, + 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, + 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, + 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, + 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, + 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, + 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, + 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, + 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, + 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, + 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, + 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, + 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, + 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, + 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, + 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, + 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, + 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, + 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, + 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, + 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, + 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, + 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, + 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, + 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, + 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, + 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, + 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, + 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, + 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, + 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, + 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, + 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, + 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, + 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, + 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, + 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, + 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, + 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, + 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, + 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, + 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, + 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, + 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, + 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, + 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, + 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, + 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL +}; + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gcrcall.h b/goldlib/gall/gcrcall.h new file mode 100644 index 0000000..09879fb --- /dev/null +++ b/goldlib/gall/gcrcall.h @@ -0,0 +1,90 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing. +// ------------------------------------------------------------------ + +#ifndef __gcrcall_h +#define __gcrcall_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Declare the CRC tables + +extern word __crc16_table[]; +extern dword __crc32_table[]; + + +// ------------------------------------------------------------------ +// Generate/update a CRC-16 or CRC-32 value +// +// These inline functions were derived from various #define macro +// implementations. Some of those implementations masked the right +// shifts to ensure correct zero fill. But this is C++, where zero +// fill is guaranteed for unsigned operands, and besides we use +// prototyped unsigned parameters anyway, so we have no problem here. + +inline word updCrc16(byte ch, word crc) { return (word)(__crc16_table[byte(crc >> 8)] ^ (crc << 8) ^ (ch)); } +inline dword updCrc32(byte ch, dword crc) { return (dword)(__crc32_table[byte(crc) ^ byte(ch)] ^ (crc >> 8)); } + + +// ------------------------------------------------------------------ +// Define CRC masks in the "normal" and "CCITT" variants + +const word CRC16_MASK_NORMAL = 0; +const word CRC16_MASK_CCITT = 0xFFFFU; +const dword CRC32_MASK_NORMAL = 0; +const dword CRC32_MASK_CCITT = 0xFFFFFFFFUL; + + +// ------------------------------------------------------------------ +// Prototypes + +word strCrc16(const char* s, bool nocase=true, word mask=CRC16_MASK_NORMAL); +dword strCrc32(const char* s, bool nocase=true, dword mask=CRC32_MASK_NORMAL); + +dword strHash32(const char* s, bool nocase=true); + +word memCrc16(const void* m, long l, bool nocase=true, word mask=CRC16_MASK_NORMAL); +dword memCrc32(const void* m, long l, bool nocase=true, dword mask=CRC32_MASK_NORMAL); + +// ------------------------------------------------------------------ +// Get keyword/value pairs and crc + +void getkeyval(char** key, char** val); +void getkeyvaleql(char** key, char** val, bool eql); +word getkeyvalcrc(char** key, char** val); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gcrchash.cpp b/goldlib/gall/gcrchash.cpp new file mode 100644 index 0000000..c2e761e --- /dev/null +++ b/goldlib/gall/gcrchash.cpp @@ -0,0 +1,63 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Hash value generation +// ------------------------------------------------------------------ +// From the Maximus/Squish MSGAPI by Scott J. Dudley, 1991. +// The prime is 65521. Whatever that means.. ;-) +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Generate 32-bit hash value from string + +dword strHash32(const char* s, bool __case) { + + const char* p = s; + dword g, hash = 0; + + while(*p) { + + hash = (hash << 4) + (__case ? tolower(*p) : *p); + + g = hash & 0xF0000000UL; + if(g) { + hash |= g >> 24; + hash |= g; + } + p++; + } + + return hash & 0x7FFFFFFFUL; // Strip off high bit (used as a flag) +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gcrckeyv.cpp b/goldlib/gall/gcrckeyv.cpp new file mode 100644 index 0000000..d37a7a4 --- /dev/null +++ b/goldlib/gall/gcrckeyv.cpp @@ -0,0 +1,155 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Split current value (val) into keyword (key) and new value +// If "eql" is true, the '=' char is a keyword separator char. + +void getkeyvaleql(char** key, char** val, bool eql) { + + // Skip leading whitespace + char *p = strskip_wht(*val); + + // Get the keyword + switch(*p) { + + // Strip "double" quotes + case '\"': + *key = ++p; + do { + p = strskip_to(p, '\"'); + if(not *p or (*(p-1) != '\\')) + break; + else + p++; + } while(*p); + break; + + // Strip 'single' quotes + case '\'': + *key = ++p; + do { + p = strskip_to(p, '\''); + if(not *p or (*(p-1) != '\\')) + break; + else + p++; + } while(*p); + break; + + // Strip round brackets + case '(': /*)*/ + *key = ++p; + p = strskip_to(p, /*(*/ ')'); + break; + + // Get straight keyword + default: + *key = p; + while(*p and not isspace(*p)) { + if(eql and (*p == '=')) + break; + p++; + } + } + + // Nul-terminate keyword and remove trailing comma if any + if(*p) { + if((*p != '\"') and (*p != '\'') and (*p != /*(*/ ')')) { + char* q = p; + while(*(--q) == ',') + *q = NUL; + } + *p++ = NUL; + } + + // Skip whitespace and '=' if any + p = strskip_wht(p); + if(eql and (*p == '=')) + p = strskip_wht(++p); + + // Get the value + *val = p; + + // Handle comments, allowing ;'s in quoted strings + while(*p and *p != ';') { + if((*p == '\"') and (*(p-1) != '\\')) { + p++; + while(*p and not ((*p == '\"') and (*(p-1) != '\\'))) + p++; + } + if(*p) + p++; + } + *p = NUL; + + // Trim whitespace from end of value + p = *val; + if(*p) { + p = strskip_to(p, NUL); + while((*(--p) <= ' ') and *p) + *p = NUL; + } + strschg(*key, "\\\"", "\""); +} + + +// ------------------------------------------------------------------ +// Split current value (val) into keyword (key) and new value + +void getkeyval(char** key, char** val) { + + getkeyvaleql(key, val, false); +} + + +// ------------------------------------------------------------------ +// Get keyword and value and calculate/return CRC16 of keyword + +word getkeyvalcrc(char** key, char** val) { + + // First get keyword and value + getkeyvaleql(key, val, false); + + // Init variables + char* p = *key; + word c = 0; + + // Calculate CRC16 of keyword + while(*p) + c = updCrc16((byte)toupper(*p++), c); + + // Return keyword CRC + return c; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gcrcm16.cpp b/goldlib/gall/gcrcm16.cpp new file mode 100644 index 0000000..8077d66 --- /dev/null +++ b/goldlib/gall/gcrcm16.cpp @@ -0,0 +1,53 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +word memCrc16(const void* _m, long l, bool __case, word mask) { + + long n; + word crc = mask; + const char *m = (const char *)_m; + + if(__case) { + for(n=0; n +#include + + +// ------------------------------------------------------------------ +// Generate CRC-32 of a memory block + +dword memCrc32(const void* _m, long l, bool __case, dword mask) { + + long n; + dword crc = mask; + const char *m = (const char *)_m; + + if(__case) { + for(n=0; n +#include + + +// ------------------------------------------------------------------ +// Generate CRC-16 of a normal nul-terminated string + +word strCrc16(const char* s, bool __case, word mask) { + + word crc = mask; + + if(__case) { + while(*s) + crc = updCrc16(toupper(*s++), crc); + } + else { + while(*s) + crc = updCrc16(*s++, crc); + } + + return crc; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gcrcs32.cpp b/goldlib/gall/gcrcs32.cpp new file mode 100644 index 0000000..3b75445 --- /dev/null +++ b/goldlib/gall/gcrcs32.cpp @@ -0,0 +1,53 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// CRC-16, CRC-32 and Hashing +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Generate CRC-32 of a normal nul-terminated string + +dword strCrc32(const char* s, bool __case, dword mask) { + + dword crc = mask; + + if(__case) { + while(*s) + crc = updCrc32(toupper(*s++), crc); + } + else { + while(*s) + crc = updCrc32(*s++, crc); + } + + return crc; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gctype.h b/goldlib/gall/gctype.h new file mode 100644 index 0000000..b907bbc --- /dev/null +++ b/goldlib/gall/gctype.h @@ -0,0 +1,62 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Portable NLS functions for ctype. +// ------------------------------------------------------------------ + +#ifndef __gctype_h +#define __gctype_h + + +// ------------------------------------------------------------------ + +#include +#include +#ifdef __BORLANDC__ +#define __USELOCALES__ +#elif defined(__EMX__) +#define _CTYPE_FUN +#endif +#include +#if defined(__EMX__) +#include +#define tolower(a) _nls_tolower((unsigned char)(a)) +#define toupper(a) _nls_toupper((unsigned char)(a)) +#elif defined(__WIN32__) +extern char tl[256], tu[256]; +inline char tolower(char c) { return tl[c]; } +inline char toupper(char c) { return tu[c]; } +#endif + + +// ------------------------------------------------------------------ + +inline int iswhite(char c) { return c < '!' and c; } +inline int isxalnum(char c) { return isalnum(c) or (c >= 128); } + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gcurses.h b/goldlib/gall/gcurses.h new file mode 100644 index 0000000..6160936 --- /dev/null +++ b/goldlib/gall/gcurses.h @@ -0,0 +1,248 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1989 Free Software Foundation +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// This file is derived from the GNU C++ Library. +// Written by Eric Newton (newton@rocky.oswego.edu) +// ------------------------------------------------------------------ + +#ifndef __gcurses_h +#define __gcurses_h + +// ------------------------------------------------------------------ + +// Even many system which mostly have C++-ready header files, +// do not have C++-ready curses.h. +extern "C" { +#ifdef __FreeBSD__ +#include +#else +#include +#endif +} + + +// ------------------------------------------------------------------ + +// "Convert" macros to inlines, if needed. +#ifdef addch +inline int (addch)(char ch) { return addch(ch); } +#undef addch +#endif +#ifdef addstr +// The (char*) cast is to hack around missing const's +inline int (addstr)(const char * str) { return addstr((char*)str); } +#undef addstr +#endif +#ifdef clear +inline int (clear)() { return clear(); } +#undef clear +#endif +#ifdef clearok +inline int (clearok)(WINDOW* win, bool bf) { return clearok(win, bf); } +#undef clearok +#else +extern "C" int clearok(WINDOW*, bool); +#endif +#ifdef clrtobot +inline int (clrtobot)() { return clrtobot(); } +#undef clrtobot +#endif +#ifdef clrtoeol +inline int (clrtoeol)() { return clrtoeol(); } +#undef clrtoeol +#endif +#ifdef delch +inline int (delch)() { return delch(); } +#undef delch +#endif +#ifdef deleteln +inline int (deleteln)() { return deleteln(); } +#undef deleteln +#endif +#ifdef erase +inline int (erase)() { return erase(); } +#undef erase +#endif +#ifdef flushok +inline int (flushok)(WINDOW* _win, int _bf) { return flushok(_win, _bf); } +#undef flushok +#else +#define _no_flushok +#endif +#ifdef getch +inline int (getch)() { return getch(); } +#undef getch +#endif +#ifdef getstr +inline int (getstr)(char *_str) { return getstr(_str); } +#undef getstr +#endif +#ifdef getyx +inline void (getyx)(WINDOW* win, int& y, int& x) { getyx(win, y, x); } +#undef getyx +#endif +#ifdef inch +inline chtype (inch)() { return inch(); } +#undef inch +#endif +#ifdef insch +inline int (insch)(char c) { return insch(c); } +#undef insch +#endif +#ifdef insertln +inline int (insertln)() { return insertln(); } +#undef insertln +#endif +#ifdef leaveok +inline int (leaveok)(WINDOW* win, bool bf) { return leaveok(win, bf); } +#undef leaveok +#else +extern "C" int leaveok(WINDOW* win, bool bf); +#endif +#ifdef move +inline int (move)(int x, int y) { return move(x, y); } +#undef move +#endif +#ifdef refresh +inline int (rfresh)() { return refresh(); } +#undef refresh +#endif +#ifdef scrollok +inline int (scrollok)(WINDOW* win, bool bf) { return scrollok(win, bf); } +#undef scrollok +#else +#ifndef hpux +extern "C" int scrollok(WINDOW*, bool); +#else +extern "C" int scrollok(WINDOW*, char); +#endif +#endif +#ifdef standend +inline int (standend)() { return standend(); } +#undef standend +#endif +#ifdef standout +inline int (standout)() { return standout(); } +#undef standout +#endif +#ifdef wstandend +inline int (wstandend)(WINDOW *win) { return wstandend(win); } +#undef wstandend +#endif +#ifdef wstandout +inline int (wstandout)(WINDOW *win) { return wstandout(win); } +#undef wstandout +#endif +#ifdef winch +inline chtype (winch)(WINDOW* win) { return winch(win); } +#undef winch +#endif + +// deal with conflicting macros in ncurses.h which is SYSV based +#ifdef box +inline int _G_box(WINDOW* win, chtype v, chtype h) {return box(win, v, h); } +#undef box +inline int box(WINDOW* win, chtype v, chtype h) {return _G_box(win, v, h); } +#endif +#ifdef scroll +inline int (scroll)(WINDOW* win) { return scroll(win); } +#undef scroll +#endif +#ifdef touchwin +inline int (touchwin)(WINDOW* win) { return touchwin(win); } +#undef touchwin +#endif + +#ifdef mvwaddch +inline int (mvwaddch)(WINDOW *win, int y, int x, char ch) +{ return mvwaddch(win, y, x, ch); } +#undef mvwaddch +#endif +#ifdef mvwaddstr +inline int (mvwaddstr)(WINDOW *win, int y, int x, const char * str) +{ return mvwaddstr(win, y, x, (char*)str); } +#undef mvwaddstr +#endif +#ifdef mvwdelch +inline int (mvwdelch)(WINDOW *win, int y, int x) { return mvwdelch(win, y, x);} +#undef mvwdelch +#endif +#ifdef mvwgetch +inline int (mvwgetch)(WINDOW *win, int y, int x) { return mvwgetch(win, y, x);} +#undef mvwgetch +#endif +#ifdef mvwgetstr +inline int (mvwgetstr)(WINDOW *win, int y, int x, char *str) +{return mvwgetstr(win,y,x, str);} +#undef mvwgetstr +#endif +#ifdef mvwinch +inline chtype (mvwinch)(WINDOW *win, int y, int x) { return mvwinch(win, y, x);} +#undef mvwinch +#endif +#ifdef mvwinsch +inline int (mvwinsch)(WINDOW *win, int y, int x, char c) +{ return mvwinsch(win, y, x, c); } +#undef mvwinsch +#endif + +#ifdef mvaddch +inline int (mvaddch)(int y, int x, char ch) +{ return mvaddch(y, x, ch); } +#undef mvaddch +#endif +#ifdef mvaddstr +inline int (mvaddstr)(int y, int x, const char * str) +{ return mvaddstr(y, x, (char*)str); } +#undef mvaddstr +#endif +#ifdef mvdelch +inline int (mvdelch)(int y, int x) { return mvdelch(y, x);} +#undef mvdelch +#endif +#ifdef mvgetch +inline int (mvgetch)(int y, int x) { return mvgetch(y, x);} +#undef mvgetch +#endif +#ifdef mvgetstr +inline int (mvgetstr)(int y, int x, char *str) {return mvgetstr(y, x, str);} +#undef mvgetstr +#endif +#ifdef mvinch +inline chtype (mvinch)(int y, int x) { return mvinch(y, x);} +#undef mvinch +#endif +#ifdef mvinsch +inline int (mvinsch)(int y, int x, char c) +{ return mvinsch(y, x, c); } +#undef mvinsch +#endif + +extern int curses_initialized; + +// ------------------------------------------------------------------ + +#endif // __gcurses_h + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdbgerr.cpp b/goldlib/gall/gdbgerr.cpp new file mode 100644 index 0000000..4e0eabc --- /dev/null +++ b/goldlib/gall/gdbgerr.cpp @@ -0,0 +1,82 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Debugging and logging. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +int errorlevel = 0; +int error_exit = 0; + +char* etext[] = { + "No", + "Open", + "Read", + "Seek", + "Memory", + "Index", + "Write", + "Tell", + "Close", + "Config", + "Break", + "NoKeys", + "Test", + "Environment", + "Lock", + "Pointer", + "" +}; + + +// ------------------------------------------------------------------- + +static char gerrbuf[100]; + + +// ------------------------------------------------------------------- + +char* gerrinfo(int __type, const char* __file, int __line) { + + sprintf(gerrbuf, "%s error exit at [%s,%u].", etext[__type], CleanFilename(__file), __line); + return gerrbuf; +} + + +// ------------------------------------------------------------------- + +char* gerrosinfo() { + + sprintf(gerrbuf, "%s reports error %u: %s.", ggetosstring(), errno, strerror(errno)); + return gerrbuf; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdbgerr.h b/goldlib/gall/gdbgerr.h new file mode 100644 index 0000000..eeae0f4 --- /dev/null +++ b/goldlib/gall/gdbgerr.h @@ -0,0 +1,187 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Debugging and logging. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GDBGERR_H +#define __GDBGERR_H + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Error codes + +#define GOLD_NO_ERROR 0 + + +// ------------------------------------------------------------------ +// Debug aid macros + +#define GDEBUGINFO __FILE__, __LINE__ +#define GDEBUGDATA GDEBUGFILE, GDEBUGLINE +#define GDEBUGPROTO char* GDEBUGFILE, int GDEBUGLINE + + +// ------------------------------------------------------------------ +// Automatic inline debugging info for use with _halt_() + +#define E_INFO __FILE__,__LINE__ +#define E_PROTO int _error_, char* _file_, int _line_ +#define E_DATA _error_, _file_, _line_ + + +// ------------------------------------------------------------------ +// Error types for use with _halt_() + +const int ERR_OK = 0; +const int ERR_OPEN = 1; +const int ERR_READ = 2; +const int ERR_SEEK = 3; +const int ERR_MEMO = 4; +const int ERR_INDX = 5; +const int ERR_WRITE = 6; +const int ERR_TELL = 7; +const int ERR_CLOSE = 8; +const int ERR_CONF = 9; +const int ERR_BREAK = 10; +const int ERR_NOKEY = 11; +const int ERR_TEST = 12; +const int ERR_ENVR = 13; +const int ERR_LOCK = 14; +const int ERR_MPTR = 15; + +#define E_OK ERR_OK , E_INFO +#define E_OPEN ERR_OPEN , E_INFO +#define E_READ ERR_READ , E_INFO +#define E_SEEK ERR_SEEK , E_INFO +#define E_MEMO ERR_MEMO , E_INFO +#define E_INDX ERR_INDX , E_INFO +#define E_WRITE ERR_WRITE, E_INFO +#define E_TELL ERR_TELL , E_INFO +#define E_CLOSE ERR_CLOSE, E_INFO +#define E_CONF ERR_CONF , E_INFO +#define E_BREAK ERR_BREAK, E_INFO +#define E_NOKEY ERR_NOKEY, E_INFO +#define E_TEST ERR_TEST , E_INFO +#define E_ENVR ERR_ENVR , E_INFO +#define E_LOCK ERR_LOCK , E_INFO +#define E_MPTR ERR_MPTR , E_INFO + + +// ------------------------------------------------------------------ +// Prototypes + +extern int errorlevel; +extern int error_exit; +extern char* etext[]; +void ErrorExit(int type); + + +// ------------------------------------------------------------------ + +char* gerrinfo(int __type, const char* __file, int __line); +char* gerrosinfo(); + + +// ------------------------------------------------------------------ + +#define gerropen() gerrinfo(ERR_OPEN, __FILE__, __LINE__) +#define gerrread() gerrinfo(ERR_READ, __FILE__, __LINE__) +#define gerrseek() gerrinfo(ERR_SEEK, __FILE__, __LINE__) +#define gerrmemory() gerrinfo(ERR_MEMO, __FILE__, __LINE__) +#define gerrindex() gerrinfo(ERR_INDX, __FILE__, __LINE__) +#define gerrwrite() gerrinfo(ERR_WRITE, __FILE__, __LINE__) +#define gerrtell() gerrinfo(ERR_TELL, __FILE__, __LINE__) +#define gerrclose() gerrinfo(ERR_CLOSE, __FILE__, __LINE__) +#define gerrconfig() gerrinfo(ERR_CONF, __FILE__, __LINE__) +#define gerrbreak() gerrinfo(ERR_BREAK, __FILE__, __LINE__) +#define gerrnokey() gerrinfo(ERR_NOKEY, __FILE__, __LINE__) +#define gerrtest() gerrinfo(ERR_TEST, __FILE__, __LINE__) +#define gerrenvr() gerrinfo(ERR_ENVR, __FILE__, __LINE__) +#define gerrlock() gerrinfo(ERR_LOCK, __FILE__, __LINE__) +#define gerrpointer() gerrinfo(ERR_MPTR, __FILE__, __LINE__) + +#define erropen(f,l) printf("! %s", gerrinfo(ERR_OPEN, f,l)) +#define errread(f,l) printf("! %s", gerrinfo(ERR_READ, f,l)) +#define errseek(f,l) printf("! %s", gerrinfo(ERR_SEEK, f,l)) +#define errmemory(f,l) printf("! %s", gerrinfo(ERR_MEMO, f,l)) +#define errindex(f,l) printf("! %s", gerrinfo(ERR_INDX, f,l)) +#define errwrite(f,l) printf("! %s", gerrinfo(ERR_WRITE, f,l)) +#define errtell(f,l) printf("! %s", gerrinfo(ERR_TELL, f,l)) +#define errclose(f,l) printf("! %s", gerrinfo(ERR_CLOSE, f,l)) +#define errconfig(f,l) printf("! %s", gerrinfo(ERR_CONF, f,l)) +#define errbreak(f,l) printf("! %s", gerrinfo(ERR_BREAK, f,l)) +#define errnokey(f,l) printf("! %s", gerrinfo(ERR_NOKEY, f,l)) +#define errtest(f,l) printf("! %s", gerrinfo(ERR_TEST, f,l)) +#define errenvr(f,l) printf("! %s", gerrinfo(ERR_ENVR, f,l)) +#define errlock(f,l) printf("! %s", gerrinfo(ERR_LOCK, f,l)) +#define errpointer(f,l) printf("! %s", gerrinfo(ERR_MPTR, f,l)) + +#define ErrOpen() erropen(__FILE__,__LINE__) +#define ErrRead() errread(__FILE__,__LINE__) +#define ErrSeek() errseek(__FILE__,__LINE__) +#define ErrMemory() errmemory(__FILE__,__LINE__) +#define ErrIndex() errindex(__FILE__,__LINE__) +#define ErrWrite() errwrite(__FILE__,__LINE__) +#define ErrTell() errtell(__FILE__,__LINE__) +#define ErrClose() errclose(__FILE__,__LINE__) +#define ErrConfig() errconfig(__FILE__,__LINE__) +#define ErrBreak() errbreak(__FILE__,__LINE__) +#define ErrNokey() errnokey(__FILE__,__LINE__) +#define ErrTest() errtest(__FILE__,__LINE__) +#define ErrEnvr() errenvr(__FILE__,__LINE__) +#define ErrLock() errlock(__FILE__,__LINE__) +#define ErrPointer() errpointer(__FILE__,__LINE__) +#define ErrOSInfo() printf(": %s", gerrosinfo()) + +#define OpenErrorExit() ErrorExit(ERR_OPEN) +#define ReadErrorExit() ErrorExit(ERR_READ) +#define SeekErrorExit() ErrorExit(ERR_SEEK) +#define MemoryErrorExit() ErrorExit(ERR_MEMO) +#define IndexErrorExit() ErrorExit(ERR_INDX) +#define WriteErrorExit() ErrorExit(ERR_WRITE) +#define TellErrorExit() ErrorExit(ERR_TELL) +#define CloseErrorExit() ErrorExit(ERR_CLOSE) +#define ConfigErrorExit() ErrorExit(ERR_CONF) +#define BreakErrorExit() ErrorExit(ERR_BREAK) +#define NokeyErrorExit() ErrorExit(ERR_NOKEY) +#define TestErrorExit() ErrorExit(ERR_TEST) +#define EnvrErrorExit() ErrorExit(ERR_ENVR) +#define LockErrorExit() ErrorExit(ERR_LOCK) +#define PointerErrorExit() ErrorExit(ERR_MPTR) + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdbgexit.cpp b/goldlib/gall/gdbgexit.cpp new file mode 100644 index 0000000..4c81651 --- /dev/null +++ b/goldlib/gall/gdbgexit.cpp @@ -0,0 +1,47 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Debugging and logging. +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Error exit function + +void ErrorExit(int type) { + + static int in_error_exit = false; + + if(not in_error_exit++) { + error_exit = type; + if(type) + exit(errorlevel); + exit(0); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdbgtrk.cpp b/goldlib/gall/gdbgtrk.cpp new file mode 100644 index 0000000..2ab8670 --- /dev/null +++ b/goldlib/gall/gdbgtrk.cpp @@ -0,0 +1,146 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Function tracker. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GFTRK_ENABLE) + + +// ------------------------------------------------------------------ +// Externals + +extern glog LOG; + + +// ------------------------------------------------------------------ +// Global vars + +int __gftrk = false; +int __gftrk_on = true; +int __gftrk_max = 50; +int __gftrk_curr; +int __gftrk_indent; +GFTrk* __gftrk_ptr; +GFTrk* __gftrk_list; + +int __gftrk_statusline = false; + + +// ------------------------------------------------------------------ + +static void __gftrk_term(void) { + + if(__gftrk) + free(__gftrk_list); +} + + +// ------------------------------------------------------------------ + +void __gftrk_init(int trackmax) { + + if(trackmax != -1) + __gftrk_max = trackmax; + __gftrk_list = (GFTrk*)calloc(__gftrk_max, sizeof(GFTrk)); + if(__gftrk_list) { + __gftrk = true; + __gftrk_curr = 0; + __gftrk_indent = 0; + atexit(__gftrk_term); + } +} + + +// ------------------------------------------------------------------ + +extern bool cmdlinedebughg; +void update_statusline(const char* info); + +void __gftrk_track(const char* text) { + + if(__gftrk_on) { + if(text) { + __gftrk_ptr = __gftrk_list + __gftrk_curr; + __gftrk_ptr->tick = clock(); + __gftrk_ptr->text = *text ? text : text+1; + __gftrk_ptr->indent = __gftrk_indent; + if(*text) { + __gftrk_indent++; + if(__gftrk_statusline) + update_statusline(text); + if(cmdlinedebughg) + LOG.printf("- %08lu %*s%s", __gftrk_ptr->tick, __gftrk_ptr->indent*2, "", __gftrk_ptr->text); + } + __gftrk_curr = (++__gftrk_curr) % __gftrk_max; + } + else { + __gftrk_indent--; + } + if(__gftrk_statusline) + THROW_CHECK(); + } +} + + +// ------------------------------------------------------------------ + +void __gftrk_log() { + + if(__gftrk) { + int _curr = __gftrk_curr - 1; + if(_curr == -1) + _curr = __gftrk_max - 1; + int _count = 0; + int _first = true; + while(_count < __gftrk_max) { + GFTrk* _ptr = __gftrk_list + _curr; + if(_ptr->text) { + if(_first) { + LOG.printf("! Function track dump follows:"); + _first = false; + } + LOG.printf("- %08lu %*s%s", _ptr->tick, _ptr->indent*2, "", _ptr->text); + } + _count++; + _curr--; + if(_curr == -1) + _curr = __gftrk_max - 1; + } + } +} + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdbgtrk.h b/goldlib/gall/gdbgtrk.h new file mode 100644 index 0000000..3984c7f --- /dev/null +++ b/goldlib/gall/gdbgtrk.h @@ -0,0 +1,82 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Function tracker. +// ------------------------------------------------------------------ + +#ifndef __gdbgtrck_h +#define __gdbgtrck_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +struct GFTrk { + dword tick; + const char* text; + int indent; +}; + + +// ------------------------------------------------------------------ + +extern int __gftrk; +extern int __gftrk_on; +extern int __gftrk_max; +extern int __gftrk_curr; +extern int __gftrk_indent; +extern GFTrk* __gftrk_ptr; +extern GFTrk* __gftrk_list; + + +// ------------------------------------------------------------------ + +#if defined(GFTRK_ENABLE) +#ifdef __GNUC__ +#define GFTRK(t) if(__gftrk) __gftrk_track(t ? __PRETTY_FUNCTION__ : t); +#else +#define GFTRK(t) if(__gftrk) __gftrk_track(t); +#endif +#define GFTrkInit(t) __gftrk_init(t) +#else +#define GFTRK(t) +#define GFTrkInit(t) +#endif + + +// ------------------------------------------------------------------ + +void __gftrk_init(int trackmax=-1); +void __gftrk_track(const char* text); +void __gftrk_log(); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdefs.h b/goldlib/gall/gdefs.h new file mode 100644 index 0000000..34cee3f --- /dev/null +++ b/goldlib/gall/gdefs.h @@ -0,0 +1,172 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Basic definitions and types. +// ------------------------------------------------------------------ + +#ifndef __goldall_h +#define __goldall_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Define portability and shorthand notation + +#ifndef and +#define not ! +#define and && +#define or || +#endif + +#ifndef true +#define true 1 +#define false 0 +#endif + +#define NO 0 +#define YES 1 +#define ALWAYS 2 +#define ASK 2 +#define GAUTO 3 +#define MAYBE 4 + +#define NUL '\x00' // Common ASCII control codes +#define BEL '\x07' +#define BS '\x08' +#define HT '\x09' +#define LF '\x0A' +#define FF '\x0C' +#define CR '\x0D' +#define ESC '\x1B' + +#ifdef __UNIX__ +#define NL "\r\n" +#else +#define NL "\n" +#endif + + +// ------------------------------------------------------------------ +// Special character constants + +#define CTRL_A '\x01' // FidoNet kludge line char +#define SOFTCR '\x8D' // "Soft" carriage-return + + +// ------------------------------------------------------------------ +// Supplements for the built-in types + +typedef signed char schar; +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef unsigned char byte; +typedef signed char sbyte; +typedef unsigned short word; +typedef signed short sword; +typedef unsigned long dword; +typedef signed long sdword; + + +// ------------------------------------------------------------------ +// Common function-pointer types + +typedef void (*VfvCP)(); +typedef int (*IfvCP)(); +typedef int (*IfcpCP)(char*); + + +// ------------------------------------------------------------------ +// Function pointer for stdlib qsort(), bsearch() compare functions + +typedef int (*StdCmpCP)(const void*, const void*); + + +// ------------------------------------------------------------------ +// Utility templates + +template inline bool in_range(T a, T b, T c) { return (a >= b) and (a <= c); } +template inline T absolute(T a) { return a < 0 ? -a : a; } +template inline int compare_two(T a, T b) { return a < b ? -1 : a > b ? 1 : 0; } +template inline T minimum_of_two(T a, T b) { return __extension__ (a inline T maximum_of_two(T a, T b) { return __extension__ (a >? b); } +template inline int zero_or_one(T e) { return e ? 1 : 0; } +template inline bool make_bool(T a) { return a ? true : false; } + + +// ------------------------------------------------------------------ +// Handy macro for safe casting. Public domain by Bob Stout +// ------------------------------------------------------------------ +// +// Example of CAST macro at work +// +// union { +// char ch[4]; +// int i[2]; +// } my_union; +// +// long longvar; +// +// longvar = (long)my_union; // Illegal cast +// longvar = CAST(long, my_union); // Legal cast +// +// ------------------------------------------------------------------ + +#define CAST(new_type,old_object) (*((new_type *)&(old_object))) + + +// ------------------------------------------------------------------ +// Get size of structure member + +#define sizeofmember(__struct, __member) sizeof(((__struct*)0)->__member) + + +// ------------------------------------------------------------------ +// Legacy defines + +#ifndef AND +#define NOT ! +#define AND && +#define OR || +#endif + +#define RngV in_range +#define AbsV absolute +#define CmpV compare_two +#define MinV minimum_of_two +#define MaxV maximum_of_two + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gdirposx.cpp b/goldlib/gall/gdirposx.cpp new file mode 100644 index 0000000..5f8557b --- /dev/null +++ b/goldlib/gall/gdirposx.cpp @@ -0,0 +1,133 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Directory maintenance class. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#ifndef __HAVE_DRIVES__ +#include +#endif + + +// ------------------------------------------------------------------ + +gdirentry::gdirentry() : name(), dirname(NULL) +{ +} + + +// ------------------------------------------------------------------ + +gdirentry::~gdirentry() +{ +} + + +// ------------------------------------------------------------------ + +gposixdir::gposixdir() : dirname(), ret(), entries() +{ + ok = false; +} + + +// ------------------------------------------------------------------ + +gposixdir::gposixdir(const char *name) : dirname(), ret(), entries() +{ + cd(name); +} + + +// ------------------------------------------------------------------ + +gposixdir::~gposixdir() +{ +} + + +// ------------------------------------------------------------------ + +void gposixdir::cd(const char *name, bool relative) +{ + string ndirname; + if(!*name) + name = "."; + if(relative) { + dirname += "/"; + dirname += name; + } else + dirname = name; + ok = maketruepath(dirname); + entries.clear(); + DIR *d = opendir(dirname.c_str()); + if(d == NULL) + ok = false; + else { + struct dirent *de; + while((de=readdir(d)) != NULL) { + ndirname = de->d_name; +#ifdef __HAVE_DRIVES__ + if((ndirname != ".") && !((ndirname == "..") && streql(dirname.c_str()+1, ":/"))) +#else + if((ndirname != ".") && !((ndirname == "..") && (dirname == "/"))) +#endif + entries.push_back(ndirname); + } + closedir(d); + rewind(); + } +} + + +// ------------------------------------------------------------------ + +const gdirentry *gposixdir::nextentry(const char *mask, bool nameonly) +{ + while(last_entry < entries.size()) { + if(mask && !gwildmat(entries[last_entry].c_str(), mask)) { + ++last_entry; + continue; + } + ret.name = entries[last_entry]; + ret.dirname = dirname.c_str(); + string pn = ret.dirname; + pn += "/"; + pn += ret.name; + size_t skipfrom; + while((skipfrom=pn.find("//")) != pn.npos) + pn.erase(skipfrom, 1); + if(!nameonly) + stat(pn.c_str(), &ret.stat_info); + ++last_entry; + return &ret; + } + return NULL; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gdirposx.h b/goldlib/gall/gdirposx.h new file mode 100644 index 0000000..481c807 --- /dev/null +++ b/goldlib/gall/gdirposx.h @@ -0,0 +1,78 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Directory maintenance class. +// ------------------------------------------------------------------ + +#ifndef __gdirposx +#define __gdirposx + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +class gdirentry { + +public: + string name; + struct stat stat_info; + const char *dirname; + gdirentry(); + ~gdirentry(); + bool is_directory() const { return S_ISDIR(stat_info.st_mode); } + bool is_file() const { return S_ISREG(stat_info.st_mode); } +}; + + +// ------------------------------------------------------------------ + +class gposixdir { + +private: + string dirname; + gdirentry ret; + gstrarray entries; + unsigned long last_entry; + +public: + bool ok; + gposixdir(); + gposixdir(const char *name); + ~gposixdir(); + void cd(const char *name, bool relative=false); + inline void rewind() { last_entry = 0; } + const gdirentry *nextentry(const char *mask=NULL, bool nameonly=false); + inline const char *fullpath() { return dirname.c_str(); } +}; + + +// ------------------------------------------------------------------ + +#endif // __gdirposx + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/geval.cpp b/goldlib/gall/geval.cpp new file mode 100644 index 0000000..347b903 --- /dev/null +++ b/goldlib/gall/geval.cpp @@ -0,0 +1,110 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Expression evaluator base class. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +geval::geval() { + + // nothing to do +} + + +// ------------------------------------------------------------------ + +geval::~geval() { + + // nothing +} + + +// ------------------------------------------------------------------ + +geval::ops geval::pop_operator() { + + ops o = ostk.back(); + ostk.pop_back(); + return o; +} + + +// ------------------------------------------------------------------ + +int geval::pop_value() { + + int v = vstk.back(); + vstk.pop_back(); + return v; +} + + +// ------------------------------------------------------------------ + +void geval::push_value(int v) { + + vstk.push_back(v); +} + + +// ------------------------------------------------------------------ + +void geval::push_operator(geval::ops o) { + + ostk.push_back(o); +} + + +// ------------------------------------------------------------------ + +int geval::evaluate_op(geval::ops o, int y, int x) { + + switch(o) { + case addition: return y + x; + case subtraction: return y - x; + case multiplication: return y * x; + case division: return y / x; + case modulus: return y % x; + case negation: return -x; + case logic_not: return (not x) ? 1 : 0; + case logic_and: return (y and x) ? 1 : 0; + case logic_xor: return (y ^ x) ? 1 : 0; + case equal: return (y == x) ? 1 : 0; + case not_equal: return (y != x) ? 1 : 0; + case greater: return (y > x) ? 1 : 0; + case greater_or_equal: return (y >= x) ? 1 : 0; + case lesser: return (y < x) ? 1 : 0; + case lesser_or_equal: return (y <= x) ? 1 : 0; + default: ; + } + + return 0; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/geval.h b/goldlib/gall/geval.h new file mode 100644 index 0000000..c37f0ee --- /dev/null +++ b/goldlib/gall/geval.h @@ -0,0 +1,131 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Expression evaluator classes. +// ------------------------------------------------------------------ + +#ifndef __geval_h +#define __geval_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Base class + +class geval { + +public: + + enum ops { + lowest, + logic_or, + logic_and, + logic_xor, + not_equal, + equal, + greater_or_equal, + greater, + lesser_or_equal, + lesser, + subtraction, + addition, + modulus, + division, + multiplication, + negation, + logic_not, + parenthesis_right, + parenthesis_left, + highest + }; + +protected: + + vector ostk; + vector vstk; + + ops pop_operator(); + int pop_value(); + +public: + + geval(); + ~geval(); + + void push_value(int v); + void push_operator(ops o); + + int evaluate_op(ops o, int y, int x); + int evaluate_ops(ops* o, int* y, int* x); + +}; + + +// ------------------------------------------------------------------ + +inline int geval::evaluate_ops(ops* o, int* y, int* x) { + + return evaluate_op(*o, *y, *x); +} + + +// ------------------------------------------------------------------ +// Reverse Polish Notation expression evaluator. + +class gevalrpn : public geval { + +public: + + gevalrpn(); + ~gevalrpn(); + + int evaluate(); + +}; + + +// ------------------------------------------------------------------ +// Human (left-to-right) expression evaluator. + +class gevalhum : public geval { + +public: + + gevalhum(); + ~gevalhum(); + + int evaluate(); + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gevalhum.cpp b/goldlib/gall/gevalhum.cpp new file mode 100644 index 0000000..c7c85cc --- /dev/null +++ b/goldlib/gall/gevalhum.cpp @@ -0,0 +1,100 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Human (left-to-right) expression evaluator class. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +gevalhum::gevalhum() { + +} + + +// ------------------------------------------------------------------ + +gevalhum::~gevalhum() { + +} + + +// ------------------------------------------------------------------ + +int gevalhum::evaluate() { + + while(vstk.size() and ostk.size()) { + + while(ostk.size()) { + + int* vptr = vstk.begin(); + ops* optr = ostk.begin(); + + while(optr < ostk.end()) { + + if(optr < (ostk.end() - 1)) { + + if(*optr == parenthesis_left) { + if(optr[1] == parenthesis_right) { + ostk.erase(optr, optr+2); + break; + } + else { + optr++; + } + continue; + } + else if(((*optr == negation) or (*optr == logic_not)) and (optr[1] == parenthesis_left)) { + optr++; + continue; + } + else if((*optr < optr[1]) and (optr[1] != parenthesis_right)) { + optr++; + vptr++; + continue; + } + } + + if(ostk.size()) { + if((*optr == negation) or (*optr == logic_not)) + *vptr = evaluate_ops(optr, vptr, vptr); + else { + *vptr = evaluate_ops(optr, vptr, vptr+1); + if(vptr+1 < vstk.end()) + vstk.erase(vptr+1); + } + ostk.erase(optr); + } + break; + } + } + } + + return pop_value(); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gevalrpn.cpp b/goldlib/gall/gevalrpn.cpp new file mode 100644 index 0000000..5825c1b --- /dev/null +++ b/goldlib/gall/gevalrpn.cpp @@ -0,0 +1,69 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Reverse Polish Notation expression evaluator class. +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +gevalrpn::gevalrpn() { + +} + + +// ------------------------------------------------------------------ + +gevalrpn::~gevalrpn() { + +} + + +// ------------------------------------------------------------------ + +int gevalrpn::evaluate() { + + ops o; + int x, y=0; + + while(ostk.size()) { + o = pop_operator(); + switch(o) { + case negation: + case logic_not: + x = pop_value(); + break; + default: + x = pop_value(); + y = pop_value(); + } + push_value(evaluate_op(o, y, x)); + } + + return pop_value(); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfile.cpp b/goldlib/gall/gfile.cpp new file mode 100644 index 0000000..fc5162b --- /dev/null +++ b/goldlib/gall/gfile.cpp @@ -0,0 +1,419 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File I/O class. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +gfile::gfile() { + + fh = -1; + fp = NULL; + status = EBADF; +} + + +// ------------------------------------------------------------------ + +gfile::gfile(int __fh) { + + fh = __fh; + fp = NULL; + status = 0; +} + + +// ------------------------------------------------------------------ + +gfile::gfile(FILE* __fp) { + + fh = -1; + fp = __fp; + status = 0; +} + + +// ------------------------------------------------------------------ + +gfile::gfile(const char* __path, int __access, int __shflag, int __mode) { + + open(__path, __access, __shflag, __mode); +} + + +// ------------------------------------------------------------------ + +gfile::gfile(const char* __path, const char* __mode, int __shflag) { + + fopen(__path, __mode, __shflag); +} + + +// ------------------------------------------------------------------ + +gfile::~gfile() { + + if(fp != NULL) + fclose(); + if(fh != -1) + close(); +} + + +// ------------------------------------------------------------------ + +int gfile::okay() { + + return !status; +} + +// ------------------------------------------------------------------ + +int gfile::isopen() { + + if((fh != -1) or (fp != NULL)) + return true; + return false; +} + +// ------------------------------------------------------------------ + +int gfile::setfh(int __fh) { + + fh = __fh; + status = 0; + return fh; +} + +// ------------------------------------------------------------------ + +FILE* gfile::setfp(FILE* __fp) { + + fp = __fp; + status = 0; + return fp; +} + +// ------------------------------------------------------------------ + +int gfile::open(const char* __path, int __access, int __shflag, int __mode) { + + fh = ::sopen(__path, __access, __shflag, __mode); + status = (fh == -1) ? errno : 0; + return fh; +} + + +// ------------------------------------------------------------------ + +int gfile::open(const char* __path, int __access, char* __fmode, int __shflag, int __mode) { + + open(__path, __access, __shflag, __mode); + fdopen(__fmode); + return fh; +} + +// ------------------------------------------------------------------ + +int gfile::close() { + + if(fp) + return fclose(); + + int _ret = ::close(fh); + status = _ret ? errno : 0; + fh = -1; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::read(void* __ptr, size_t __len) { + + int _ret = ::read(fh, __ptr, (unsigned)__len); + status = (_ret == -1) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::write(void* __ptr, size_t __len) { + + int _ret = ::write(fh, __ptr, (unsigned)__len); + status = (_ret == -1) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +long gfile::tell() { + + long _ret = ::tell(fh); + status = (_ret == -1) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +long gfile::lseek(long __offset, int __direction) { + + long _ret = ::lseek(fh, __offset, __direction); + status = (_ret == -1) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +long gfile::filelength() { + + long _ret = ::filelength(fh); + status = (_ret == -1) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::chsize(long __size) { + + int _ret = ::chsize(fh, __size); + status = _ret ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::lock(long __offset, long __len) { + + int _ret = ::lock(fh, __offset, __len); + status = _ret ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::unlock(long __offset, long __len) { + + int _ret = ::unlock(fh, __offset, __len); + status = _ret ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::eof() { + + int _ret = ::eof(fh); + status = (_ret == -1) ? errno : 0; + return _ret; +} + + +// ------------------------------------------------------------------ + +int gfile::getftime(dword* __ftime) { + + struct stat s; + if(fp) + fflush(); + int rv = fstat (fh, &s); + status = (rv) ? errno : 0; + if(rv == 0) + *__ftime = gfixstattime(s.st_mtime); + else + __ftime = 0; + return rv; +} + + +// ------------------------------------------------------------------ + +FILE* gfile::fopen(const string& __path, const char* __mode, int __shflag) { + + return fopen(__path.c_str(), __mode, __shflag); +} + + +// ------------------------------------------------------------------ + +FILE* gfile::fopen(const char* __path, const char* __mode, int __shflag) { + + fp = ::fsopen(__path, __mode, __shflag); + status = (fp == NULL) ? errno : 0; + if(fp) + fh = fileno(fp); + return fp; +} + +// ------------------------------------------------------------------ + +FILE* gfile::fdopen(char* __mode) { + + fp = ::fdopen(fh, __mode); + status = fp ? 0 : errno; + if(fp) + fh = fileno(fp); + return fp; +} + +// ------------------------------------------------------------------ + +int gfile::fclose() { + + int _ret = 0; + if(fp) + _ret = ::fclose(fp); + status = _ret ? errno : 0; + fp = NULL; + fh = -1; + return _ret; +} + +// ------------------------------------------------------------------ + +size_t gfile::fread(void* __ptr, size_t __size, size_t __items) { + + size_t _ret = ::fread(__ptr, __size, __items, fp); + status = ferror_() ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +size_t gfile::fwrite(const void* __ptr, size_t __size, size_t __items) { + + size_t _ret = ::fwrite(__ptr, __size, __items, fp); + status = (_ret < __items) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::fgetc() { + + int _ret = ::fgetc(fp); + status = ferror_() ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::fputc(int __ch) { + + int _ret = ::fputc(__ch, fp); + status = ferror_() ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +char* gfile::fgets(char* __str, size_t __len) { + + char* _ret = ::fgets(__str, __len, fp); + status = (_ret == NULL) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::fputs(const char* __str) { + + int _ret = ::fputs(__str, fp); + status = (_ret == EOF) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::printf(const char* __format, ...) { + + va_list _argptr; + va_start(_argptr, __format); + int _outcount = ::vfprintf(fp, __format, _argptr); + va_end(_argptr); + return _outcount; +} + +// ------------------------------------------------------------------ + +int gfile::fflush() { + + int _ret = ::fflush(fp); + status = _ret ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +long gfile::ftell() { + + long _ret = ::ftell(fp); + status = (_ret == -1) ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::fseek(long __offset, int __direction) { + + int _ret = ::fseek(fp, __offset, __direction); + status = _ret ? errno : 0; + return _ret; +} + +// ------------------------------------------------------------------ + +int gfile::setvbuf(char* __buf, int __type, size_t __size) { + + int _ret = ::setvbuf(fp, __buf, __type, __size); + status = _ret ? errno : 0; + return _ret; +} + + +// ------------------------------------------------------------------ + +#ifdef __GOLDWARE_HAS_BOOL +gfile& gfile::operator>> (bool& i) { fread(&i, sizeof(bool)); return *this; } +#endif +gfile& gfile::operator>> (unsigned char& i) { fread(&i, sizeof(unsigned char)); return *this; } +gfile& gfile::operator>> (unsigned short& i) { fread(&i, sizeof(unsigned short)); return *this; } +gfile& gfile::operator>> (unsigned int& i) { unsigned int ii; fread(&ii, sizeof(unsigned int)); i = ii; return *this; } +gfile& gfile::operator>> (unsigned long& i) { fread(&i, sizeof(unsigned long)); return *this; } + +#ifdef __GOLDWARE_HAS_BOOL +gfile& gfile::operator<< (bool o) { fwrite(&o, sizeof(o)); return *this; } +#endif +gfile& gfile::operator<< (unsigned char o) { fwrite(&o, sizeof(o)); return *this; } +gfile& gfile::operator<< (unsigned short o) { fwrite(&o, sizeof(o)); return *this; } +gfile& gfile::operator<< (unsigned int o) { fwrite(&o, sizeof(o)); return *this; } +gfile& gfile::operator<< (unsigned long o) { fwrite(&o, sizeof(o)); return *this; } + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfile.h b/goldlib/gall/gfile.h new file mode 100644 index 0000000..52feafa --- /dev/null +++ b/goldlib/gall/gfile.h @@ -0,0 +1,248 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File I/O class. +// ------------------------------------------------------------------ + +#ifndef __gfilbase_h +#define __gfilbase_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// An invalid path/filename + +#define GFILE_INVALID "::INVALID::" + + +// ------------------------------------------------------------------ +// Stream/Unix-style file I/O class + +class gfile { + +public: + + // ---------------------------------------------------------------- + // Internal variables + + int fh; // File handle for Unix I/O + FILE* fp; // File pointer for ANSI stream I/O + + + // -------------------------------------------------------------- + // State variables + + int status; // Contains last errno value + + + // -------------------------------------------------------------- + // Handy utility functions + + int okay(); // Returns non-zero if no errors were detected + int isopen(); // true if the file is open + + + // -------------------------------------------------------------- + // Constructors and destructor + + gfile(); // Bare constructor + gfile(int __fh); // Construct from Unix file handle + gfile(FILE* __fp); // Construct from ANSI stream pointer + gfile(const char* __path, int __access, int __shflag=SH_DENYNO, int __mode=S_IREAD|S_IWRITE); + gfile(const char* __path, const char* __mode, int __shflag=SH_DENYNO); + + ~gfile(); // Destructor (closes file) + + operator bool() { return isopen(); } + + + // -------------------------------------------------------------- + // Set file handle or stream pointer + + int setfh(int __fh); + FILE* setfp(FILE* __fp); + + + // -------------------------------------------------------------- + // UNIX-style raw I/O + + int open (const char* __path, int __access, int __shflag=SH_DENYNO, int __mode=S_IREAD|S_IWRITE); + int open (const char* __path, int __access, char* __fmode, int __shflag=SH_DENYNO, int __mode=S_IREAD|S_IWRITE); + int close (); + + int read (void* __ptr, size_t __len); + int write (void* __ptr, size_t __len); + + long tell (); + long lseek (long __offset, int __direction); + long lseek (long __record, long __recordsize, int __direction); + long lseekset (long __record, long __recordsize=1); + + long filelength (); + + int chsize (long __size); + + int lock (long __offset, long __len); + int unlock (long __offset, long __len); + + int getftime (dword* __ftime); + + int eof (); + + + // -------------------------------------------------------------- + // ANSI-style streaming buffered I/O + + FILE* fopen (const char* __path, const char* __mode, int __shflag=SH_DENYNO); + FILE* fopen (const string& __path, const char* __mode, int __shflag=SH_DENYNO); + FILE* fdopen (char* __mode); + int fclose (); + + size_t fread (void* __ptr, size_t __size, size_t __items=1); + size_t fwrite (const void* __ptr, size_t __size, size_t __items=1); + + int fgetc (); + int fputc (int __ch); + + char* fgets (char* __str, size_t __len); + int fputs (const char* __str); + + int printf (const char* __format, ...) __attribute__ ((format (printf, 2, 3))); + + int fflush (); + + long ftell (); + int fseek (long __offset, int __direction); + int fseek (long __record, long __recordsize, int __direction); + int fseekset(long __record, long __recordsize=1); + + void rewind (); + + int setvbuf (char* __buf=NULL, int __type=_IOFBF, size_t __size=8192); + int setvbuf (size_t __size) { return setvbuf(NULL, _IOFBF, __size); } + + int feof_ (); + int ferror_ (); + + + // ---------------------------------------------------------------- + + #ifdef __GOLDWARE_HAS_BOOL + gfile& operator>> (bool& i); + #endif + gfile& operator>> (unsigned char& i); + gfile& operator>> (unsigned short& i); + gfile& operator>> (unsigned int& i); + gfile& operator>> (unsigned long& i); + gfile& operator>> (char& i) { return operator>>((unsigned char&)i); } + gfile& operator>> (signed char& i) { return operator>>((unsigned char&)i); } + gfile& operator>> (short& i) { return operator>>((unsigned short&)i); } + gfile& operator>> (int& i) { return operator>>((unsigned int&)i); } + gfile& operator>> (long& i) { return operator>>((unsigned long&)i); } + + #ifdef __GOLDWARE_HAS_BOOL + gfile& operator<< (bool o); + #endif + gfile& operator<< (unsigned char o); + gfile& operator<< (unsigned short o); + gfile& operator<< (unsigned int o); + gfile& operator<< (unsigned long o); + gfile& operator<< (char o) { return operator<<((unsigned char)o); } + gfile& operator<< (signed char o) { return operator<<((unsigned char)o); } + gfile& operator<< (short o) { return operator<<((unsigned short)o); } + gfile& operator<< (int o) { return operator<<((unsigned int)o); } + gfile& operator<< (long o) { return operator<<((unsigned long)o); } + +}; + + +// ------------------------------------------------------------------ +// Inline implementations + + +// ------------------------------------------------------------------ + +inline long gfile::lseek(long __record, long __recordsize, int __direction) { + + return lseek(__record*__recordsize, __direction); +} + + +// ------------------------------------------------------------------ + +inline long gfile::lseekset(long __record, long __recordsize) { + + return lseek(__record*__recordsize, SEEK_SET); +} + + +// ------------------------------------------------------------------ + +inline int gfile::ferror_() { + + return ferror(fp); +} + + +// ------------------------------------------------------------------ + +inline int gfile::fseek(long __record, long __recordsize, int __direction) { + + return fseek(__record*__recordsize, __direction); +} + + +// ------------------------------------------------------------------ + +inline int gfile::fseekset(long __record, long __recordsize) { + + return fseek(__record*__recordsize, SEEK_SET); +} + + +// ------------------------------------------------------------------ + +inline void gfile::rewind() { + + ::rewind(fp); +} + + +// ------------------------------------------------------------------ + +inline int gfile::feof_() { + + return feof(fp); +} + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfilport.cpp b/goldlib/gall/gfilport.cpp new file mode 100644 index 0000000..8bc5aad --- /dev/null +++ b/goldlib/gall/gfilport.cpp @@ -0,0 +1,204 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ports of OS-specific file/path functions. +// ------------------------------------------------------------------ + +#include + +#if defined(__OS2__) +#define INCL_BASE +#define INCL_ERROR_H +#include +#endif + +#if defined(__WIN32__) +#include +#endif + +#if defined(__CYGWIN__) +#include +#endif + +#if defined(__MINGW32__) +#include +#endif + + +// ------------------------------------------------------------------ + +#ifdef __cplusplus +extern "C" { +#endif + + +// ------------------------------------------------------------------ + +#if (defined(__BORLANDC__) and defined(__OS2__)) or defined(__UNIX__) or defined(__EMX__) + +long filelength(int handle) { + + struct stat s; + if(fstat(handle, &s) == 0) + return s.st_size; + else + return -1; +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__OS2__) + +int lock(int handle, long ofs, long length) +{ + int rc; + APIRET apiret; + FILELOCK urange, lrange; + + lrange.lOffset = ofs; + lrange.lRange = length; + urange.lRange = urange.lOffset = 0; + + if((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 0, 0)) != 0) { + if(apiret == ERROR_LOCK_VIOLATION) { + errno = EACCES; + rc = -1; + } + else + rc = (int)apiret; + } + else + rc = 0; + + return rc; +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__OS2__) + +int unlock(int handle, long ofs, long length) +{ + int rc; + FILELOCK urange, lrange; + APIRET apiret; + + urange.lOffset = ofs; + urange.lRange = length; + lrange.lRange = lrange.lOffset = 0; + + if((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 0, 0)) != 0) { + if(apiret == ERROR_LOCK_VIOLATION) { + errno = EACCES; + rc = -1; + } + else + rc = apiret; + } + else + rc = 0; + + return rc; +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__UNIX__) or defined(__CYGWIN__) + +int lock(int handle, long offset, long length) { + + struct flock fl; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = length; + + return fcntl(handle, F_SETLK, &fl); +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__UNIX__) or defined(__CYGWIN__) + +int unlock(int handle, long offset, long length) { + + struct flock fl; + fl.l_type = F_UNLCK; + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = length; + + return fcntl(handle, F_SETLK, &fl); +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__MINGW32__) or defined(_MSC_VER) + +int lock(int fh, long offs, long len) { + + if(LockFile((HANDLE)_get_osfhandle(fh), offs, 0L, len, 0L)) return 0; + else return -1; +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__MINGW32__) or defined(_MSC_VER) + +int unlock(int fh, long offs, long len) { + + if(UnlockFile((HANDLE)_get_osfhandle(fh), offs, 0L, len, 0L)) return 0; + else return -1; +} + +#endif + + +// ------------------------------------------------------------------ + +#ifdef __cplusplus +} +#endif + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gfilutil.h b/goldlib/gall/gfilutil.h new file mode 100644 index 0000000..66ebfc7 --- /dev/null +++ b/goldlib/gall/gfilutil.h @@ -0,0 +1,255 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File/disk handling functions. +// ------------------------------------------------------------------ + +#ifndef __gfilutil_h +#define __gfilutil_h + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#if not defined(__UNIX__) +#include +#endif + + +// ------------------------------------------------------------------M + +#if defined(__UNIX__) +#define O_TEXT 0 +#define O_BINARY 0 +#endif + +#ifndef S_IWUSR +#define S_IWUSR S_IWRITE +#define S_IRUSR S_IREAD +#endif + +#if defined(__UNIX__) +#define S_STDRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) +#define S_STDRD (S_IRUSR|S_IRGRP|S_IROTH) +#else +#define S_STDRW (S_IRUSR|S_IWUSR) +#define S_STDRD S_IRUSR +#endif + + +// ------------------------------------------------------------------ + +#ifdef PATH_MAX +#define GMAXPATH (PATH_MAX+1) +#else +#define GMAXPATH 1025 +#endif + + +// ------------------------------------------------------------------ +// Standardized split/merge defines + +#define GMAXDRIVE 265 +#define GMAXDIR 256 +#define GMAXFILE 256 +#define GMAXEXT 256 +#define GMAXFILEEXT 256 + + +// ------------------------------------------------------------------ +// Misc. defines + +#if defined(__MSDOS__) or defined(__OS2__) or defined(__WIN32__) + #define GOLD_SLASH_CHR '\\' // Backslash + #define GOLD_SLASH_STR "\\" + #define GOLD_WRONG_SLASH_CHR '/' // Fwrdslash + #define GOLD_WRONG_SLASH_STR "/" + #define GOLD_SHELL_ENV "COMSPEC" +#else + #define GOLD_SLASH_CHR '/' // Fwrdslash + #define GOLD_SLASH_STR "/" + #define GOLD_WRONG_SLASH_CHR '\\' // Backslash + #define GOLD_WRONG_SLASH_STR "\\" + #define GOLD_SHELL_ENV "SHELL" +#endif + +inline bool isslash(char c) { return (c == '\\') || (c == '/'); } + + +// ------------------------------------------------------------------ +// Path typedefs + +typedef char Path[GMAXPATH]; + + +// ------------------------------------------------------------------ +// Structure for filetime stamp checking + +struct Stamp { + dword ft; // Timestamp + Path fn; // Filename + byte fc; // Filecheck +}; + + +// ------------------------------------------------------------------ +// Prototypes + +#if not defined(__GNUC__) or defined(__MINGW32__) +#define mkdir(path,unused) mkdir(path) +#endif + +FILE* fsopen(const char* path, const char* type, int shflag); +inline FILE* fsopen(const string& path, const char* type, int shflag) { return fsopen(path.c_str(), type, shflag); } + +int is_dir(const char* path); +inline int is_dir(const string& path) { return is_dir(path.c_str()); } + +inline bool fexist(const char* filename) { return *filename ? ((access(filename, 0) == 0) and not is_dir(filename)) : false; } +inline bool fexist(const string& filename) { return fexist(filename.c_str()); } + +dword gfixstattime(time_t st_time); + +dword GetFiletime(const char* file); +inline dword GetFiletime(const string& file) { return GetFiletime(file.c_str()); } + +inline long FiletimeCmp(const char* file1, const char* file2) { return long(GetFiletime(file1) - GetFiletime(file2)); } +inline long FiletimeCmp(const string& file1, const string& file2) { return FiletimeCmp(file1.c_str(), file2.c_str()); } + +long fsize(FILE* fp); +long GetFilesize(const char* file); + +const char* AddPath(const char* path, const char* file); +inline const char* AddPath(const string& path, const char* file) { return AddPath(path.c_str(), file); } +inline const char* AddPath(const string& path, const string& file) { return AddPath(path.c_str(), file.c_str()); } + +void MakePathname(char* pathname, const char* path, const char* name); +void MakePathname(string& pathname, const string& path, const string& name); + +char* AddBackslash(char* p); +string& AddBackslash(string& p); +char* StripBackslash(char* p); + +char* PathCopy(char* dst, const char* src); +void PathCopy(string& dst, const char* src); + +void TouchFile(const char* __filename); + +int TestLockPath(const char* __path); +void WipeFile(const char* file, int options); + +const char* CleanFilename(const char* __file); + +int strschg_environ(char* s); +int strschg_environ(string& s); + +char* MapPath(char* map, bool reverse = false); +inline char* ReMapPath(char* map) { return MapPath(map, true); }; + +inline long lseekset(int fh, long offset) { return lseek(fh, offset, SEEK_SET); } +inline long lseekset(int fh, long record, long recordsize) { return lseek(fh, record*recordsize, SEEK_SET); } + +int gchdir(const char* dir); + + +// ------------------------------------------------------------------ + +#ifdef __cplusplus +extern "C" { +#endif + + +// ------------------------------------------------------------------ + +#if (defined(__BORLANDC__) and defined(__OS2__)) or defined(__UNIX__) or defined(__EMX__) +long filelength(int fh); +#endif + + +// ------------------------------------------------------------------ + +void replaceextension(char *destpath, const char *srcpath, const char *ext); +void extractdirname(char *dir, const char *path); + + +// ------------------------------------------------------------------ + +#if defined(_MSC_VER) +int lock(int handle, long offset, long length); +int unlock(int handle, long offset, long length); +#endif + + +// ------------------------------------------------------------------ + +#if defined(__DJGPP__) +#undef sopen +#endif + +#if not defined(__DJGPP__) and defined(__GNUC__) +int lock(int handle, long offset, long length); +int unlock(int handle, long offset, long length); +inline long tell(int fh) { return lseek(fh, 0, SEEK_CUR); } +#endif + +#if not defined(__MINGW32__) and not defined(__EMX__) and defined(__GNUC__) + +inline int eof(int h) { + return tell(h) > filelength(h); +} + +inline int sopen(const char* path, int access, int shflag, int mode) { + return open(path, access|shflag, mode); +} + +#endif + +#if defined(__UNIX__) or defined(__CYGWIN__) +inline int chsize(int handle, long size) { return ftruncate(handle, size); } +#endif + + +// ------------------------------------------------------------------ + +bool maketruepath(string &dirname); + + +// ------------------------------------------------------------------ + +#ifdef __cplusplus +} +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfilutl1.cpp b/goldlib/gall/gfilutl1.cpp new file mode 100644 index 0000000..702b7bb --- /dev/null +++ b/goldlib/gall/gfilutl1.cpp @@ -0,0 +1,455 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File utility functions +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#if defined(__OS2__) +#define INCL_BASE +#include +#endif + +#if defined(__WIN32__) +#include +#endif + +#if defined(__MSDOS__) +#include +#endif + + +// ------------------------------------------------------------------ + +char* AddBackslash(char* p) { + + if(*p) { + strchg(p, GOLD_WRONG_SLASH_CHR, GOLD_SLASH_CHR); + if(p[strlen(p)-1] != GOLD_SLASH_CHR) + strcat(p, GOLD_SLASH_STR); + } + else + strcpy(p, GOLD_SLASH_STR); + + return p; +} + + +// ------------------------------------------------------------------ + +char* StripBackslash(char* p) { + + int x = strlen(p) - 1; + + if(*p and isslash(p[x])) + p[x] = NUL; + + return p; +} + + +// ------------------------------------------------------------------ +// Get size of file + +long GetFilesize(const char* file) { + + struct stat info; + if(stat(file, &info) == 0) + return info.st_size; + return -1; +} + + +// ------------------------------------------------------------------ +// Convert time returned with stat to FFTime + +dword gfixstattime(time_t st_time) { + + #if defined(__MINGW32__) or defined(__CYGWIN__) + struct tm &f = *gmtime(&st_time); + #else + struct tm &f = *localtime(&st_time); + #endif + FFTime t; + t.ft_year = f.tm_year - 80; + t.ft_month = f.tm_mon + 1; + t.ft_day = f.tm_mday; + t.ft_hour = f.tm_hour; + t.ft_min = f.tm_min; + t.ft_tsec = f.tm_sec / 2; + #if defined(__MINGW32__) or defined(__CYGWIN__) + union { + DWORD t; + struct { + WORD wFatTime; + WORD wFatDate; + } d; + } ft; + ft.t = (DWORD)t.number(); + FILETIME FileTime, LocalFileTime; + DosDateTimeToFileTime(ft.d.wFatDate, ft.d.wFatTime, &FileTime); + FileTimeToLocalFileTime(&FileTime, &LocalFileTime); + SYSTEMTIME SystemTime; + FileTimeToSystemTime(&LocalFileTime, &SystemTime); + t.ft_year = SystemTime.wYear - 1980; + t.ft_month = SystemTime.wMonth; + t.ft_day = SystemTime.wDay; + t.ft_hour = SystemTime.wHour; + t.ft_min = SystemTime.wMinute; + t.ft_tsec = SystemTime.wSecond / 2; + #endif + return t.number(); +} + + +// ------------------------------------------------------------------ +// Get timestamp of file + +dword GetFiletime(const char* file) { + + struct stat st; + if(stat(file, &st) == 0) { + #if defined(__MINGW32__) + if(st.st_mode & S_IFDIR) + return 0; + #endif + return gfixstattime(st.st_mtime); + } + return 0; +} + + +// ------------------------------------------------------------------ +// Get size of open file + +long fsize(FILE* fp) { + + return filelength(fileno(fp)); +} + + +// ------------------------------------------------------------------ +// Check if a pathname is a directory + +int is_dir(const char* path) { + + // Check if it's a root path (X:\) + #if defined(__HAVE_DRIVES__) + if(isalpha(path[0]) and (path[1] == ':') and isslash(path[2]) and (path[3] == NUL)) + return true; // The root is a directory + #endif + + Path tmp; + strxcpy(tmp, path, sizeof(Path)); + StripBackslash(tmp); + + struct stat st; + if(stat(tmp, &st) == 0) + return (st.st_mode & S_IFDIR) ? true : false; + return false; +} + + +// ------------------------------------------------------------------ +// Add path to filename if no path is present + +static Path __addpath; + +const char* AddPath(const char* path, const char* file) { + + if(strpbrk(file, "/\\")) { + // Don't add path if the filename already contains one + return file; + } + else if(*path and ((*file == '.') or isslash(path[strlen(path)-1]))) { + // Build path+filename if path ends with a slash or backslash + strxmerge(__addpath, sizeof(Path), path, file, NULL); + return __addpath; + } + else { + // Use filename in path or file + return *path ? path : file; + } +} + + +// ------------------------------------------------------------------ +// Add path to filename, if no path is set + +void MakePathname(char* pathname, const char* path, const char* name) { + + char newpath[GMAXPATH]; + Path tmpname; + Path tmppath; + strcpy(tmpname, name); + strcpy(tmppath, path); + + if(strblank(tmpname)) { + *pathname = NUL; + return; + } + + strbtrim(tmppath); + strchg(tmppath, GOLD_WRONG_SLASH_CHR, GOLD_SLASH_CHR); + strchg(tmpname, GOLD_WRONG_SLASH_CHR, GOLD_SLASH_CHR); + if(strpbrk(tmpname, GOLD_SLASH_STR)) + strcpy(pathname, tmpname); + else { + strcpy(newpath, tmppath); + if(*newpath) + AddBackslash(newpath); + strxmerge(pathname, sizeof(Path), newpath, tmpname, NULL); + } +} + + +// ------------------------------------------------------------------ +// Shareable fopen() for compilers that need it + +FILE *fsopen(const char *path, const char *type, int shflag) { + + FILE* fp=NULL; + int fh=-1, acc=0, mode=S_STDRD, c, n; + + switch(type[0]) { + case 'r': + acc |= O_RDONLY; + break; + case 'w': + acc |= (O_TRUNC|O_CREAT|O_WRONLY); + mode |= S_STDRW; + break; + case 'a': + acc |= (O_APPEND|O_CREAT|O_WRONLY); + mode |= S_STDRW; + break; + default: + return NULL; + } + n=0; + do { + c = type[++n]; + switch(c) { + case '+': + acc &= (~O_RDONLY); + acc &= (~O_WRONLY); + acc |= O_RDWR; + break; + case 'b': + acc |= O_BINARY; + break; + case 't': + acc |= O_TEXT; + break; + default: + break; + } + } while((n < 3) && (c)); + + fh = sopen(path, acc, shflag, mode); + if(fh != -1) + fp = fdopen(fh, (char*)type); + + return fp; +} + + +// ------------------------------------------------------------------ + +void TouchFile(const char* filename) { + + if(not fexist(filename)) + close(open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_STDRW)); + else { + struct utimbuf ut; + ut.actime = ut.modtime = time(NULL); + utime(filename, &ut); + } +} + + +// ------------------------------------------------------------------ + +char* PathCopy(char* __dst, const char* __src) { + + return AddBackslash(strxcpy(__dst, __src, sizeof(Path))); +} + + +// ------------------------------------------------------------------ + +int TestLockPath(const char* __path) { + + int _canlock = false; + + Path _file; + strxmerge(_file, sizeof(Path), __path, "GDXXXXXX", NULL); + mktemp(_file); + + int _fh = sopen(_file, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, SH_DENYNO, S_STDRW); + if(_fh != -1) { + if(lock(_fh, 0L, 1L) == -1) + _canlock = NO; + else { + _canlock = YES; + unlock(_fh, 0L, 1L); + } + close(_fh); + remove(_file); + } + + return _canlock; +} + + +// ------------------------------------------------------------------ + +const char* CleanFilename(const char* __file) { + + static const char* invalidfilename = ""; + if((__file == NULL) or (__file == (char*)0xFFFFFFFFL) or (__file == (char*)0xEEEEEEEEL)) + return invalidfilename; + + const char *tmp, *tmp2; + tmp = tmp2 = __file; + while(*tmp) + if(isslash(*tmp++)) + tmp2 = tmp; + return *tmp2 ? tmp2 : invalidfilename; +} + + +// ------------------------------------------------------------------ + +void WipeFile(const char* file, int options) { + + uint n; + byte buf[512]; + + switch(options) { + default: + for(n=0; n<512; n++) + buf[n] = (byte)(rand() % 256); + } + + int fh = sopen(file, O_RDWR|O_BINARY, SH_DENYRW, S_STDRW); + if(fh != -1) { + uint blocks = (uint)(filelength(fh) / 512L) + 1; + for(n=0; n 0) + ptr2 = dot; + strcpy(ptr2, ext); +} + + +// ------------------------------------------------------------------ + +void extractdirname(char *dir, const char *path) { + + const char *p1 = path; + char *p2, *p3; + p3 = p2 = dir; + while(*p1) { + if(isslash(*p1)) + p2 = p3; + *p3++ = *p1++; + } + if(isslash(*p2)) + ++p2; + *p2 = NUL; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfilutl2.cpp b/goldlib/gall/gfilutl2.cpp new file mode 100644 index 0000000..5dbcb8d --- /dev/null +++ b/goldlib/gall/gfilutl2.cpp @@ -0,0 +1,213 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File utility functions +// ------------------------------------------------------------------ + +#include +#ifndef __HAVE_DRIVES__ +#include +#endif + + +// ------------------------------------------------------------------ + +string& AddBackslash(string& p) { + + for(size_t posn = 0; (posn=p.find(GOLD_WRONG_SLASH_CHR, posn)) != p.npos; posn++) + p[posn] = GOLD_SLASH_CHR; + if(p[p.length()-1] != GOLD_SLASH_CHR) + p += GOLD_SLASH_STR; + + return p; +} + + +// ------------------------------------------------------------------ +// Add path to filename, if no path is set + +void MakePathname(string& pathname, const string& path, const string& name) { + + Path pn; + strcpy(pn, pathname.c_str()); + MakePathname(pn, path.c_str(), name.c_str()); + pathname = pn; +} + + +// ------------------------------------------------------------------ + +void PathCopy(string& dst, const char* src) { + + dst = src; + AddBackslash(dst); +} + + +// ------------------------------------------------------------------ + +int strschg_environ(string& s) { + + string fnd; + int replaced = 0; + size_t posn, posn1; + + while(((posn=s.find('%')) != s.npos) and ((posn1=s.find('%', posn+1)) != s.npos)) { + fnd = s.substr(posn+1, posn1-1); + const char* rep = getenv(fnd.c_str()); + rep = rep ? rep : ""; + s.replace(posn, posn1-posn+1, rep); + replaced++; + } + +#ifndef __HAVE_DRIVES__ + if(not s.empty() and (s[0] == '~')) { + string name; + const char *p = s.c_str()+1; + if((s.length() != 1) and not isslash(*p)) { + while(*p and not isslash(*p)) + name += *p++; + } else + name = getlogin(); + struct passwd *pe = getpwnam(name.c_str()); + if(pe != NULL) { + string dirname = pe->pw_dir; + dirname += "/"; + if(isslash(*p)) + ++p; + dirname += p; + s = dirname.c_str(); + replaced++; + } + } +#endif + + return replaced; +} + + +// ------------------------------------------------------------------ + +bool maketruepath(string &dirname) { + + bool ok = true; + string ndirname; + char cwd[GMAXPATH]; + getcwd(cwd, GMAXPATH); +#ifdef __HAVE_DRIVES__ + long inspos = -1; + if((dirname.length() == 2) && (dirname[1] == ':')) + inspos = 2; + else if((dirname.length() < 2) || (dirname[1] != ':') || isslash(dirname[0])) + inspos = 0; + else if(!isslash(dirname[2])) + inspos = 2; + if(inspos != -1) { + char chdrive[] = " :"; + chdrive[0] = (inspos == 2) ? dirname[0] : cwd[0]; + if(!chdir(chdrive)) { + char dwd[GMAXPATH]; + getcwd(dwd, GMAXPATH); + if(isslash(dirname[0])) + ndirname = chdrive; + else { + ndirname = dwd; + ndirname += "/"; + } + ndirname += dirname.c_str() + inspos; + dirname = ndirname; + } else { + dirname = cwd; + ok = false; + } + chdir(cwd); + } +#else + if(!dirname.empty() && (dirname[0] == '~')) { + const char *p = dirname.c_str()+1; + if((dirname.length() != 1) && !isslash(*p)) { + while(*p && !isslash(*p)) + ndirname += *p++; // get user name + } else + ndirname = getlogin(); // get current user name + struct passwd *pe = getpwnam(ndirname.c_str()); // get home + if(pe != NULL) { + ndirname = pe->pw_dir; + ndirname += "/"; + if(isslash(*p)) + ++p; + ndirname += p; + dirname = ndirname; + } else { + dirname = cwd; + ok = false; + } + } else if(!dirname.empty() && !isslash(dirname[0])) { + ndirname = cwd; + ndirname += "/"; + ndirname += dirname; + dirname = ndirname; + } +#endif + size_t posn; + for(posn = 0; (posn=dirname.find('\\', posn)) != dirname.npos; posn++) + dirname[posn] = '/'; + size_t skipfrom, skipto; + while((skipfrom=dirname.find("//")) != dirname.npos) + dirname.erase(skipfrom, 1); + size_t len = dirname.length(); +#ifdef __HAVE_DRIVES__ + while((len > 3) && isslash(dirname[--len])) +#else + while((len > 1) && isslash(dirname[--len])) +#endif + dirname.erase(len, 1); + if(access(dirname.c_str(), R_OK)) { + dirname = cwd; + ok = false; + } + for(posn = 0; (posn=dirname.find('\\', posn)) != dirname.npos; posn++) + dirname[posn] = '/'; + while((skipto=dirname.find("/../")) != dirname.npos) { + skipfrom = (skipto == 0) ? 0 : dirname.rfind('/', skipto-1); + skipto += 2; + dirname.erase(skipfrom, skipto-skipfrom+1); + } + while((skipfrom=dirname.find("/./")) != dirname.npos) + dirname.erase(skipfrom, 2); + len = dirname.length(); + if(len > 2 && !strcmp(&(dirname[len-2]), "/.")) + dirname.erase(len-2, 2); + len = dirname.length(); +#ifdef __HAVE_DRIVES__ + if((len > 3) && isslash(dirname[--len])) +#else + if((len > 1) && isslash(dirname[--len])) +#endif + dirname.erase(len, 1); + return ok; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnaddr.cpp b/goldlib/gall/gftnaddr.cpp new file mode 100644 index 0000000..f4f33b3 --- /dev/null +++ b/goldlib/gall/gftnaddr.cpp @@ -0,0 +1,392 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FidoNet Technology Network - 4D address class. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void ftn_addr::set(uint zn, uint nt, uint nd, uint pt) { + + zone = (word)zn; + net = (word)nt; + node = (word)nd; + point = (word)pt; +} + + +// ------------------------------------------------------------------ + +void ftn_addr::set(const ftn_addr& a) { + + zone = a.zone; + net = a.net; + node = a.node; + point = a.point; +} + + +// ------------------------------------------------------------------ + +void ftn_addr::set(const void* a) { + + zone = ((ftn_addr*)a)->zone; + net = ((ftn_addr*)a)->net; + node = ((ftn_addr*)a)->node; + point = ((ftn_addr*)a)->point; +} + + +// ------------------------------------------------------------------ + +void ftn_addr::set_all(uint part) { + + set_fast(part, part, part, part); +} + + +// ------------------------------------------------------------------ + +void ftn_addr::reset() { + + reset_fast(); +} + + +// ------------------------------------------------------------------ + +char* ftn_addr::reset(const char* str, char* dom, int domsizelimit) { + + reset_fast(); + return set(str, dom, domsizelimit); +} + + +// ------------------------------------------------------------------ + +void ftn_addr::reset(const string& str) { + + reset(str.c_str()); +} + + +// ------------------------------------------------------------------ + +void ftn_addr::reset(const string& str, string& dom, int domsizelimit) { + + ftn_domain doms; + reset(str.c_str(), doms, domsizelimit); + dom = doms; +} + + +// ------------------------------------------------------------------ + +static bool ftn_getaddrpart(word& part, const char* s) { + + if(*s == '*') { + part = ftn::wildcard_all; + return true; + } + else if(*s == '?') { + part = ftn::wildcard_first; + return true; + } + else if(isdigit(*s)) { + part = atow(s); + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +const char* ftn_addr::set(const string& str) { + + return set(str.c_str()); +} + + +// ------------------------------------------------------------------ + +const char* ftn_addr::set(const string& str, string& dom, int domsizelimit) { + + ftn_domain doms; + set(str.c_str(), doms, domsizelimit); + dom = doms; + return dom.c_str(); +} + + +// ------------------------------------------------------------------ + +char* ftn_addr::set(const char* str, char* dom, int domsizelimit) { + + const char* ptr = str; + const char* domptr; + bool gotzone = false; + bool gotnet = false; + bool gotnode = false; + bool gotpoint = false; + bool gotdomain = false; + static char* nulchar = ""; + + if(*str == '*') + set_all(ftn::wildcard_all); + + while(*ptr and (' ' < *ptr)) { + + switch(*ptr) { + + case '<': + return nulchar; + + case '{': /*}*/ + while((*ptr != /*{*/ '}') and *ptr) + ptr++; + //if(*ptr == /*{*/ '}') + // ptr++; + break; + + case '#': + domptr = str; + str = ++ptr; + if(dom) { + int domsize = (int)(ptr-domptr); + strxcpy(dom, domptr, minimum_of_two(domsize, domsizelimit)); + gotdomain = true; + } + break; + + case ':': + gotzone = ftn_getaddrpart(zone, str); + str = ++ptr; + if(*str) + gotnet = ftn_getaddrpart(net, str); + break; + + case '/': + if(not gotnet) + gotnet = ftn_getaddrpart(net, str); + str = ++ptr; + if(*str) + gotnode = ftn_getaddrpart(node, str); + break; + + case '.': + if((not gotnode) and (*str != '.')) + gotnode = ftn_getaddrpart(node, str); + str = ++ptr; + if(*str) + ftn_getaddrpart(point, str); + gotpoint = true; + break; + + case '@': + if(not (gotzone or gotnet or gotnode or gotpoint)) + gotnode = ftn_getaddrpart(node, str); + domptr = str = ptr++; + //while(isalnum(*ptr)) + while(*ptr > ' ') + ptr++; + if(dom) { + int domsize = (int)(ptr-domptr); + strxcpy(dom, domptr+1, minimum_of_two(domsize, domsizelimit)); + gotdomain = true; + } + break; + + default: + ptr++; + } + } + + if(not (gotzone or gotnet or gotnode or gotpoint)) + gotnode = ftn_getaddrpart(node, str); + + if(gotzone and not gotnet) + net = 0; + + if(gotzone and not gotnode) { + node = (word)((net == ftn::wildcard_all) ? ftn::wildcard_all : 0); + gotnode = true; + } + + if(gotnode and not gotpoint) + point = (word)((node == ftn::wildcard_all) ? ftn::wildcard_all : 0); + + if(dom and gotzone and not gotdomain) + *dom = NUL; + + return dom ? dom : nulchar; +} + + +// ------------------------------------------------------------------ + +bool ftn_addr::match(const ftn_addr& mask) const { + + if(not ((mask.zone == ftn::wildcard_all) or (mask.zone == zone))) + return false; + if(not ((mask.net == ftn::wildcard_all) or (mask.net == net))) + return false; + if(not ((mask.node == ftn::wildcard_all) or (mask.node == node))) + return false; + if(not ((mask.point == ftn::wildcard_all) or (mask.point == point))) + return false; + + return true; +} + + +// ------------------------------------------------------------------ + +int ftn_addr::compare(const ftn_addr& other) const { + + int n = 1; + int d = compare_two(zone, other.zone); + if(d == 0) { + n++; + d = compare_two(net, other.net); + if(d == 0) { + n++; + d = compare_two(node, other.node); + if(d == 0) { + n++; + d = compare_two(point, other.point); + } + } + } + + return d != 0 ? (d > 0 ? n : -n) : 0; +} + + +// ------------------------------------------------------------------ + +string& ftn_addr::make_string(string& str) const { + + char buf[200]; + make_string(buf); + str = buf; + return str; +} + + +// ------------------------------------------------------------------ + +string& ftn_addr::make_string(string& str, const string& dom, int domfmt) const { + + char buf[200]; + make_string(buf, dom.c_str(), domfmt); + str = buf; + return str; +} + + +// ------------------------------------------------------------------ + +char* ftn_addr::make_string(char* str, const char* dom, int domfmt) const { + + if(net == 0) { + *str = NUL; + return str; + } + + char buf[20]; + char* ptr = str; + + *ptr = NUL; + + if(domfmt == ftn::domain_first) { + if(dom and *dom) { + ptr = stpcpy(ptr, dom); + *ptr++ = '#'; + } + } + + if(zone) { + if(zone == ftn::wildcard_all) + ptr = stpcpy(ptr, "*"); + else if(zone == ftn::wildcard_first) + ptr = stpcpy(ptr, "?"); + else { + sprintf(buf, "%u", (uint)zone); + ptr = stpcpy(ptr, buf); + } + *ptr++ = ':'; + } + + if(net == ftn::wildcard_all) + ptr = stpcpy(ptr, "*"); + else if(net == ftn::wildcard_first) + ptr = stpcpy(ptr, "?"); + else { + sprintf(buf, "%u", (uint)net); + ptr = stpcpy(ptr, buf); + } + *ptr++ = '/'; + + if(node == ftn::wildcard_all) + ptr = stpcpy(ptr, "*"); + else if(node == ftn::wildcard_first) + ptr = stpcpy(ptr, "?"); + else { + sprintf(buf, "%u", (uint)node); + ptr = stpcpy(ptr, buf); + } + + if(point) { + *ptr++ = '.'; + if(point == ftn::wildcard_all) + ptr = stpcpy(ptr, "*"); + else if(point == ftn::wildcard_first) + ptr = stpcpy(ptr, "?"); + else { + sprintf(buf, "%u", (uint)point); + ptr = stpcpy(ptr, buf); + } + } + + if(domfmt == ftn::domain_last) { + if(dom and *dom) { + *ptr++ = '@'; + ptr = stpcpy(ptr, dom); + } + } + + *ptr = NUL; + + return str; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnall.h b/goldlib/gall/gftnall.h new file mode 100644 index 0000000..276a2c7 --- /dev/null +++ b/goldlib/gall/gftnall.h @@ -0,0 +1,257 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FidoNet Technology Network - Basic Data Structures. +// ------------------------------------------------------------------ + +#ifndef __gftnall_h +#define __gftnall_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// FTN contants + +class ftn { + +public: + + enum { + wildcard_all = 0xFFFE, // For wildcard '*' + wildcard_first = 0xFFFD, // For wildcard '?' + domain_first = 1, // domain#address + domain_last = 2, // address@domain + domain_limit = 41, + name_limit = 36 + }; +}; + + +// ------------------------------------------------------------------ +// FTN domain type + +typedef char ftn_domain[ftn::domain_limit]; + + +// ------------------------------------------------------------------ +// FTN name type + +typedef char ftn_name[ftn::name_limit]; + + +// ------------------------------------------------------------------ +// FTN 4D address type + +class ftn_addr { + +public: + + word zone; + word net; + word node; + word point; + + ftn_addr() : zone(0), net(0), node(0), point(0) {} + ftn_addr(uint a); + ftn_addr(const char* s); + ftn_addr(const string& s); + ftn_addr(const ftn_addr& a); + ftn_addr(uint zn, uint nt, uint nd, uint pt); + + bool valid() const { return net != 0; } + bool invalid() const { return net == 0; } + + void set_all(uint part); + void set_fast(const ftn_addr& a); + void set_fast(uint zn=0, uint nt=0, uint nd=0, uint pt=0); + void set(uint zn=0, uint nt=0, uint nd=0, uint pt=0); + void set(const ftn_addr& a); + void set(const void* a); + char* set(const char* str, char* dom=NULL, int domsizelimit=ftn::domain_limit); + const char* set(const string& str); + const char* set(const string& str, string& dom, int domsizelimit=ftn::domain_limit); + + void reset(); + void reset_fast(); + void reset(const string& str); + char* reset(const char* str, char* dom=NULL, int domsizelimit=ftn::domain_limit); + void reset(const string& str, string& dom, int domsizelimit=ftn::domain_limit); + + bool match(const ftn_addr& mask) const; + bool equals(const ftn_addr& other) const; + int compare(const ftn_addr& other) const; + + string& make_string(string& str) const; + string& make_string(string& str, const string& dom, int domfmt=ftn::domain_last) const; + char* make_string(char* str, const char* dom=NULL, int domfmt=ftn::domain_last) const; + + bool operator==(const ftn_addr& b) const; + bool operator!=(const ftn_addr& b) const; + + ftn_addr& operator=(int n); + ftn_addr& operator=(const char* s); + ftn_addr& operator=(const string& s); + ftn_addr& operator=(const ftn_addr& a); +}; + + +// ------------------------------------------------------------------ + +struct ftn_aka { + + ftn_addr addr; + ftn_domain domain; + word pointnet; +}; + + +// ------------------------------------------------------------------ + +inline void ftn_addr::set_fast(const ftn_addr& a) { + + zone = a.zone; + net = a.net; + node = a.node; + point = a.point; +} + + +// ------------------------------------------------------------------ + +inline void ftn_addr::set_fast(uint zn, uint nt, uint nd, uint pt) { + + zone = (word)zn; + net = (word)nt; + node = (word)nd; + point = (word)pt; +} + + +// ------------------------------------------------------------------ + +inline ftn_addr::ftn_addr(uint a) : zone(0), net(0), node(0), point(0) { + + set_fast(a, a, a, a); +} + + +// ------------------------------------------------------------------ + +inline ftn_addr::ftn_addr(const char* s) : zone(0), net(0), node(0), point(0) { + + reset(s); +} + + +// ------------------------------------------------------------------ + +inline ftn_addr::ftn_addr(const string& s) : zone(0), net(0), node(0), point(0) { + + reset(s); +} + + +// ------------------------------------------------------------------ + +inline ftn_addr::ftn_addr(const ftn_addr& a) : zone(0), net(0), node(0), point(0) { + + set_fast(a); +} + + +// ------------------------------------------------------------------ + +inline ftn_addr::ftn_addr(uint zn, uint nt, uint nd, uint pt) : zone(0), net(0), node(0), point(0) { + + set_fast(zn, nt, nd, pt); +} + + +// ------------------------------------------------------------------ + +inline void ftn_addr::reset_fast() { + + set_fast(); +} + + +// ------------------------------------------------------------------ + +inline bool ftn_addr::equals(const ftn_addr& other) const { + + return compare(other) == 0; +} + + +// ------------------------------------------------------------------ + +inline bool ftn_addr::operator==(const ftn_addr& b) const { return equals(b); } +inline bool ftn_addr::operator!=(const ftn_addr& b) const { return !equals(b); } + + +// ------------------------------------------------------------------ + +inline ftn_addr& ftn_addr::operator=(int n) { set_all(n); return *this; } +inline ftn_addr& ftn_addr::operator=(const char* s) { reset(s); return *this; } +inline ftn_addr& ftn_addr::operator=(const string& s) { reset(s); return *this; } +inline ftn_addr& ftn_addr::operator=(const ftn_addr& a) { set_fast(a); return *this; } + + +// ------------------------------------------------------------------ + +class ftn_akamatch { + +public: + + ftn_akamatch& operator=(const ftn_akamatch& o) { mask=o.mask; aka=o.aka; return *this; } + + ftn_addr mask; + ftn_addr aka; +}; + + +// ------------------------------------------------------------------ +// Legacy + +typedef ftn_addr Addr; +typedef ftn_domain Domn; +typedef ftn_aka gaka; + +#define GFTN_ALL ftn::wildcard_all +#define GFTN_FIRST ftn::wildcard_first +#define GFTN_DOMAIN_FIRST ftn::domain_first +#define GFTN_DOMAIN_LAST ftn::domain_last +#define GFTN_DOMAIN_LIMIT ftn::domain_limit + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnl.cpp b/goldlib/gall/gftnnl.cpp new file mode 100644 index 0000000..54c81a4 --- /dev/null +++ b/goldlib/gall/gftnnl.cpp @@ -0,0 +1,103 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Nodelist index. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +void ftn_nodelist_entry::unpack(char* line) { + + *status = NUL; + *system = NUL; + *location = NUL; + *name = NUL; + *phone = NUL; + *baud = NUL; + *flags = NUL; + + strchg(strtrim(line), '_', ' '); + + char* q = line; + char* p = strchr(line, ','); + if(p) { + *p++ = NUL; + strxcpy(status, q, sizeof(status)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + // Skip over number + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(system, q, sizeof(system)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(location, q, sizeof(location)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(name, q, sizeof(name)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(phone, q, sizeof(phone)); + p = strchr((q=p), ','); + sprintf(baud, "%lu", atol(q)); + if(p) + strxcpy(flags, p+1, sizeof(flags)); + } + } + } + } + } + } +} + + +// ------------------------------------------------------------------ + +ftn_nodelist_entry& ftn_nodelist_entry::operator=(const ftn_nodelist_entry& e) { + + addr = e.addr; + strcpy(address, e.address); + strcpy(name, e.name); + strcpy(status, e.status); + strcpy(system, e.system); + strcpy(location, e.location); + strcpy(phone, e.phone); + strcpy(baud, e.baud); + strcpy(flags, e.flags); + + return *this; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gftnnl.h b/goldlib/gall/gftnnl.h new file mode 100644 index 0000000..246f672 --- /dev/null +++ b/goldlib/gall/gftnnl.h @@ -0,0 +1,136 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Nodelist Index Base Class. +// ------------------------------------------------------------------ + +#ifndef __gftnnl_h +#define __gftnnl_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Nodelist entry data structure + +class ftn_nodelist_entry { + +public: + + ftn_addr addr; // FTN 4D address, binary form + char address[30]; // FTN address, string form + char name[80]; // Name of the node (sysop) + char status[20]; // Status of the node + char system[80]; // System name + char location[80]; // System location + char phone[40]; // Phone number + char baud[20]; // Modem baud rate + char flags[80]; // Flags (everything after the baud string) + + void unpack(char* line); + + ftn_nodelist_entry& operator=(const ftn_nodelist_entry& e); + +}; + + +// ------------------------------------------------------------------ +// Nodelist index base class + +class ftn_nodelist_index_base { + +protected: + + ftn_nodelist_entry data; // Nodelist data for current node + const char* nlpath; // Path to the nodelist files + bool exactmatch; // true if an exact match was found + bool isopen; // true if index is open and ready + bool namebrowse; // true if browsing names + long indexmax; // Maximum index value, if possible + long indexpos; // Current index position, if possible + + virtual bool search() = 0; + +public: + + ftn_nodelist_index_base() { indexmax = indexpos = 0; } + virtual ~ftn_nodelist_index_base() { } + + virtual bool can_browse_name() const = 0; + virtual bool can_browse_address() const = 0; + + bool browsing_names() const { return namebrowse; } + bool browsing_addresses() const { return not namebrowse; } + + void set_path(const char* path) { nlpath = path; } + + virtual bool open() = 0; + virtual void close() = 0; + + long index_max() const { return indexmax; } + long index_pos() const { return indexpos; } + + bool is_open() const { return isopen; } + + virtual bool find(const char* name) = 0; + virtual bool find(const ftn_addr& addr) = 0; + + bool find_again() { return search(); } + + bool found() { return exactmatch; } + + virtual bool previous() = 0; + virtual bool next() = 0; + + virtual void first() = 0; + virtual void last() = 0; + + virtual void push_state() = 0; + virtual void pop_state() = 0; + + virtual const char* index_name() const = 0; + virtual const char* nodelist_name() const = 0; + + const ftn_addr& addrs() const { return data.addr; } + const char* address() const { return data.address; } + const char* name() const { return data.name; } + const char* status() const { return data.status; } + const char* system() const { return data.system; } + const char* location() const { return data.location; } + const char* phone() const { return data.phone; } + const char* baud() const { return data.baud; } + const char* flags() const { return data.flags; } + + const ftn_nodelist_entry& entry() const { return data; } + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlfd.cpp b/goldlib/gall/gftnnlfd.cpp new file mode 100644 index 0000000..f8f4139 --- /dev/null +++ b/goldlib/gall/gftnnlfd.cpp @@ -0,0 +1,739 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FrontDoor Nodelist Indexing. +// Based on code kindly provided by Scott Dudley. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +inline const _FDUdx& ftn_frontdoor_nodelist_index::namerec() const { + + return block.node.name[node-1]; +} + + +// ------------------------------------------------------------------ + +inline const _FDFdx& ftn_frontdoor_nodelist_index::addrrec() const { + + return block.node.addr[node-1]; +} + + +// ------------------------------------------------------------------ + +inline const _FDGdx& ftn_frontdoor_nodelist_index::noderec() const { + + return namebrowse ? *((_FDGdx*)&block.node.name[node-1]) : *((_FDGdx*)&block.node.addr[node-1]); +} + + +// ------------------------------------------------------------------ + +int ftn_frontdoor_nodelist_index::namecmp() const { + + #ifdef DEBUG + printf("[%s] [%-15.15s] ", searchname, namerec().name); + #endif + + const char* a = searchname; + const char* b = namerec().name; + int n = 1; + while(n <= 15) { + int d = (int)((byte)*a) - (int)((byte)*b); + if(d != 0) + return d > 0 ? n : -n; + a++; + b++; + n++; + } + return 0; +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::getaddr(ftn_addr& addr) const { + + if(namebrowse) { + addr.zone = (word)((namerec().zone_hi << 8) | namerec().zone_lo); + addr.net = (word)((namerec().net_hi << 8) | namerec().net_lo); + addr.node = (word)((namerec().node_hi << 8) | namerec().node_lo); + addr.point = (word)((namerec().point_hi << 8) | namerec().point_lo); + } + else { + addr.zone = (word)((addrrec().zone_hi << 8) | addrrec().zone_lo); + addr.net = (word)((addrrec().net_hi << 8) | addrrec().net_lo); + addr.node = (word)((addrrec().node_hi << 8) | addrrec().node_lo); + addr.point = (word)((addrrec().point_hi << 8) | addrrec().point_lo); + } +} + + +// ------------------------------------------------------------------ + +int ftn_frontdoor_nodelist_index::addrcmp() const { + + ftn_addr currentaddr; + getaddr(currentaddr); + + #ifdef DEBUG + printf("[%d:%d/%d.%d] [%d:%d/%d.%d] ", + searchaddr.zone, searchaddr.net, searchaddr.node, searchaddr.point, + currentaddr.zone, currentaddr.net, currentaddr.node, currentaddr.point + ); + #endif + + return searchaddr.compare(currentaddr); +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::getstatus(char* _status, int type) const { + + switch(type) { + case ISZC: strcpy(_status, "Zone"); break; + case ISRC: strcpy(_status, "Region"); break; + case ISNC: strcpy(_status, "Host"); break; + case ISHUB: strcpy(_status, "Hub"); break; + case ISPVT: strcpy(_status, "Pvt"); break; + case ISHOLD: strcpy(_status, "Hold"); break; + case ISDOWN: strcpy(_status, "Down"); break; + case ISPOINT: strcpy(_status, "Point"); break; + default: *_status = NUL; + } +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::fetchdata() { + + bool infdpvt = !!(noderec().nlofs & IN_FDNET); + bool infdpoint = !!(noderec().nlofs & IN_FDPOINT); + bool infdnode = !!(noderec().nlofs & IN_FDNODE); + + if(infdnode) { + + int fd = ::sopen(AddPath(nlpath, "FDNODE.FDA"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(fd != -1) { + _FDFdn fda; + while(read(fd, &fda, sizeof(_FDFdn)) == sizeof(_FDFdn)) { + if(not fda.erased) { + if((fda.zone == data.addr.zone) and (fda.net == data.addr.net) and (fda.node == data.addr.node) and (fda.point == data.addr.point)) { + strnp2cc(data.name, fda.user, 36); + strnp2cc(data.system, fda.name, 30); + strnp2cc(data.phone, fda.telephone, 40); + strnp2cc(data.location, fda.location, 40); + switch(fda.maxbaud) { + case ISBAUD300 : strcpy(data.baud, "300"); break; + case ISBAUD1200 : strcpy(data.baud, "1200"); break; + case ISBAUD2400 : strcpy(data.baud, "2400"); break; + case ISBAUD4800 : strcpy(data.baud, "4800"); break; + case ISBAUD7200 : strcpy(data.baud, "7200"); break; + case ISBAUD9600 : strcpy(data.baud, "9600"); break; + case ISBAUD12000 : strcpy(data.baud, "12000"); break; + case ISBAUD14400 : strcpy(data.baud, "14400"); break; + case ISBAUD16800 : strcpy(data.baud, "16800"); break; + case ISBAUD19200 : strcpy(data.baud, "19200"); break; + case ISBAUD38400 : strcpy(data.baud, "38400"); break; + case ISBAUD57600 : strcpy(data.baud, "57600"); break; + case ISBAUD64000 : strcpy(data.baud, "64000"); break; + case ISBAUD76800 : strcpy(data.baud, "76800"); break; + case ISBAUD115200: strcpy(data.baud, "115200"); break; + default: *data.baud = NUL; + } + getstatus(data.status, fda.status); + *data.flags = NUL; + long c = fda.capability; + char* f = data.flags; + if(c & CMflag) strcat(f, "CM,"); + if(c & MOflag) strcat(f, "MO,"); + if(c & LOflag) strcat(f, "LO,"); + if(c & V32flag) strcat(f, "V32,"); + if(c & V32bflag) strcat(f, "V32B,"); + if(c & V33flag) strcat(f, "V33,"); + if(c & V34flag) strcat(f, "V34,"); + if(c & V42flag) strcat(f, "V42,"); + if(c & V42bflag) strcat(f, "V42B,"); + if(c & MNPflag) strcat(f, "MNP,"); + if(c & H96flag) strcat(f, "H96,"); + if(c & HSTflag) strcat(f, "HST,"); + if(c & HST14flag) strcat(f, "H14,"); + if(c & HST16flag) strcat(f, "H16,"); + if(c & MAXflag) strcat(f, "MAX,"); + if(c & PEPflag) strcat(f, "PEP,"); + if(c & ZYXflag) strcat(f, "ZYX,"); + if(c & XAflag) strcat(f, "XA,"); + if(c & XBflag) strcat(f, "XB,"); + if(c & XCflag) strcat(f, "XC,"); + if(c & XPflag) strcat(f, "XP,"); + if(c & XRflag) strcat(f, "XR,"); + if(c & XWflag) strcat(f, "XW,"); + if(c & XXflag) strcat(f, "XX,"); + if(c & FAXflag) strcat(f, "FAX,"); + if(c & UISDNAflag) strcat(f, "V110L,"); + if(c & UISDNBflag) strcat(f, "V110H,"); + if(c & UISDNCflag) strcat(f, "X75,"); + if(*f) f[strlen(f)-1] = NUL; + break; + } + } + } + ::close(fd); + } + } + else { + + int fd = infdpvt ? pfd : (infdpoint ? ppfd : nfd); + long offset = noderec().nlofs & ~(IN_FDNET|IN_FDPOINT); + + char buf[256]; + buf[255] = NUL; + + lseek(fd, offset, SEEK_SET); + read(fd, buf, 255); + if(*buf != ';') { + + char* end = strchr(buf, '\r'); + if(end) + *end = NUL; + + strchg(strtrim(buf), '_', ' '); + + *data.name = NUL; + *data.system = NUL; + *data.location = NUL; + *data.phone = NUL; + *data.flags = NUL; + *data.baud = NUL; + + char* q = buf; + char* p = strchr(buf, ','); + if(p) { + *p++ = NUL; + strxcpy(data.system, q, sizeof(data.system)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(data.location, q, sizeof(data.location)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(data.name, q, sizeof(data.name)); + p = strchr((q=p), ','); + if(p) { + *p++ = NUL; + strxcpy(data.phone, q, sizeof(data.phone)); + p = strchr((q=p), ','); + sprintf(data.baud, "%lu", atol(q)); + if(p) + strxcpy(data.flags, p+1, sizeof(data.flags)); + } + } + } + } + } + + getstatus(data.status, namebrowse ? namerec().type : addrrec().type); + } + + data.addr.make_string(data.address); +} + + +// ------------------------------------------------------------------ + +#ifdef DEBUG +void ftn_frontdoor_nodelist_index::printnode() const { + + printf("<%05d.%05d.%05d.%d> <%02d:%02d> ", + blockno, + block.info.index, + noderec().block_num, + depth, + block.info.nodes, + node + ); +} +#endif + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::getnodedata() { + + #ifdef DEBUG + printnode(); + #endif + getaddr(data.addr); + fetchdata(); +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::getblock() { + + lseek(xfd, (long)blockno*(long)blocksize, SEEK_SET); + read(xfd, &block, blocksize); +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::push() { + + stack[depth].blockno = blockno; + stack[depth].block_num = noderec().block_num; + stack[depth].maxnodes = block.info.nodes; + stack[depth].node = node; + depth++; +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::pop() { + + depth--; + node = stack[depth].node; + blockno = stack[depth].blockno; +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::search() { + + xfd = namebrowse ? ufd : fdfd; + blocksize = namebrowse ? sizeof(_FDUdb) : sizeof(_FDFdb); + + // Read beginning control block + lseek(xfd, 0L, SEEK_SET); + read(xfd, &ctl, sizeof(_FDCtl)); + + // Now trace down the tree, starting at the master index + exactmatch = false; + int diff = 0; + int prevdiff = 0; + blockno = ctl.hdr.master_idx; + maxblockno = (uint)(lseek(xfd, 0L, SEEK_END)/blocksize); + depth = 0; + node = 1; + push(); + + // Do one block at a time... + while((not exactmatch) and (blockno < maxblockno)) { + + // Get one block + node = 0; + getblock(); + + // Scan all nodes in this block to find a match + lastblockno = block.info.index; + do { + node++; + if(namebrowse) { + #ifdef DEBUG + printnode(); + #endif + prevdiff = diff; + diff = namecmp(); + #ifdef DEBUG + printf("{%d}\n", diff); + #endif + if(diff <= 0) { + if(diff == 0) { + exactmatch = true; + } + break; + } + lastblockno = namerec().block_num; + } + else { + #ifdef DEBUG + printnode(); + #endif + prevdiff = diff; + diff = addrcmp(); + #ifdef DEBUG + printf("{%d}\n", diff); + #endif + if(diff <= 0) { + if(diff == 0) { + exactmatch = true; + } + break; + } + lastblockno = addrrec().block_num; + } + } while(node < block.info.nodes); + + if(not exactmatch) { + if(lastblockno) { + push(); + blockno = lastblockno; + } + else { + break; + } + } + } + + if(diff == 0) { + #ifdef DEBUG + printf("Gotcha!\n"); + #endif + while(previous()) { + if(not exactmatch) { + next(); + break; + } + } + return true; + } + else if((prevdiff > 0) and (diff < 0)) { + if(absolute(prevdiff) > absolute(diff)) { + #ifdef DEBUG + printf("Begin lookup at previous blockno.\n"); + #endif + prevnode(); + } + } + else { + #ifdef DEBUG + printf("Begin lookup at current blockno.\n"); + #endif + } + + getnodedata(); + + return exactmatch; +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::prevnode() { + + if(node == 1) { + if(blockno == 1) + return false; + if(depth > 0) { + pop(); + getblock(); + node--; + if(node <= 0) { + blockno = block.info.index; + getblock(); + node = block.info.nodes; + } + } + else { + return false; + } + } + else { + node--; + if(noderec().block_num) { + node++; + push(); + node--; + blockno = noderec().block_num; + getblock(); + node = block.info.nodes; + } + } + + return true; +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::nextnode() { + + if(noderec().block_num) { + // Current node has a block. Go to it. + node++; + push(); + node--; + blockno = noderec().block_num; + node = 1; + getblock(); + } + else if(node >= block.info.nodes) { + // Reached end of nodes in current block. + if(depth > 0) { + if((stack[depth-1].node == stack[depth-1].maxnodes) and (stack[depth-1].block_num == blockno)) + return false; + // Go back to previous block + pop(); + getblock(); + } + else { + // Reached final leaf + return false; + } + } + else { + node++; + } + + return true; +} + + +// ------------------------------------------------------------------ + +ftn_frontdoor_nodelist_index::ftn_frontdoor_nodelist_index() { + + fdfd = nfd = pfd = ppfd = ufd = -1; + is_intermail = false; + isopen = false; + blocksize = 0; + depth = 0; +} + + +// ------------------------------------------------------------------ + +ftn_frontdoor_nodelist_index::~ftn_frontdoor_nodelist_index() { + + if(isopen) + close(); +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::open() { + + if(isopen) + close(); + + if(fexist(AddPath(nlpath, "IMNODE.CTL"))) + is_intermail = true; + + // Open the nodelist binary file first + fdfd = ::sopen(AddPath(nlpath, "NODELIST.FDX"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(fdfd == -1) { + close(); + return false; + } + + // Read the control block up front + read(fdfd, &ctl, sizeof(_FDCtl)); + + // Now use that info to open the primary nodelist + Path primary; + sprintf(nodelist, "NODELIST.%3.3s", ctl.nl_ext); + sprintf(primary, "%s%s", nlpath, nodelist); + nfd = ::sopen(primary, O_RDONLY | O_BINARY, SH_DENYNO, S_STDRD); + // Don't check for failure, since there may not be a primary nodelist! + + // Open the userlist file + ufd = ::sopen(AddPath(nlpath, "USERLIST.FDX"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(ufd == -1) { + close(); + return false; + } + + // Failing to open the private nodelist is not an error, since there may not be one! + pfd = ::sopen(AddPath(nlpath, is_intermail ? "IMNET.PVT" : "FDNET.PVT"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + + // Failing to open the point nodelist is not an error, since there may not be one! + ppfd = ::sopen(AddPath(nlpath, is_intermail ? "IMPOINT.PVT" : "FDPOINT.PVT"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + + isopen = true; + + return true; +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::close() { + + if(fdfd != -1) ::close(fdfd); fdfd = -1; + if(nfd != -1) ::close(nfd); nfd = -1; + if(pfd != -1) ::close(pfd); pfd = -1; + if(ppfd != -1) ::close(ppfd); ppfd = -1; + if(ufd != -1) ::close(ufd); ufd = -1; + + isopen = false; +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::find(const char* lookup_name) { + + char buf[80], tmp[80]; + + strcpy(tmp, lookup_name); + namebrowse = true; + char* ptr = strrchr(tmp, ' '); + if(ptr) { + if(ptr == (tmp+strlen(tmp)-1)) { + while((*ptr == ' ') and (ptr > tmp)) + ptr--; + ptr++; + } + *ptr = NUL; + sprintf(buf, "%s %s", ptr+1, tmp); + *ptr = ' '; + } + else { + strcpy(buf, tmp); + } + strupr(strtrim(buf)); + sprintf(searchname, "%-15.15s", buf); + + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::find(const ftn_addr& addr) { + + namebrowse = false; + searchaddr = addr; + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::previous() { + + bool moved = prevnode(); + if(moved) { + getnodedata(); + compare(); + } + return moved; +} + + +// ------------------------------------------------------------------ + +bool ftn_frontdoor_nodelist_index::next() { + + bool moved = nextnode(); + if(moved) { + getnodedata(); + compare(); + } + return moved; +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::first() { + + if(namebrowse) { + memset(searchname, ' ', sizeof(searchname)-1); + searchname[sizeof(searchname)-1] = NUL; + } + else { + searchaddr.reset(); + } + search(); +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::last() { + + if(namebrowse) { + memset(searchname, 0xFF, sizeof(searchname)-1); + searchname[sizeof(searchname)-1] = NUL; + } + else { + searchaddr.set_all(0xFFFF); + } + search(); +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::push_state() { + + state.node = node; + state.depth = depth; + state.blockno = blockno; + memcpy(state.stack, stack, sizeof(stack)); +} + + +// ------------------------------------------------------------------ + +void ftn_frontdoor_nodelist_index::pop_state() { + + memcpy(stack, state.stack, sizeof(stack)); + blockno = state.blockno; + depth = state.depth; + node = state.node; + getblock(); + getnodedata(); + compare(); +} + + +// ------------------------------------------------------------------ + +const char* ftn_frontdoor_nodelist_index::index_name() const { + + return namebrowse ? "USERLIST.FDX" : "NODELIST.FDX"; +} + + +// ------------------------------------------------------------------ + +const char* ftn_frontdoor_nodelist_index::nodelist_name() const { + + if(noderec().nlofs & IN_FDNODE) + return "FDNODE.FDA"; + else if(noderec().nlofs & IN_FDNET) + return is_intermail ? "IMNET.PVT" : "FDNET.PVT"; + else if(noderec().nlofs & IN_FDPOINT) + return is_intermail ? "IMPOINT.PVT" : "FDPOINT.PVT"; + return nodelist; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlfd.h b/goldlib/gall/gftnnlfd.h new file mode 100644 index 0000000..7fdd6e3 --- /dev/null +++ b/goldlib/gall/gftnnlfd.h @@ -0,0 +1,363 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FrontDoor Nodelist Indexing. +// Derived from code kindly provided by Scott Dudley. +// ------------------------------------------------------------------ + +#ifndef __gftnnlfd_h +#define __gftnnlfd_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +struct _FDHdr { + word rsvd1; + byte rsvd2; + word master_idx; +}; + + +// ------------------------------------------------------------------ +// The four-byte header at the beginning of each Btree block + +struct _FDInf { + char nodes; + word index; + char rsvd[2]; +}; + + +// ------------------------------------------------------------------ +// Layout of first record + +struct _FDCtl { + _FDInf inf; + _FDHdr hdr; + char stuff[246]; + byte unknown; + char nl_ext[3]; +}; + + +// ------------------------------------------------------------------ +// Masks for the nlofs member + +const ulong IN_FDNODE = 0x01000000UL; // Data in FDNODE.FD +const ulong IN_FDNET = 0x10000000UL; // Data in FDNET.PVT +const ulong IN_FDPOINT = 0x20000000UL; // Data in FDPOINT.PVT + + +// ------------------------------------------------------------------ + +struct _FDGdx { + dword nlofs; + word block_num; +}; + + +// ------------------------------------------------------------------ +// A FrontDoor USERLIST.FDX record + +struct _FDUdx { + dword nlofs; // Index into raw nodelist. + word block_num; // Block number (used in index recs only) + word rsvd1; // Unknown + byte rsvd2; // Unknown - always '\x18' + char name[15]; // Space-padded, uppercase + byte zone_hi; // MSB of zone + byte zone_lo; // LSB of zone + byte net_hi; // MSB of net + byte net_lo; // LSB of net + byte node_hi; // MSB of node + byte node_lo; // LSB of node + byte point_hi; // MSB of point + byte point_lo; // LSB of point + byte type; // See TYPE_XXX +}; + + +// ------------------------------------------------------------------ +// Structure of a B-Tree data block in USERLIST.FDX. This structure +// is always 1061 bytes long, and the file length is always a +// multiple of this + +struct _FDUdb { + _FDInf inf; + _FDUdx udx[32]; +}; + + +// ------------------------------------------------------------------ +// A FrontDoor NODELIST.FDX record + +struct _FDFdx { + dword nlofs; // Index into raw nodelist. + word block_num; // Block number (used in index recs only) + word rsvd1; // Unknown + byte rsvd2; // Unknown - always '\x0e' + byte zone_hi; // MSB of zone + byte zone_lo; // LSB of zone + byte net_hi; // MSB of net + byte net_lo; // LSB of net + byte node_hi; // MSB of node + byte node_lo; // LSB of node + byte point_hi; // MSB of point + byte point_lo; // LSB of point + word host_route; // Net# for host routng, or 0 if none + word hub_route; // Hub# for hub routing, or 0 if none + byte type; // See TYPE_XXX + byte sentinel; // Always 0xFF +}; + + +// ------------------------------------------------------------------ +// Structure of a B-Tree data block in NODELIST.FDX. This structure +// is always 741 bytes long, and the file length is always a multiple +// of this + +struct _FDFdb { + _FDInf inf; + _FDFdx fdx[32]; +}; + + +// ------------------------------------------------------------------ +// B-Tree common data block with union for convenience + +struct _FDBlk { + _FDInf info; + union { + _FDUdx name[32]; + _FDFdx addr[32]; + } node; +}; + + +// ------------------------------------------------------------------ +// The private Nodelist Database (FDNODE.FDA) has the following record +// format. Note that the char[] fields are in Pascal fashion. The first +// byte is the length byte. The actual string starts at [1] and the +// string is not NUL terminated. + +// Status +#define ISZC 1 +#define ISRC 2 +#define ISNC 3 +#define ISHUB 4 +#define ISPVT 5 +#define ISHOLD 6 +#define ISDOWN 7 +#define ISPOINT 9 + +// Capability flags +#define CMflag 0x00000002L +#define MOflag 0x00000004L +#define HSTflag 0x00000008L +#define H96flag 0x00000010L +#define PEPflag 0x00000020L +#define MAXflag 0x00000040L +#define XXflag 0x00000080L +#define XBflag 0x00000100L +#define XRflag 0x00000200L +#define XPflag 0x00000400L +#define XWflag 0x00000800L +#define MNPflag 0x00001000L +#define HST14flag 0x00002000L +#define V32flag 0x00004000L +#define V33flag 0x00008000L +#define V34flag 0x00010000L +#define V42flag 0x00020000L +#define XCflag 0x00040000L +#define XAflag 0x00080000L +#define V42bflag 0x00100000L +#define V32bflag 0x00200000L +#define HST16flag 0x00400000L +#define LOflag 0x00800000L +#define ZYXflag 0x01000000L +#define UISDNAflag 0x02000000L +#define UISDNBflag 0x04000000L +#define UISDNCflag 0x08000000L +#define FAXflag 0x10000000L + +// MaxBaud field +#define ISBAUD300 2 +#define ISBAUD1200 4 +#define ISBAUD2400 5 +#define ISBAUD4800 6 +#define ISBAUD7200 10 +#define ISBAUD9600 7 +#define ISBAUD12000 11 +#define ISBAUD14400 12 +#define ISBAUD16800 13 +#define ISBAUD19200 14 +#define ISBAUD38400 15 +#define ISBAUD57600 16 +#define ISBAUD64000 17 +#define ISBAUD76800 18 +#define ISBAUD115200 19 + +// Record structure +struct _FDFdn { + long erased; // Used to signal erased status + byte status; // Zone, host, hub, etc. + word node; // Network address + word net; // + word zone; // + word point; // + word routnode; // Default routing within zone + word routnet; // + word cost; // Cost per minute for system + long capability; // Capability flags + byte maxbaud; // Maximum baud rate + char name[31]; // Name of system + char telephone[41]; // Raw telephone number + char location[41]; // Location of system + char user[37]; // SysOp name + char selecttag[4]; // Group field +}; + + +// ------------------------------------------------------------------ +// + +struct _FDStk { + uint blockno; + uint block_num; + int maxnodes; + int node; +}; + + +// ------------------------------------------------------------------ + +struct _FDstate { + uint depth; + _FDStk stack[8]; + int blockno; + int node; +}; + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +class ftn_frontdoor_nodelist_index : public ftn_nodelist_index_base { + + bool is_intermail; + + int fdfd; + int nfd; + int pfd; + int ppfd; + int ufd; + int xfd; + + _FDCtl ctl; + + _FDBlk block; + uint blocksize; + uint blockno; + uint maxblockno; + uint lastblockno; + int node; + + _FDStk stack[8]; + uint depth; + + _FDstate state; + + char nodelist[13]; + long nodelistoffset; + + char searchname[16]; + ftn_addr searchaddr; + + const _FDUdx& namerec() const; + const _FDFdx& addrrec() const; + const _FDGdx& noderec() const; + void getaddr(ftn_addr& addr) const; + void getblock(); + int namecmp() const; + int addrcmp() const; + void getstatus(char* status, int type) const; + void fetchdata(); + void getnodedata(); + void push(); + void pop(); + bool prevnode(); + bool nextnode(); + void compare() { exactmatch = not (namebrowse ? namecmp() : addrcmp()); } + bool search(); + + #ifdef DEBUG + void printnode() const; + #endif + +public: + + ftn_frontdoor_nodelist_index(); + virtual ~ftn_frontdoor_nodelist_index(); + + bool can_browse_name() const { return true; } + bool can_browse_address() const { return true; } + + bool open(); + void close(); + + bool find(const char* name); + bool find(const ftn_addr& addr); + + bool previous(); + bool next(); + + void first(); + void last(); + + void push_state(); + void pop_state(); + + const char* index_name() const; + const char* nodelist_name() const; + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlfu.cpp b/goldlib/gall/gftnnlfu.cpp new file mode 100644 index 0000000..f5e91e5 --- /dev/null +++ b/goldlib/gall/gftnnlfu.cpp @@ -0,0 +1,306 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FIDOUSER.LST Indexing. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +bool ftn_fidouser_nodelist_index::getnode() { + + #ifdef DEBUG + printf("<%05ld> ", node); + #endif + + lseekset(fh, (node-1L)*62L); + if(read(fh, nodebuf, 62) == 62) { + nodebuf[60] = NUL; + char* ptr = strrchr(nodebuf, ' '); + if(ptr) { + data.addr.reset(ptr+1); + data.addr.make_string(data.address); + *ptr = NUL; + strtrim(nodebuf); + strunrevname(data.name, nodebuf); + *data.status = NUL; + *data.system = NUL; + *data.location = NUL; + *data.phone = NUL; + *data.baud = NUL; + *data.flags = NUL; + return true; + } + } + + return false; +} + + +// ------------------------------------------------------------------ + +int ftn_fidouser_nodelist_index::namecmp() const { + + #ifdef DEBUG + printf("[%s] [%s] ", searchname, nodebuf); + #endif + + const char* a = searchname; + const char* b = nodebuf; + int n = 1; + int d; + while(1) { + d = tolower(*a) - tolower(*b); + if((d != 0) or (*a == NUL) or (*b == NUL)) + break; + a++; + b++; + n++; + } + return d != 0 ? (d > 0 ? n : -n) : 0; +} + + +// ------------------------------------------------------------------ + +bool ftn_fidouser_nodelist_index::search() { + + if(maxnode) { + + long mid; + long left = 0; + long right = maxnode; + int diff = 0; + int prevdiff; + + do { + mid = (left+right)/2; + node = mid + 1; + getnode(); + prevdiff = diff; + diff = namecmp(); + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + if(diff < 0) + right = mid - 1; + else if(diff > 0) + left = mid + 1; + else { + exactmatch = true; + return true; + } + } while(left < right); + + if(left < maxnode) { + node = left + 1; + getnode(); + prevdiff = diff; + diff = namecmp(); + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + if(diff == 0) { + exactmatch = true; + return true; + } + } + + if(absolute(prevdiff) > absolute(diff)) + previous(); + else { + prevdiff = diff; + if(next()) { + diff = namecmp(); + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + if(absolute(prevdiff) >= absolute(diff)) + previous(); + } + } + } + + exactmatch = false; + return false; +} + + +// ------------------------------------------------------------------ + +ftn_fidouser_nodelist_index::ftn_fidouser_nodelist_index() { + + fh = -1; + isopen = false; + nodebuf[62] = NUL; + node = 1; + namebrowse = true; +} + + +// ------------------------------------------------------------------ + +ftn_fidouser_nodelist_index::~ftn_fidouser_nodelist_index() { + + if(isopen) + close(); +} + + +// ------------------------------------------------------------------ + +bool ftn_fidouser_nodelist_index::open() { + + if(isopen) + close(); + + // Open the list file + fh = ::sopen(nlpath, O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(fh == -1) { + close(); + return false; + } + + maxnode = filelength(fh) / 62L; + getnode(); + + isopen = true; + + return true; +} + + +// ------------------------------------------------------------------ + +void ftn_fidouser_nodelist_index::close() { + + if(fh != -1) ::close(fh); fh = -1; + + isopen = false; +} + + +// ------------------------------------------------------------------ + +bool ftn_fidouser_nodelist_index::find(const char* lookup_name) { + + namebrowse = true; + + struplow(strrevname(searchname, lookup_name)); + + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_fidouser_nodelist_index::previous() { + + if(node > 1) { + node--; + bool retval = getnode(); + compare(); + return retval; + } + + return false; +} + + +// ------------------------------------------------------------------ + +bool ftn_fidouser_nodelist_index::next() { + + if(node < maxnode) { + node++; + bool retval = getnode(); + compare(); + return retval; + } + + return false; +} + + +// ------------------------------------------------------------------ + +void ftn_fidouser_nodelist_index::first() { + + node = 1; + getnode(); + compare(); +} + + +// ------------------------------------------------------------------ + +void ftn_fidouser_nodelist_index::last() { + + node = maxnode; + getnode(); + compare(); +} + + +// ------------------------------------------------------------------ + +void ftn_fidouser_nodelist_index::push_state() { + + statenode = node; +} + + +// ------------------------------------------------------------------ + +void ftn_fidouser_nodelist_index::pop_state() { + + node = statenode; + getnode(); + compare(); +} + + +// ------------------------------------------------------------------ + +const char* ftn_fidouser_nodelist_index::index_name() const { + + const char* ptr = strrchr(nlpath, '\\'); + return ptr ? ptr+1 : nlpath; +} + + +// ------------------------------------------------------------------ + +const char* ftn_fidouser_nodelist_index::nodelist_name() const { + + return NULL; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gftnnlfu.h b/goldlib/gall/gftnnlfu.h new file mode 100644 index 0000000..a222f3b --- /dev/null +++ b/goldlib/gall/gftnnlfu.h @@ -0,0 +1,88 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FIDOUSER.LST Indexing. +// ------------------------------------------------------------------ + +#ifndef __GFTNNLFU_H +#define __GFTNNLFU_H + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class ftn_fidouser_nodelist_index : public ftn_nodelist_index_base { + + int fh; + char nodebuf[63]; + long node; + long maxnode; + + long statenode; + + char searchname[80]; + + bool getnode(); + int namecmp() const; + int addrcmp() const { return -1; } + void compare() { exactmatch = not namecmp(); } + bool search(); + +public: + + ftn_fidouser_nodelist_index(); + virtual ~ftn_fidouser_nodelist_index(); + + bool can_browse_name() const { return true; } + bool can_browse_address() const { return false; } + + bool open(); + void close(); + + bool find(const char* name); + bool find(const ftn_addr&) { return false; } + + bool previous(); + bool next(); + + void first(); + void last(); + + void push_state(); + void pop_state(); + + const char* index_name() const; + const char* nodelist_name() const; + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlge.cpp b/goldlib/gall/gftnnlge.cpp new file mode 100644 index 0000000..f9ea4ba --- /dev/null +++ b/goldlib/gall/gftnnlge.cpp @@ -0,0 +1,498 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// GoldED nodelist indexing. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +static char* make_goldnode_name(char* inp) { + + if(*inp == NUL) + return inp; + + char buf[100]; + char* p; + char* q; + + // Convert underlines to spaces + p = inp; + while(*p) + if(*(p++) == '_') + *(p-1) = ' '; + + // Strip leading spaces + p = inp; + while(isspace(*p)) + p++; + q = &inp[strlen(p)-1]; + + // Strip trailing spaces + while(isspace(*q)) + *q-- = NUL; + + // Search for last space or point + while(*q != ' ' and *q != '.' and q > p) + q--; + + // If last char is a point, find last space instead + if(*(q+1) == 0) + while(*q != ' ' and q > p) + q--; + + // Exchange last name and first name(s) + if(p != q) { + strcpy(stpcpy(buf, q+1), ", "); + *(q+(*q == '.' ? 1 : 0)) = NUL; + strcat(buf, p); + strcpy(inp, buf); + } + struplow(inp); + + return inp; +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::fetchdata() { + + int currfileno = (int)((current.pos >> 24) & 0xFF); + + // currfileno == 0xFF: Entry is taken from a userlist, no nodelist available + if(currfileno != lastfileno) { + if(fhx != -1) + ::close(fhx); + + if(currfileno != 0xff) { + fhx = ::sopen(nodelist[currfileno].filename, O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + lastfileno = currfileno; + } else { + fhx = -1; + lastfileno = -1; + } + } + + strunrevname(data.name, current.name); + *data.status = NUL; + *data.system = NUL; + *data.location = NUL; + *data.phone = NUL; + *data.flags = NUL; + *data.baud = NUL; + + if(fhx != -1) { + + char buf[256]; + buf[255] = NUL; + + lseekset(fhx, current.pos & 0x00FFFFFFL); + read(fhx, buf, 255); + if(*buf != ';') { + + char* end = strchr(buf, '\r'); + if(end) + *end = NUL; + + data.unpack(buf); + } + } + + data.addr = current.addr; + data.addr.make_string(data.address); +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::getnode() { + + #ifdef DEBUG + printf("<%05ld> ", node); + #endif + + long seekto = node - 1L; + if(not namebrowse) { + if(index32) { + lseekset(fha, seekto*(long)sizeof(dword)); + dword nseekto; + read(fha, &nseekto, sizeof(dword)); + seekto = nseekto; + } + else { + lseekset(fha, seekto*(long)sizeof(word)); + word nseekto; + read(fha, &nseekto, sizeof(word)); + seekto = nseekto; + } + } + lseekset(fhn, seekto*(long)sizeof(_GEIdx)); + read(fhn, ¤t, sizeof(_GEIdx)); +} + + +// ------------------------------------------------------------------ + +int ftn_golded_nodelist_index::namecmp() const { + + #ifdef DEBUG + printf("[%s] [%s] ", searchname, current.name); + #endif + + const char* a = searchname; + const char* b = current.name; + int n = 1; + int d; + while(1) { + d = tolower(*a) - tolower(*b); + if((d != 0) or (*a == NUL) or (*b == NUL)) + break; + a++; + b++; + n++; + } + return d != 0 ? (d > 0 ? n : -n) : 0; +} + + +// ------------------------------------------------------------------ + +int ftn_golded_nodelist_index::addrcmp() const { + + #ifdef DEBUG + printf("[%d:%d/%d.%d] [%d:%d/%d.%d] ", + searchaddr.zone, searchaddr.net, searchaddr.node, searchaddr.point, + current.addr.zone, current.addr.net, current.addr.node, current.addr.point + ); + #endif + + return searchaddr.compare(current.addr); +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::searchfirst() { + + if(maxnode) { + + long mid; + long left = 0; + long right = maxnode; + int diff = 0; + int prevdiff; + + do { + mid = (left+right)/2; + node = mid + 1; + getnode(); + prevdiff = diff; + diff = namebrowse ? namecmp() : addrcmp(); + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + if(diff < 0) + right = mid - 1; + else if(diff > 0) + left = mid + 1; + else { + exactmatch = true; + fetchdata(); + return true; + } + } while(left < right); + + if(left < maxnode) { + node = left + 1; + getnode(); + prevdiff = diff; + diff = namebrowse ? namecmp() : addrcmp(); + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + if(diff == 0) { + exactmatch = true; + fetchdata(); + return true; + } + } + + if(absolute(prevdiff) > absolute(diff)) + previous(); + else { + prevdiff = diff; + if(next()) { + diff = namebrowse ? namecmp() : addrcmp(); + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + if(absolute(prevdiff) >= absolute(diff)) + previous(); + } + else + fetchdata(); + } + } + + exactmatch = false; + return false; +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::search() { + + if(searchfirst()) { + // Search backwards until first exact match is found + while(previous()) { + if(not exactmatch) { + next(); + break; + } + } + return true; + } + + return false; +} + + +// ------------------------------------------------------------------ + +ftn_golded_nodelist_index::ftn_golded_nodelist_index() { + + fha = fhn = fhx = -1; + nodelist = NULL; + nodelists = 0; + lastfileno = -1; + isopen = false; +} + + +// ------------------------------------------------------------------ + +ftn_golded_nodelist_index::~ftn_golded_nodelist_index() { + + if(isopen) + close(); +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::open() { + + if(isopen) + close(); + + fha = ::sopen(AddPath(nlpath, "goldnode.gxa"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(fha == -1) { + close(); + return false; + } + + fhn = ::sopen(AddPath(nlpath, "goldnode.gxn"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(fhn == -1) { + close(); + return false; + } + + FILE* fp = fopen(AddPath(nlpath, "goldnode.gxl"), "rt"); + if(fp == NULL) { + close(); + return false; + } + + // Read the list index + char buf[256]; + nodelists = 0; + while(fgets(buf, sizeof(buf), fp)) { + nodelist = (fstamp*)throw_realloc(nodelist, (nodelists+1)*sizeof(fstamp)); + char* key; + char* val=buf; + getkeyval(&key, &val); + strcpy(nodelist[nodelists].filename, key); + MapPath(nodelist[nodelists].filename); + nodelist[nodelists].stamp = atol(val); + nodelists++; + } + fclose(fp); + + maxnode = filelength(fha) / sizeof(word); + if(filelength(fhn) / sizeof(_GEIdx) < (size_t)maxnode) { + maxnode = filelength(fha) / sizeof(dword); + index32 = true; + } + else + index32 = false; + + isopen = true; + + return true; +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::close() { + + throw_release(nodelist); + nodelists = 0; + + lastfileno = -1; + + if(fha != -1) ::close(fha); fha = -1; + if(fhn != -1) ::close(fhn); fhn = -1; + if(fhx != -1) ::close(fhx); fhx = -1; + + isopen = false; +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::find(const char* lookup_name) { + + namebrowse = true; + make_goldnode_name(strcpy(searchname, lookup_name)); + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::find(const ftn_addr& addr) { + + namebrowse = false; + searchaddr = addr; + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::previous() { + + if(node > 1) { + node--; + getnode(); + fetchdata(); + compare(); + return true; + } + + return false; +} + + +// ------------------------------------------------------------------ + +bool ftn_golded_nodelist_index::next() { + + if(node < maxnode) { + node++; + getnode(); + fetchdata(); + compare(); + return true; + } + + return false; +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::first() { + + node = 1; + getnode(); + fetchdata(); + compare(); +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::last() { + + node = maxnode; + getnode(); + fetchdata(); + compare(); +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::push_state() { + + statenode = node; +} + + +// ------------------------------------------------------------------ + +void ftn_golded_nodelist_index::pop_state() { + + node = statenode; + getnode(); + fetchdata(); + compare(); +} + + +// ------------------------------------------------------------------ + +const char* ftn_golded_nodelist_index::index_name() const { + + #if defined(__UNIX__) + return namebrowse ? "goldnode.gxn" : "goldnode.gxa"; + #else + return namebrowse ? "GOLDNODE.GXN" : "GOLDNODE.GXA"; + #endif +} + + +// ------------------------------------------------------------------ + +const char* ftn_golded_nodelist_index::nodelist_name() const { + + if(lastfileno == -1) + return index_name(); + + const char* ptr = strrchr(nodelist[lastfileno].filename, '\\'); + return ptr ? ptr+1 : nodelist[lastfileno].filename; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlge.h b/goldlib/gall/gftnnlge.h new file mode 100644 index 0000000..399fc53 --- /dev/null +++ b/goldlib/gall/gftnnlge.h @@ -0,0 +1,128 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// GoldED nodelist indexing. +// ------------------------------------------------------------------ + +#ifndef __gftnnlge_h +#define __gftnnlge_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +struct _GEIdx { + long pos; // File Number OR'ed with pos in nodelist file + ftn_addr addr; // Node address + char name[36]; // Name in reversed form + _GEIdx() : pos(0), addr() { *name = NUL; } + void reset() { pos = 0; addr.reset(); *name = NUL; } +}; + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +class ftn_golded_nodelist_index : public ftn_nodelist_index_base { + +protected: + + struct fstamp { + Path filename; + long stamp; + }; + + int fha; + int fhn; + int fhx; + bool index32; // New (32-bit) address index used? + + fstamp* nodelist; + int nodelists; + + int lastfileno; + + _GEIdx current; + + long node; + long maxnode; + + long statenode; + + char searchname[80]; + ftn_addr searchaddr; + + void fetchdata(); + void getnode(); + int namecmp() const; + int addrcmp() const; + void compare() { exactmatch = not (namebrowse ? namecmp() : addrcmp()); } + bool searchfirst(); + bool search(); + +public: + + ftn_golded_nodelist_index(); + virtual ~ftn_golded_nodelist_index(); + + bool can_browse_name() const { return true; } + bool can_browse_address() const { return true; } + + bool open(); + void close(); + + bool find(const char* name); + bool find(const ftn_addr& addr); + + bool previous(); + bool next(); + + void first(); + void last(); + + void push_state(); + void pop_state(); + + const char* index_name() const; + const char* nodelist_name() const; + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlv7.cpp b/goldlib/gall/gftnnlv7.cpp new file mode 100644 index 0000000..835462e --- /dev/null +++ b/goldlib/gall/gftnnlv7.cpp @@ -0,0 +1,708 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Version 7 nodelist processing module. +// Based on source code from Binkley 2.50. +// V7+ support based on draft #2 by Thomas Waldmann. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +char v7nodeflags[16][9] = { + { "Hub" }, + { "Host" }, + { "Region" }, + { "Zone" }, + { "CM," }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" } +}; + + +// ------------------------------------------------------------------ + +char v7modemtype[8][9] = { + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" }, + { "" } +}; + + +// ------------------------------------------------------------------ +// Unpack a dense version of a symbol (base 40 polynomial) + +static void v7unpack(char* src, char* dest, uint count) { + + // This table has been modified to minimize searches + // 1234567890123456789012345678901234567890 + static char unwrk[] = " EANROSTILCHBDMUGPKYWFVJXZQ-\'0123456789"; + + union { + word w; + byte c[2]; + } u; + + int i, j; + char obuf[4]; + + *dest = NUL; + + while(count) { + + u.c[0] = *src++; + u.c[1] = *src++; + + count -= 2; + + for(j=2; j>=0; j--) { + + i = u.w % 40; + u.w /= (word)40; + obuf[j] = unwrk[i]; + } + + obuf[3] = NUL; + + strcat(dest, obuf); + } + #ifdef DEBUGx + printf("{%s}", dest); + #endif +} + + +// ------------------------------------------------------------------ + +const char* ftn_version7_nodelist_index::namekey() const { + + return key; +} + + +// ------------------------------------------------------------------ + +const ftn_addr& ftn_version7_nodelist_index::addrkey() const { + + return *((ftn_addr*)key); +} + + +// ------------------------------------------------------------------ + +int ftn_version7_nodelist_index::namecmp() const { + + #ifdef DEBUG + printf("[%s] [%s] ", searchname, namekey()); + #endif + + const char* a = searchname; + const char* b = namekey(); + int n = 1; + int d; + while(1) { + d = tolower((uchar)*a) - tolower((uchar)*b); + if((d != 0) or (*a == NUL) or (*b == NUL)) + break; + a++; + b++; + n++; + } + return d != 0 ? (d > 0 ? n : -n) : 0; +} + + +// ------------------------------------------------------------------ + +int ftn_version7_nodelist_index::addrcmp() const { + + #ifdef DEBUG + printf("[%d:%d/%d.%d] [%d:%d/%d.%d] ", + searchaddr.zone, searchaddr.net, searchaddr.node, searchaddr.point, + addrkey()->zone, addrkey()->net, addrkey()->node, keylength == 6 ? 0 : addrkey()->point + ); + #endif + + ftn_addr currentaddr; + currentaddr = addrkey(); + if(keylength == 6) + currentaddr.point = 0; + + return searchaddr.compare(currentaddr); +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::fetchdata() { + + if(node) { + + // Get data package + _V7Data v7data; + lseek(dfh, block.ndx.lnodeblk.leafref[node-1].keyval, SEEK_SET); + read(dfh, &v7data, sizeof(_V7Data)); + + // Reset data buffers + char buf[160], buf2[1024]; + memset(buf, 0, sizeof(buf)); + memset(buf2, 0, sizeof(buf2)); + + // Get phone + read(dfh, data.phone, v7data.phone_len); + data.phone[v7data.phone_len] = NUL; + + // Skip password + lseek(dfh, v7data.password_len, SEEK_CUR); + + // Get packed data and unpack it + read(dfh, buf2, v7data.pack_len); + v7unpack(buf2, buf, v7data.pack_len); + + // Get system name + struplow(strxcpy(data.system, buf, v7data.bname_len+1)); + + // Get name + if(namebrowse) + strunrevname(data.name, namekey()); + else { + char* namep = buf + v7data.bname_len; + strxcpy(data.name, namep, v7data.sname_len+1); + } + struplow(data.name); + + // Get location + char* locationp = buf + v7data.bname_len + v7data.sname_len; + struplow(strxcpy(data.location, locationp, v7data.cname_len+1)); + + // Check if V7+ data is available + char* v7plus = locationp + v7data.cname_len; + dword v7p = 0; + int i, j; + + for(i=0; (i<8) and (*v7plus); v7plus++, i++) { + if(not isxdigit(*v7plus)) + break; + else + v7p = (v7p <<4) | (xtoi(*v7plus)); + } + + use_v7plus = (tfh > 0) and (i == 8); + + if(use_v7plus) { + + lseek(tfh, v7p, SEEK_SET); + + if(v7data.nodeflags & V7_B_Point) // node is a point + lseek(tfh, (long)dtpctl.AllFixSize, SEEK_CUR); + else + lseek(tfh, (long)dtpctl.AllFixSize + (long)dtpctl.AddFixSize, SEEK_CUR); + + word raw_length; + + read(tfh, &raw_length, sizeof(raw_length)); + + if(raw_length < sizeof(buf2)) { + read(tfh, buf2, raw_length); + data.unpack(buf2); + } + } + else { + + // Get status + for(j=1, i=0; i<4; j+=j, i++) { + if(v7data.nodeflags & j) + strcpy(data.status, v7nodeflags[i]); + } + *data.status = NUL; + + // Get baud + sprintf(data.baud, "%lu", 300L * (long)v7data.baudrate); + + // Get flags + *data.flags = NUL; + char* ptr = data.flags; + + for(j=(1<<4),i=4; i<16; j+=j,i++) + if(v7data.nodeflags & j) + ptr = stpcpy(ptr, v7nodeflags[i]); + + // Get modem types + for(j=1,i=0; i<8; j+=j,i++) + if(v7data.modemtype & j) + ptr = stpcpy(ptr, v7modemtype[i]); + + // Erase the trailing comma + if(ptr != data.flags) + *(--ptr) = NUL; + } + + // Get address + data.addr.zone = v7data.zone; + data.addr.net = v7data.net; + data.addr.node = v7data.node; + data.addr.point = (word)((v7data.nodeflags & V7_B_Point) ? v7data.hubnode : 0); + data.addr.make_string(data.address); + } +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::getindexkey() { + + _V7IndxRef* ip = &(block.ndx.inodeblk.indxref[inode-1]); + keylength = ip->indxlen; + memcpy(key, (char*)&block+ip->indxofs, keylength); + key[keylength] = NUL; + + #ifdef DEBUG + printf("ÀÄÄÄ%02d:%02d <%04ld> ", + inode, + block.ndx.inodeblk.indxcnt, + block.ndx.inodeblk.indxref[inode-1].indxptr + ); + #endif +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::getleafkey() { + + _V7LeafRef* lp = &(block.ndx.lnodeblk.leafref[node-1]); + keylength = lp->keylen; + memcpy(key, (char*)&block+lp->keyofs, keylength); + key[keylength] = NUL; + + #ifdef DEBUG + printf("ÀÄÄÄ%02d:%02d ", node, block.ndx.lnodeblk.indxcnt); + #endif +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::getblock() { + + lseek(xfh, blockno*(long)ctl.ndx.ctlblk.ctlblksize, SEEK_SET); + read(xfh, &block, sizeof(_V7Ndx)); + + #ifdef DEBUG + if(block.ndx.inodeblk.indxfirst != -1) { + printf("INDEXINFO: Branch:%ld, Below:%ld, Left:%ld, Right:%ld.\n", + blockno, + block.ndx.inodeblk.indxfirst, + block.ndx.inodeblk.indxblink, + block.ndx.inodeblk.indxflink + ); + } + #endif +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::getleaf() { + + #ifdef DEBUG + printf("LEAF_INFO: Branch:%ld, Left:%ld, Right:%ld.\n", + blockno, + block.ndx.lnodeblk.indxblink, + block.ndx.lnodeblk.indxflink + ); + #endif +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::search() { + + int diff = 0; + int prevdiff = 0; + int previndexdiff = 0; + exactmatch = false; + + xfh = namebrowse ? sfh : nfh; + node = 0; + + // Get CtlRec + lseek(xfh, 0, SEEK_SET); + read(xfh, &ctl, sizeof(_V7Ndx)); + + // The guts of the matter -- walk from CtlRec to Leaf + blockno = ctl.ndx.ctlblk.ctlroot; + memset(&block, 0, sizeof(_V7Ndx)); + inode = 1; + + // Read the first Index node. + getblock(); + + // Follow the node tree until we either match a key right in the + // index node, or locate the leaf node which must contain the data. + while(block.ndx.inodeblk.indxfirst != -1) { + if(block.ndx.inodeblk.indxcnt == 0) { + exactmatch = false; + return false; + } + + for(inode=1; inode<=block.ndx.inodeblk.indxcnt; inode++) { + + getindexkey(); + + diff = namebrowse ? namecmp() : addrcmp(); + previndexdiff = diff; + + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + + if(diff <= 0) + break; + } + + if(inode == 1) + blockno = block.ndx.inodeblk.indxfirst; + else if(diff == 0) + blockno = block.ndx.inodeblk.indxref[inode-1].indxptr; + else + blockno = block.ndx.inodeblk.indxref[(--inode)-1].indxptr; + + getblock(); + } + + // We can only get here if we've found the leafnode which must + // contain our data. Find our guy here or die trying. + + if(block.ndx.lnodeblk.indxcnt != 0) { + + // Search for a higher key + + getleaf(); + + for(node=1; node<=block.ndx.lnodeblk.indxcnt; node++) { + + getleafkey(); + + prevdiff = diff; + diff = namebrowse ? namecmp() : addrcmp(); + + #ifdef DEBUG + printf("(%d)\n", diff); + #endif + + if(diff < 0) + break; + if(diff == 0) { + while(previous()) { + if(not exactmatch) { + next(); + break; + } + } + return true; + } + } + + if((prevdiff > 0) and (diff <0)) { + if(absolute(prevdiff) > absolute(diff)) { + #ifdef DEBUG + printf("Begin lookup at previous blockno.\n"); + #endif + prevnode(); + } + else { + #ifdef DEBUG + printf("Begin lookup at current blockno.\n"); + #endif + } + } + else { + if(absolute(previndexdiff) > absolute(diff)) { + #ifdef DEBUG + printf("Begin lookup at next blockno.\n"); + #endif + nextnode(); + } + else { + #ifdef DEBUG + printf("Begin lookup at this blockno.\n"); + #endif + if(node > 1) + node--; + } + } + + fetchdata(); + } + + return exactmatch; +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::prevnode() { + + if(node == 1) { + // Reached first node in current leaf + if(block.ndx.lnodeblk.indxblink == 0) + return false; + blockno = block.ndx.inodeblk.indxblink; + getblock(); + getleaf(); + node = block.ndx.lnodeblk.indxcnt; + } + else { + node--; + } + getleafkey(); + + return true; +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::nextnode() { + + if(node >= block.ndx.lnodeblk.indxcnt) { + // Reached end of nodes in current leaf + if(block.ndx.lnodeblk.indxflink == 0) + return false; + blockno = block.ndx.inodeblk.indxflink; + getblock(); + getleaf(); + node = 1; + } + else { + node++; + } + getleafkey(); + + return true; +} + + +// ------------------------------------------------------------------ + +ftn_version7_nodelist_index::ftn_version7_nodelist_index() { + + nfh = sfh = dfh = tfh = -1; + use_v7plus = false; + isopen = false; +} + + +// ------------------------------------------------------------------ + +ftn_version7_nodelist_index::~ftn_version7_nodelist_index() { + + if(isopen) + close(); +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::open() { + + if(isopen) + close(); + + nfh = ::sopen(AddPath(nlpath, "NODEX.NDX"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + sfh = ::sopen(AddPath(nlpath, "SYSOP.NDX"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(sfh == -1) + sfh = ::sopen(AddPath(nlpath, "NODEX.SDX"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + dfh = ::sopen(AddPath(nlpath, "NODEX.DAT"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + tfh = ::sopen(AddPath(nlpath, "NODEX.DTP"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + + if((nfh == -1) or (sfh == -1) or (dfh == -1)) { + // Unable to open an index file + close(); + return false; + } + + if(tfh != -1) + read(tfh, &dtpctl, sizeof(_V7DTPCtl)); + + isopen = true; + + return true; +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::close() { + + if(dfh != -1) ::close(dfh); dfh = -1; + if(sfh != -1) ::close(sfh); sfh = -1; + if(nfh != -1) ::close(nfh); nfh = -1; + if(tfh != -1) ::close(tfh); tfh = -1; + + isopen = false; +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::find(const char* lookup_name) { + + namebrowse = true; + + char tmpname[80]; + strcpy(tmpname, lookup_name); + strchg(tmpname, '.', ' '); + struplow(strrevname(searchname, tmpname)); + + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::find(const ftn_addr& addr) { + + namebrowse = false; + searchaddr = addr; + return search(); +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::previous() { + + bool moved = prevnode(); + if(moved) { + fetchdata(); + compare(); + } + return moved; +} + + +// ------------------------------------------------------------------ + +bool ftn_version7_nodelist_index::next() { + + bool moved = nextnode(); + if(moved) { + fetchdata(); + compare(); + } + return moved; +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::first() { + + if(namebrowse) { + *searchname = NUL; + } + else { + searchaddr.reset(); + } + search(); +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::last() { + + if(namebrowse) { + memset(searchname, 0xFF, sizeof(searchname)); + searchname[sizeof(searchname)-1] = NUL; + } + else { + searchaddr.set_all(0xFFFF); + } + search(); +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::push_state() { + + state.blockno = blockno; + state.node = node; +} + + +// ------------------------------------------------------------------ + +void ftn_version7_nodelist_index::pop_state() { + + blockno = state.blockno; + node = state.node; + getblock(); + getleaf(); + getleafkey(); + fetchdata(); + compare(); +} + + +// ------------------------------------------------------------------ + +const char* ftn_version7_nodelist_index::index_name() const { + + return namebrowse ? "SYSOP.NDX" : "NODEX.NDX"; +} + + +// ------------------------------------------------------------------ + +const char* ftn_version7_nodelist_index::nodelist_name() const { + + return use_v7plus ? "NODEX.DTP" : (const char*)NULL; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gftnnlv7.h b/goldlib/gall/gftnnlv7.h new file mode 100644 index 0000000..a07cbee --- /dev/null +++ b/goldlib/gall/gftnnlv7.h @@ -0,0 +1,291 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Version 7 nodelist index. +// Derived from the Binkley 2.50 source code. +// V7+ support based on draft #2 by Thomas Waldmann. +// ------------------------------------------------------------------ + +#ifndef __gftnnlv7_h +#define __gftnnlv7_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------- +// Version 7 Nodelist Index structure. This is a 512-byte record, +// which is defined by three structures: Record 0 is the Control +// Record, then some number of Leaf Node (LNode) Records, then the +// Index Node (INode) Records. This defines an unbalanced binary +// tree. +// +// This description is based on Scott Samet's CBTREE.PAS program. +// +// Used for NODEX.NDX and SYSOP.NDX +// ------------------------------------------------------------------ + + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// Index Node records + +struct _V7IndxRef { + + word indxofs; // Offset of string into block + word indxlen; // Length of string + long indxdata; // Record number of string + long indxptr; // Block number of lower index +}; + + +// ------------------------------------------------------------------ +// Leaf Node records + +struct _V7LeafRef { + + word keyofs; // Offset of string into block + word keylen; // Length of string + long keyval; // Pointer to data block +}; + + +// ------------------------------------------------------------------ +// Index records + +struct _V7Ndx { + + union { + + // Control Record + struct { + word ctlblksize; // Blocksize of Index Blocks + long ctlroot; // Block number of Root + long ctlhiblk; // Block number of last block + long ctlloleaf; // Block number of first leaf + long ctlhileaf; // Block number of last leaf + long ctlfree; // Head of freelist + word ctllvls; // Number of index levels + word ctlparity; // XOR of above fields + } ctlblk; + + // Index Node records + struct { + long indxfirst; // Pointer to next lower level + long indxblink; // Pointer to previous link + long indxflink; // Pointer to next link + short indxcnt; // Count of Items in block + word indxstr; // Offset in block of 1st str + _V7IndxRef indxref[20]; // If IndxFirst is not -1, this is INode + } inodeblk; + + // Leaf Node records + struct { + long indxfirst; // Pointer to next lower level (is -1 in LNodes) + long indxblink; // Pointer to previous link + long indxflink; // Pointer to next link + short indxcnt; // Count of Items in block + word indxstr; // Offset in block of 1st str + _V7LeafRef leafref[30]; + } lnodeblk; + + // Raw index data + char rawndx[512]; + + } ndx; +}; + + +// ------------------------------------------------------------------ +// OPUS 1.20 Version 7 Nodelist structure. +// Copyright 1991 Wynn Wagner III and Doug Boone. + +struct _V7Data { + + word zone; // Zone + word net; // Net + word node; // Node + word hubnode; // Point (if nodeflags&V7_B_point) or hubnode number + word callcost; // Phone company's charge + word msgfee; // Amount charged to user for a message + word nodeflags; // Set of flags (see below) + byte modemtype; // RESERVED for modem type + byte phone_len; // Length of phone number + byte password_len; // Length of password + byte bname_len; // Length of system name + byte sname_len; // Length of sysop name + byte cname_len; // Length of location + byte pack_len; // Length of packed data + byte baudrate; // baud rate divided by 300 +}; + + +// ------------------------------------------------------------------ +// Values for the `_V7Data.nodeflags' field +// ------------------------------------------------------------------ + +#define V7_B_Hub 0x0001 // node is a net hub 00000000 00000001 +#define V7_B_Host 0x0002 // node is a net host 00000000 00000010 +#define V7_B_Region 0x0004 // node is region coord 00000000 00000100 +#define V7_B_Zone 0x0008 // is a zone gateway 00000000 00001000 +#define V7_B_CM 0x0010 // runs continuous mail 00000000 00010000 +#define V7_B_Res1 0x0020 // reserved by Opus 00000000 00100000 +#define V7_B_Res2 0x0040 // reserved by Opus 00000000 01000000 +#define V7_B_Res3 0x0080 // reserved by Opus 00000000 10000000 + +#define V7_B_Res4 0x0100 // reserved by Opus 00000001 00000000 +#define V7_B_Res5 0x0200 // reserved for non-Opus 00000010 00000000 +#define V7_B_Res6 0x0400 // reserved for non-Opus 00000100 00000000 +#define V7_B_Res7 0x0800 // reserved for non-Opus 00001000 00000000 +#define V7_B_Point 0x1000 // node is a point 00010000 00000000 +#define V7_B_Res9 0x2000 // reserved for non-Opus 00100000 00000000 +#define V7_B_Res10 0x4000 // reserved for non-Opus 01000000 00000000 +#define V7_B_Plus 0x8000 // V7+ field length list 10000000 00000000 + +#define V7_Hub 0 +#define V7_Host 1 +#define V7_Region 2 +#define V7_Zone 3 +#define V7_CM 4 +#define V7_Res1 5 +#define V7_Res2 6 +#define V7_Res3 7 + +#define V7_Res4 8 +#define V7_Res5 9 +#define V7_Res6 10 +#define V7_Res7 11 +#define V7_Point 12 +#define V7_Res9 13 +#define V7_Res10 14 +#define V7_Plus 15 + + +// ------------------------------------------------------------------ + +struct _V7Stk { + long blockno; + int node; +}; + + +// ------------------------------------------------------------------ + +struct _V7DTPCtl { + word size; // Size of this control structure + byte Version; // Version of DTP file (current = 0) + byte AllFixSize; // sizeof (_V7DTPAllLnk) + byte AddFixSize; // sizeof (_V7DTPNodeLnk) +}; + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +class ftn_version7_nodelist_index : public ftn_nodelist_index_base { + + int nfh; + int sfh; + int dfh; + int xfh; + int tfh; + + _V7Ndx ctl; + _V7Ndx block; + _V7DTPCtl dtpctl; + + int node; + int inode; + long blockno; + bool use_v7plus; + + char key[160]; + uint keylength; + + _V7Stk state; + + char searchname[80]; + ftn_addr searchaddr; + + void getindexkey(); + void getleafkey(); + void getblock(); + void getleaf(); + + const char* namekey() const; + const ftn_addr& addrkey() const; + + int namecmp() const; + int addrcmp() const; + + void fetchdata(); + + void push(); + void pop(); + bool prevnode(); + bool nextnode(); + void compare() { exactmatch = not (namebrowse ? namecmp() : addrcmp()); } + bool search(); + +public: + + ftn_version7_nodelist_index(); + virtual ~ftn_version7_nodelist_index(); + + bool can_browse_name() const { return true; } + bool can_browse_address() const { return true; } + + bool open(); + void close(); + + bool find(const char* name); + bool find(const ftn_addr& addr); + + bool previous(); + bool next(); + + void first(); + void last(); + + void push_state(); + void pop_state(); + + const char* index_name() const; + const char* nodelist_name() const; + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfuzzy.cpp b/goldlib/gall/gfuzzy.cpp new file mode 100644 index 0000000..993018d --- /dev/null +++ b/goldlib/gall/gfuzzy.cpp @@ -0,0 +1,189 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fuzzy string search. +// ------------------------------------------------------------------ +// +// C++ port and cleanup by Odinn Sorensen, August 1992. +// Dusted off and re-used, March 1994. +// Converted to C++ class, December 1997. +// +// Original source: APPROX.C (found in SNIP1091). +// Original author: John Rex, August 1988. +// +// References: (1) Computer Algorithms, by Sara Baase Addison-Wesley, +// 1988, pp 242-4. +// (2) Hall PAV, Dowling GR: "Approximate string match- +// ing", ACM Computing Surveys, 12:381-402, 1980. +// +// Usage: +// +// pattern, string - Search for pattern in text +// degree - Degree of allowed mismatch (no of chars) +// +// init(pattern, degree, casing) - Setup routine +// findfirst(string) - Find first match +// findnext() - Find next match +// +// Searching is finished when findfirst/next() returns false +// +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +gfuzzy::gfuzzy() { + + ldiffs = NULL; +} + + +// ------------------------------------------------------------------ + +gfuzzy::~gfuzzy() { + + throw_deletearray(ldiffs); +} + + +// ------------------------------------------------------------------ +// Fuzzy search init + +void gfuzzy::init(const char* pat, int fuzzydegree, bool case_sensitive) { + + casing = case_sensitive; + degree = fuzzydegree; + pattern = pat; + plen = strlen(pattern); + + ldiffs = new int [(plen+1)*4]; + throw_new(ldiffs); +} + + +// ------------------------------------------------------------------ + +bool gfuzzy::findfirst(const char* string) { + + textloc = -1; + text = string; + start = text; + + ldiff = ldiffs; + rdiff = ldiff + plen + 1; + loffs = rdiff + plen + 1; + roffs = loffs + plen + 1; + + for(int i=0; i<=plen; i++) { + rdiff[i] = i; // Initial values for right-hand column + roffs[i] = 1; + } + + return findnext(); +} + + +// ------------------------------------------------------------------ +// Fuzzy search next + +bool gfuzzy::findnext() { + + if(start) { + + start = NULL; + howclose = -1; + + while(start == NULL) { // Start computing columns + + if(text[++textloc] == NUL) // Out of text to search! + break; + + int* temp = rdiff; // Move right-hand column to left ... + rdiff = ldiff; // ... so that we can compute new ... + ldiff = temp; // ... right-hand column + rdiff[0] = 0; // Top (boundary) row + + temp = roffs; // And swap offset arrays, too + roffs = loffs; + loffs = temp; + roffs[1] = 0; + + for(int i=0; i 1) { + for(int i=2; i<=plen; i++) { + if(ldiff[i-1] < rdiff[i]) + roffs[i] = loffs[i-1] - 1; + else if(rdiff[i-1] < rdiff[i]) + roffs[i] = roffs[i-1]; + else if(ldiff[i] < rdiff[i]) + roffs[i] = loffs[i] - 1; + else // Then we have ldiff[i-1] == rdiff[i] + roffs[i] = loffs[i-1] - 1; + } + } + + // Now, do we have an approximate match? + if(rdiff[plen] <= degree) { // indeed so! + end = text + textloc; + start = end + roffs[plen]; + howclose = rdiff[plen]; + } + } + } + + return start ? true : false; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gfuzzy.h b/goldlib/gall/gfuzzy.h new file mode 100644 index 0000000..6bccebc --- /dev/null +++ b/goldlib/gall/gfuzzy.h @@ -0,0 +1,76 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fuzzy string search. +// ------------------------------------------------------------------ + +#ifndef __gfuzzy_h +#define __gfuzzy_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class gfuzzy { + +protected: + + const char* text; + const char* pattern; // Pointers to search strings + int textloc; // Current search position in Text + int plen; // Length of Pattern + int degree; // Max degree of allowed mismatch + int* ldiffs; + int* ldiff; + int* rdiff; // Dynamic difference arrays + int* loffs; + int* roffs; // Used to calculate start of match + bool casing; + +public: + + gfuzzy(); + ~gfuzzy(); + + const char* start; + const char* end; + int howclose; + int length() { return end - start + 1; } + + void init(const char* pat, int fuzzydegree, bool case_sensitive); + bool findfirst(const char* string); + bool findnext(); + + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/ghdrmime.cpp b/goldlib/gall/ghdrmime.cpp new file mode 100644 index 0000000..ca9562e --- /dev/null +++ b/goldlib/gall/ghdrmime.cpp @@ -0,0 +1,71 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// MIME header processing. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +const char* mime_crack_encoded_word(const char* encoded_word, char* charset, char* encoding, char* text) { + + if(charset) *charset = NUL; + if(encoding) *encoding = NUL; + if(text) *text = NUL; + + const char* ptr = encoded_word; + if((ptr[0] == '=') and (ptr[1] == '?')) { + ptr += 2; + const char* begin = ptr; + while(*ptr and not is_mime_especial(*ptr)) + ptr++; + if((ptr-begin) and (*ptr == '?')) { + ptr++; + if(charset) + strxcpy(charset, begin, (uint)(ptr-begin)); + begin = ptr; + while(*ptr and not is_mime_especial(*ptr)) + ptr++; + if((ptr-begin) and (*ptr == '?')) { + ptr++; + if(encoding) + strxcpy(encoding, begin, (uint)(ptr-begin)); + begin = ptr; + while(*ptr and (*ptr != '?')) + ptr++; + if(ptr-begin) { + strxcpy(text, begin, 1+(int)(ptr-begin)); + return ptr + (ptr[0] == '?') + (ptr[1] == '='); + } + } + } + } + return NULL; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/ghdrmime.h b/goldlib/gall/ghdrmime.h new file mode 100644 index 0000000..e5e7636 --- /dev/null +++ b/goldlib/gall/ghdrmime.h @@ -0,0 +1,38 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __ghdrmime_h +#define __ghdrmime_h + + +// ------------------------------------------------------------------ + +const char* mime_crack_encoded_word(const char* encoded_word, char* charset, char* encoding, char* text); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdbase.cpp b/goldlib/gall/gkbdbase.cpp new file mode 100644 index 0000000..d828bd5 --- /dev/null +++ b/goldlib/gall/gkbdbase.cpp @@ -0,0 +1,1462 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// Copyright (C) 2000 Jacobo Tarrio +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Keyboard functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + +#if defined(__OS2__) +#define INCL_BASE +#include +#endif + +#ifdef __WIN32__ +#include +#endif + +#if defined(__UNIX__) and not defined(__USE_NCURSES__) +#include +#endif + +#if defined(__DJGPP__) +#include +#endif + +#if defined(__USE_NCURSES__) +#include +#endif + + +// ------------------------------------------------------------------ + +#if defined(__USE_NCURSES__) +int curses_initialized = 0; +#endif + + +// ------------------------------------------------------------------ + +#if defined(__WIN32__) +#define KBD_TEXTMODE (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT) +#endif + + +// ------------------------------------------------------------------ +// Global keyboard data + +#if defined(__WIN32__) and not defined(__USE_NCURSES__) +HANDLE gkbd_hin; +DWORD gkbd_kbdmode; +int gkbd_nt; +#endif + +GKbd gkbd; + +int blanked = false; + +bool right_alt_same_as_left = false; + +// ------------------------------------------------------------------ +// Keyboard Class Initializer + +void GKbd::Init() { + + #if defined(__USE_NCURSES__) + + if(not curses_initialized++) + initscr(); + raw(); + noecho(); + nonl(); + intrflush(stdscr, FALSE); + keypad(stdscr, TRUE); + + // WARNING: this might break with another version of ncurses, or + // with another implementation of curses. I'm putting it here because + // it is quote useful most of the time :-) For other implementations of + // curses, you might have to compile curses yourself to achieve this. -jt + #if defined(NCURSES_VERSION) + ESCDELAY = 50; // ms, slow for a 300bps terminal, fast for humans :-) + #endif + // For more ncurses-dependent code, look at the gkbd_curstable array + // and at the kbxget_raw() function -jt + + #elif defined(__OS2__) + + KBDINFO kbstInfo; + kbstInfo.cb = sizeof(kbstInfo); + KbdGetStatus(&kbstInfo, 0); + kbstInfo.fsMask = (USHORT)((kbstInfo.fsMask & 0xFFF7) | 0x0004); + KbdSetStatus(&kbstInfo, 0); + + #elif defined(__WIN32__) + + OSVERSIONINFO osversion; + osversion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osversion); + gkbd_nt = (osversion.dwPlatformId & VER_PLATFORM_WIN32_NT) ? true : false; + gkbd_hin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, NULL); + GetConsoleMode(gkbd_hin, &gkbd_kbdmode); + if(gkbd_kbdmode & KBD_TEXTMODE) + SetConsoleMode(gkbd_hin, gkbd_kbdmode & ~KBD_TEXTMODE); + + #elif defined(__UNIX__) + + gkbd_tty_init(); + + #endif +} + + +// ------------------------------------------------------------------ +// Keyboard Class constructor + +GKbd::GKbd() { + + kbuf = NULL; + onkey = NULL; + curronkey = NULL; + inmenu = 0; + source = 0; + polling = 0; + tickinterval = 0; + tickvalue = 0; + tickfunc = NULL; + tickpress = 0; + inidle = 0; + quitall = NO; + + // Detect enhanced keyboard by checking bit 4 at 0x00000496 + #if defined(__USE_NCURSES__) + extkbd = true; + #elif defined(__DJGPP__) + extkbd = _farpeekb (_dos_ds, 0x0496) & (1 << 4); + #elif defined(__MSDOS__) + extkbd = *((byte*)0x0496) & (1 << 4); + #elif defined(__OS2__) or defined(__WIN32__) + extkbd = true; + #endif + + Init(); + + #if defined(__UNIX__) and not defined(__USE_NCURSES__) + + gkbd_keymap_init(); + + char escseq[2]; + escseq[1] = NUL; + for(int n=0; n<256; n++) { + escseq[0] = (char)n; + if(n == 0x7F or n == 0x08) + gkbd_define_keysym(escseq, Key_BS); + else if(n == 0x09) + gkbd_define_keysym(escseq, Key_Tab); + else if(n == 0x0D) + gkbd_define_keysym(escseq, Key_Ent); + else + gkbd_define_keysym(escseq, (n < 128) ? (scancode_table[n]|n) : n); + } + + gkbd_define_keysym("^@", 0); + + gkbd_define_keysym("\033[A", Key_Up); + gkbd_define_keysym("\033[B", Key_Dwn); + gkbd_define_keysym("\033[C", Key_Rgt); + gkbd_define_keysym("\033[D", Key_Lft); + + gkbd_define_keysym("\033[[W", Key_C_Up); + gkbd_define_keysym("\033[[Z", Key_C_Dwn); + gkbd_define_keysym("\033[[Y", Key_C_Rgt); + gkbd_define_keysym("\033[[X", Key_C_Lft); + + gkbd_define_keysym("\033[1~", Key_Home); + gkbd_define_keysym("\033[7~", Key_Home); + gkbd_define_keysym("\033[H", Key_Home); + gkbd_define_keysym("\033[2~", Key_Ins); + gkbd_define_keysym("\033[3~", Key_Del); + gkbd_define_keysym("\033[4~", Key_End); + gkbd_define_keysym("\033[8~", Key_End); + gkbd_define_keysym("\033[F", Key_End); + gkbd_define_keysym("\033[5~", Key_PgUp); + gkbd_define_keysym("\033[6~", Key_PgDn); + + gkbd_define_keysym("\033[[A", Key_F1); + gkbd_define_keysym("\033[[B", Key_F2); + gkbd_define_keysym("\033[[C", Key_F3); + gkbd_define_keysym("\033[[D", Key_F4); + gkbd_define_keysym("\033[[E", Key_F5); + gkbd_define_keysym("\033[17~", Key_F6); + gkbd_define_keysym("\033[18~", Key_F7); + gkbd_define_keysym("\033[19~", Key_F8); + gkbd_define_keysym("\033[20~", Key_F9); + gkbd_define_keysym("\033[21~", Key_F10); + + gkbd_define_keysym("\033[23~", Key_S_F1); + gkbd_define_keysym("\033[24~", Key_S_F2); + gkbd_define_keysym("\033[25~", Key_S_F3); + gkbd_define_keysym("\033[26~", Key_S_F4); + gkbd_define_keysym("\033[28~", Key_S_F5); + gkbd_define_keysym("\033[29~", Key_S_F6); + gkbd_define_keysym("\033[31~", Key_S_F7); + gkbd_define_keysym("\033[32~", Key_S_F8); + gkbd_define_keysym("\033[33~", Key_S_F9); + gkbd_define_keysym("\033[34~", Key_S_F10); + + gkbd_define_keysym("\033""0", Key_A_0); + gkbd_define_keysym("\033""1", Key_A_1); + gkbd_define_keysym("\033""2", Key_A_2); + gkbd_define_keysym("\033""3", Key_A_3); + gkbd_define_keysym("\033""4", Key_A_4); + gkbd_define_keysym("\033""5", Key_A_5); + gkbd_define_keysym("\033""6", Key_A_6); + gkbd_define_keysym("\033""7", Key_A_7); + gkbd_define_keysym("\033""8", Key_A_8); + gkbd_define_keysym("\033""9", Key_A_9); + + gkbd_define_keysym("\033a", Key_A_A); + gkbd_define_keysym("\033b", Key_A_B); + gkbd_define_keysym("\033c", Key_A_C); + gkbd_define_keysym("\033d", Key_A_D); + gkbd_define_keysym("\033e", Key_A_E); + gkbd_define_keysym("\033f", Key_A_F); + gkbd_define_keysym("\033g", Key_A_G); + gkbd_define_keysym("\033h", Key_A_H); + gkbd_define_keysym("\033i", Key_A_I); + gkbd_define_keysym("\033j", Key_A_J); + gkbd_define_keysym("\033k", Key_A_K); + gkbd_define_keysym("\033l", Key_A_L); + gkbd_define_keysym("\033m", Key_A_M); + gkbd_define_keysym("\033n", Key_A_N); + gkbd_define_keysym("\033o", Key_A_O); + gkbd_define_keysym("\033p", Key_A_P); + gkbd_define_keysym("\033q", Key_A_Q); + gkbd_define_keysym("\033r", Key_A_R); + gkbd_define_keysym("\033s", Key_A_S); + gkbd_define_keysym("\033t", Key_A_T); + gkbd_define_keysym("\033u", Key_A_U); + gkbd_define_keysym("\033v", Key_A_V); + gkbd_define_keysym("\033w", Key_A_W); + gkbd_define_keysym("\033x", Key_A_X); + gkbd_define_keysym("\033y", Key_A_Y); + gkbd_define_keysym("\033z", Key_A_Z); + + gkbd_define_keysym("^?", Key_BS); + gkbd_define_keysym("\033\x7F", Key_A_BS); + gkbd_define_keysym("\033\x0D", Key_A_Ent); + gkbd_define_keysym("\033\x09", Key_A_Tab); + + #endif +} + + +// ------------------------------------------------------------------ +// Keyboard Class destructor + +GKbd::~GKbd() { + + #if defined(__USE_NCURSES__) + + if(not --curses_initialized) + endwin(); + + #elif defined(__WIN32__) + + if(gkbd_kbdmode & KBD_TEXTMODE) + SetConsoleMode(gkbd_hin, gkbd_kbdmode); + + #elif defined(__UNIX__) + + gkbd_keymap_reset(); + gkbd_tty_reset(); + + #endif +} + + +// ------------------------------------------------------------------ +// Local table for scancode() + +gkey scancode_table[] = { + + Key_C_2 & 0xFF00u, // 0x0300 C <2 @> [NUL] + Key_C_A & 0xFF00u, // 0x1E01 C [SOH] + Key_C_B & 0xFF00u, // 0x3002 C [STX] + Key_C_C & 0xFF00u, // 0x2E03 C [ETX] + Key_C_D & 0xFF00u, // 0x2004 C [EOT] + Key_C_E & 0xFF00u, // 0x1205 C [ENQ] + Key_C_F & 0xFF00u, // 0x2106 C [ACK] + Key_C_G & 0xFF00u, // 0x2207 C [BEL] + Key_C_H & 0xFF00u, // 0x2308 C [BS] + Key_C_I & 0xFF00u, // 0x1709 C [HT] + Key_C_J & 0xFF00u, // 0x240A C [LF] + Key_C_K & 0xFF00u, // 0x250B C [VT] + Key_C_L & 0xFF00u, // 0x260C C [FF] + Key_C_M & 0xFF00u, // 0x320D C [CR] + Key_C_N & 0xFF00u, // 0x310E C [SO] + Key_C_O & 0xFF00u, // 0x180F C [SI] + Key_C_P & 0xFF00u, // 0x1910 C

+ Key_S_Q & 0xFF00u, // 0x1051 + Key_S_R & 0xFF00u, // 0x1352 + Key_S_S & 0xFF00u, // 0x1F53 + Key_S_T & 0xFF00u, // 0x1454 + Key_S_U & 0xFF00u, // 0x1655 + Key_S_V & 0xFF00u, // 0x2F56 + Key_S_W & 0xFF00u, // 0x1157 + Key_S_X & 0xFF00u, // 0x2D58 + Key_S_Y & 0xFF00u, // 0x1559 + Key_S_Z & 0xFF00u, // 0x2C5A + Key_Lbr & 0xFF00u, // 0x1A5B <[> + Key_Bsl & 0xFF00u, // 0x2B5C <\> + Key_Rbr & 0xFF00u, // 0x1B5D <]> + Key_S_6 & 0xFF00u, // 0x075E <6 ^> + Key_S_Min & 0xFF00u, // 0x0C5F <- _> + Key_Grv & 0xFF00u, // 0x2960 <`> + Key_A & 0xFF00u, // 0x1E61 + Key_B & 0xFF00u, // 0x3062 + Key_C & 0xFF00u, // 0x2E63 + Key_D & 0xFF00u, // 0x2064 + Key_E & 0xFF00u, // 0x1265 + Key_F & 0xFF00u, // 0x2166 + Key_G & 0xFF00u, // 0x2267 + Key_H & 0xFF00u, // 0x2368 + Key_I & 0xFF00u, // 0x1769 + Key_J & 0xFF00u, // 0x246A + Key_K & 0xFF00u, // 0x256B + Key_L & 0xFF00u, // 0x266C + Key_M & 0xFF00u, // 0x326D + Key_N & 0xFF00u, // 0x316E + Key_O & 0xFF00u, // 0x186F + Key_P & 0xFF00u, // 0x1970

+ Key_Q & 0xFF00u, // 0x1071 + Key_R & 0xFF00u, // 0x1372 + Key_S & 0xFF00u, // 0x1F73 + Key_T & 0xFF00u, // 0x1474 + Key_U & 0xFF00u, // 0x1675 + Key_V & 0xFF00u, // 0x2F76 + Key_W & 0xFF00u, // 0x1177 + Key_X & 0xFF00u, // 0x2D78 + Key_Y & 0xFF00u, // 0x1579 + Key_Z & 0xFF00u, // 0x2C7A + Key_S_Lbr & 0xFF00u, // 0x1A7B <[ {> + Key_S_Bsl & 0xFF00u, // 0x2B7C <\ |> + Key_S_Rbr & 0xFF00u, // 0x1B7D <] }> + Key_S_Grv & 0xFF00u, // 0x297E <` ~> + Key_C_BS & 0xFF00u // 0x0E7F C [RUB] +}; + + +// ------------------------------------------------------------------ +// Returns the scan code of an ASCII character + +byte scancode(gkey ch) { + + if(KCodAsc(ch) <= 127) + return (byte)(scancode_table[KCodAsc(ch)] >> 8); + return 0; +} + + +// ------------------------------------------------------------------ +// Translate scancode for ASCII keys + +gkey keyscanxlat(gkey k) { + + // Only translate ASCII keys + if(KCodAsc(k)) { + + // if scancode zero and ascii-code non-zero, it's a "explicit" character, + // entered by ALT + , so don't change it + //if(KCodScn(k) == 0x00) + // return k; + + // Check for certain ctrl-keys + switch(KCodAsc(k)) { + + case 0x08: // CtrlH or BackSpace 23/0E + if(KCodScn(k) == 0x0E) + return k; + else + break; + + case 0x09: // CtrlI or Tab 17/0F + if(KCodScn(k) == 0x0F) + return k; + else + break; + + case 0x0A: // CtrlJ or CtrlEnter or GreyCtrlEnter 24/1C/E0 + case 0x0D: // CtrlM or Enter or GreyEnter 32/1C/E0 + if(KCodScn(k) == 0x1C) + return k; + else if(KCodScn(k) == 0xE0) { + KCodScn(k) = 0x1C; // Translate Numpad-Enter to main Enter + return k; + } + else + break; + + case 0x1B: // Ctrl[ or Esc 1A/01 + if(KCodScn(k) == 0x01) + return k; + else + break; + + case 0x15: // CtrlU or Shift3 (on german keyboards) 16/04 + if(KCodScn(k) == 0x04) + return k; + break; + case 0xE0: // Check for extended key and fix it if necessary + if(KCodScn(k)) { + KCodAsc(k) = 0x00; + return k; + } + break; + } + + // Translate scancode of ASCII key to a known value + if (KCodAsc(k) <= 127) + return (gkey)(scancode_table[KCodAsc(k)] | KCodAsc(k)); + else + return (gkey)(KCodAsc(k)); + } + else { + + // Check if its the center key and translate it to '5' + if(k == 0x4c00) + k = (gkey)(scancode_table['5'] | '5'); + + } + + return k; +} + + +// ------------------------------------------------------------------ +// The following tables map curses keyboard codes to BIOS keyboard +// values. + +#if defined(__USE_NCURSES__) + +// This might not work with something other than ncurses... :-( +// If you ever port it to other curses implementation, remember +// that it might have to be changed to another data structure, or +// the array might have to be filled in another manner... + +int gkbd_curstable[] = { + Key_C_Brk, // KEY_BREAK + Key_Dwn, // KEY_DOWN + Key_Up, // KEY_UP + Key_Lft, // KEY_LEFT + Key_Rgt, // KEY_RIGHT + Key_Home, // KEY_HOME + Key_BS, // KEY_BACKSPACE + -1, // KEY_F0 + Key_F1, // KEY_F(1) + Key_F2, // KEY_F(2) + Key_F3, // KEY_F(3) + Key_F4, // KEY_F(4) + Key_F5, // KEY_F(5) + Key_F6, // KEY_F(6) + Key_F7, // KEY_F(7) + Key_F8, // KEY_F(8) + Key_F9, // KEY_F(9) + Key_F10, // KEY_F(10) + Key_F11, // KEY_F(11) + Key_F12, // KEY_F(12) + Key_S_F3, // KEY_F(13) + Key_S_F4, // KEY_F(14) + Key_S_F5, // KEY_F(15) + Key_S_F6, // KEY_F(16) + Key_S_F7, // KEY_F(17) + Key_S_F8, // KEY_F(18) + Key_S_F9, // KEY_F(19) + Key_S_F10, // KEY_F(20) + Key_S_F11, // KEY_F(21) + Key_S_F12, // KEY_F(22) + -1, // KEY_F(23) + -1, // KEY_F(24) + -1, // KEY_F(25) + -1, // KEY_F(26) + -1, // KEY_F(27) + -1, // KEY_F(28) + -1, // KEY_F(29) + -1, // KEY_F(30) + -1, // KEY_F(31) + -1, // KEY_F(32) + -1, // KEY_F(33) + -1, // KEY_F(34) + -1, // KEY_F(35) + -1, // KEY_F(36) + -1, // KEY_F(37) + -1, // KEY_F(38) + -1, // KEY_F(39) + -1, // KEY_F(40) + -1, // KEY_F(41) + -1, // KEY_F(42) + -1, // KEY_F(43) + -1, // KEY_F(44) + -1, // KEY_F(45) + -1, // KEY_F(46) + -1, // KEY_F(47) + -1, // KEY_F(48) + -1, // KEY_F(49) + -1, // KEY_F(50) + -1, // KEY_F(51) + -1, // KEY_F(52) + -1, // KEY_F(53) + -1, // KEY_F(54) + -1, // KEY_F(55) + -1, // KEY_F(56) + -1, // KEY_F(57) + -1, // KEY_F(58) + -1, // KEY_F(59) + -1, // KEY_F(60) + -1, // KEY_F(61) + -1, // KEY_F(62) + -1, // KEY_F(63) + -1, // KEY_DL + -1, // KEY_IL + Key_Del, // KEY_DC + Key_Ins, // KEY_IC + Key_Ins, // KEY_EIC + -1, // KEY_CLEAR + -1, // KEY_EOS + -1, // KEY_EOL + -1, // KEY_SF + -1, // KEY_SR + Key_PgDn, // KEY_NPAGE + Key_PgUp, // KEY_PPAGE + -1, // KEY_STAB + -1, // KEY_CTAB + -1, // KEY_CATAB + Key_Ent, // KEY_ENTER + -1, // KEY_SRESET + -1, // KEY_RESET + -1, // KEY_PRINT + Key_End, // KEY_LL + Key_Home, // KEY_A1 + Key_PgUp, // KEY_A3 + Key_Cent, // KEY_B2 + Key_End, // KEY_C1 + Key_PgDn, // KEY_C3 + Key_S_Tab, // KEY_BTAB + Key_Home, // KEY_BEG + -1, // KEY_CANCEL + -1, // KEY_CLOSE + -1, // KEY_COMMAND + -1, // KEY_COPY + -1, // KEY_CREATE + Key_End, // KEY_END + -1, // KEY_EXIT + -1, // KEY_FIND + -1, // KEY_HELP + -1, // KEY_MARK + -1, // KEY_MESSAGE + -1, // KEY_MOVE + -1, // KEY_NEXT + -1, // KEY_OPEN + -1, // KEY_OPTIONS + -1, // KEY_PREVIOUS + -1, // KEY_REDO + -1, // KEY_REFERENCE + -1, // KEY_REFRESH + -1, // KEY_REPLACE + -1, // KEY_RESTART + -1, // KEY_RESUME + -1, // KEY_SAVE + Key_S_Home,// KEY_SBEG + -1, // KEY_SCANCEL + -1, // KEY_SCOMMAND + -1, // KEY_SCOPY + -1, // KEY_SCREATE + Key_S_Del, // KEY_SDC + -1, // KEY_SDL + -1, // KEY_SELECT + Key_S_End, // KEY_SEND + -1, // KEY_SEOL + -1, // KEY_SEXIT + -1, // KEY_SFIND + -1, // KEY_SHELP + Key_S_Home,// KEY_SHOME + Key_S_Ins, // KEY_SIC + Key_S_Lft, // KEY_SLEFT + -1, // KEY_SMESSAGE + -1, // KEY_SMOVE + -1, // KEY_SNEXT + -1, // KEY_SOPTIONS + -1, // KEY_SPREVIOUS + -1, // KEY_SPRINT + -1, // KEY_SREDO + -1, // KEY_SREPLACE + Key_S_Rgt, // KEY_SRIGHT + -1, // KEY_SRSUME + -1, // KEY_SSAVE + -1, // KEY_SSUSPEND + -1, // KEY_SUNDO + -1, // KEY_SUSPEND + -1, // KEY_UNDO + -1, // KEY_MOUSE + -1 // KEY_RESIZE +}; + +int gkbd_cursgetch(int mode) { + + int key; + nodelay(stdscr, mode); + key = getch(); + nodelay(stdscr, FALSE); + + return key; +} + + +// ------------------------------------------------------------------ +// The following table maps NT virtual keycodes to PC BIOS keyboard +// values. For each virtual keycode there are four possible BIOS +// values: normal, shift, Ctrl, and ALT. Key combinations that have +// no BIOS equivalent have a value of -1, and are ignored. Extended +// (non-ASCII) key values have bit 8 set to 1 using the EXT macro. + +#elif defined(__WIN32__) + +#define EXT(key) ((key)|0x10000) +#define ISEXT(val) ((val)&0x10000) +#define EXTVAL(val) ((val)&0xFF) + +struct kbd { + int keycode; // virtual keycode + int normal; // BIOS keycode - normal + int shift; // BIOS keycode - Shift- + int ctrl; // BIOS keycode - Ctrl- + int alt; // BIOS keycode - Alt- +} __gkbd_nt2b_table [] = +{ + +// ------------------------------------------------------------------ +// Virtual key Normal Shift Control Alt + + { VK_BACK, 0x0E08, 0x0E08, 0x0E7F, EXT(14) }, + { VK_TAB, 0x0F09, EXT(15), EXT(148), EXT(165) }, + { VK_RETURN, 0x1C0D, 0x1C0D, 0x1C0A, EXT(166) }, + { VK_ESCAPE, 0x011B, 0x011B, 0x011B, EXT(1) }, + { VK_SPACE, 0x20, 0x20, 0x20, 0x20, }, + + { '0', '0', ')', -1, EXT(129) }, + { '1', '1', '!', -1, EXT(120) }, + { '2', '2', '@', EXT(3), EXT(121) }, + { '3', '3', '#', -1, EXT(122) }, + { '4', '4', '$', -1, EXT(123) }, + { '5', '5', '%', -1, EXT(124) }, + { '6', '6', '^', 0x1E, EXT(125) }, + { '7', '7', '&', -1, EXT(126) }, + { '8', '8', '*', -1, EXT(127) }, + { '9', '9', '(', -1, EXT(128) }, + + { 'A', 'a', 'A', 0x01, EXT(30) }, + { 'B', 'b', 'B', 0x02, EXT(48) }, + { 'C', 'c', 'C', 0x03, EXT(46) }, + { 'D', 'd', 'D', 0x04, EXT(32) }, + { 'E', 'e', 'E', 0x05, EXT(18) }, + { 'F', 'f', 'F', 0x06, EXT(33) }, + { 'G', 'g', 'G', 0x07, EXT(34) }, + { 'H', 'h', 'H', 0x08, EXT(35) }, + { 'I', 'i', 'I', 0x09, EXT(23) }, + { 'J', 'j', 'J', 0x0A, EXT(36) }, + { 'K', 'k', 'K', 0x0B, EXT(37) }, + { 'L', 'l', 'L', 0x0C, EXT(38) }, + { 'M', 'm', 'M', 0x0D, EXT(50) }, + { 'N', 'n', 'N', 0x0E, EXT(49) }, + { 'O', 'o', 'O', 0x0F, EXT(24) }, + { 'P', 'p', 'P', 0x10, EXT(25) }, + { 'Q', 'q', 'Q', 0x11, EXT(16) }, + { 'R', 'r', 'R', 0x12, EXT(19) }, + { 'S', 's', 'S', 0x13, EXT(31) }, + { 'T', 't', 'T', 0x14, EXT(20) }, + { 'U', 'u', 'U', 0x15, EXT(22) }, + { 'V', 'v', 'V', 0x16, EXT(47) }, + { 'W', 'w', 'W', 0x17, EXT(17) }, + { 'X', 'x', 'X', 0x18, EXT(45) }, + { 'Y', 'y', 'Y', 0x19, EXT(21) }, + { 'Z', 'z', 'Z', 0x1A, EXT(44) }, + + { VK_PRIOR, EXT(73), EXT(73|0x80), EXT(132), EXT(153) }, + { VK_NEXT, EXT(81), EXT(81|0x80), EXT(118), EXT(161) }, + { VK_END, EXT(79), EXT(79|0x80), EXT(117), EXT(159) }, + { VK_HOME, EXT(71), EXT(71|0x80), EXT(119), EXT(151) }, + { VK_LEFT, EXT(75), EXT(75|0x80), EXT(115), EXT(155) }, + { VK_UP, EXT(72), EXT(72|0x80), EXT(141), EXT(152) }, + { VK_RIGHT, EXT(77), EXT(77|0x80), EXT(116), EXT(157) }, + { VK_DOWN, EXT(80), EXT(80|0x80), EXT(145), EXT(160) }, + { VK_INSERT, EXT(82), EXT(82|0x80), EXT(146), EXT(162) }, + { VK_DELETE, EXT(83), EXT(83|0x80), EXT(147), EXT(163) }, + { VK_NUMPAD0, '0', EXT(82|0x80), EXT(146), -1 }, + { VK_NUMPAD1, '1', EXT(79|0x80), EXT(117), -1 }, + { VK_NUMPAD2, '2', EXT(80|0x80), EXT(145), -1 }, + { VK_NUMPAD3, '3', EXT(81|0x80), EXT(118), -1 }, + { VK_NUMPAD4, '4', EXT(75|0x80), EXT(115), -1 }, + { VK_NUMPAD5, '5', EXT(76), EXT(143), -1 }, + { VK_NUMPAD6, '6', EXT(77|0x80), EXT(116), -1 }, + { VK_NUMPAD7, '7', EXT(71|0x80), EXT(119), -1 }, + { VK_NUMPAD8, '8', EXT(72|0x80), EXT(141), -1 }, + { VK_NUMPAD9, '9', EXT(73|0x80), EXT(132), -1 }, + { VK_MULTIPLY, '*', '*', EXT(150), EXT(55) }, + { VK_ADD, '+', '+', EXT(144), EXT(78) }, + { VK_SUBTRACT, '-', '-', EXT(142), EXT(74) }, + { VK_DECIMAL, '.', '.', EXT(83), EXT(147) }, + { VK_DIVIDE, '/', '/', EXT(149), EXT(164) }, + { VK_F1, EXT(59), EXT(84), EXT(94), EXT(104) }, + { VK_F2, EXT(60), EXT(85), EXT(95), EXT(105) }, + { VK_F3, EXT(61), EXT(86), EXT(96), EXT(106) }, + { VK_F4, EXT(62), EXT(87), EXT(97), EXT(107) }, + { VK_F5, EXT(63), EXT(88), EXT(98), EXT(108) }, + { VK_F6, EXT(64), EXT(89), EXT(99), EXT(109) }, + { VK_F7, EXT(65), EXT(90), EXT(100), EXT(110) }, + { VK_F8, EXT(66), EXT(91), EXT(101), EXT(111) }, + { VK_F9, EXT(67), EXT(92), EXT(102), EXT(112) }, + { VK_F10, EXT(68), EXT(93), EXT(103), EXT(113) }, + { VK_F11, EXT(133), EXT(135), EXT(137), EXT(139) }, + { VK_F12, EXT(134), EXT(136), EXT(138), EXT(140) }, + + { -1, -1, -1, -1, -1 } // THE END +}; + + +// ------------------------------------------------------------------ + +int gkbd_nt2bios(INPUT_RECORD& inp) { + + int keycode = inp.Event.KeyEvent.wVirtualKeyCode; + int state = inp.Event.KeyEvent.dwControlKeyState; + int ascii = inp.Event.KeyEvent.uChar.AsciiChar; + + // Look up the virtual keycode in the table. Ignore unrecognized keys. + + kbd* k = &__gkbd_nt2b_table[0]; + while((keycode != k->keycode) and (k->keycode != -1)) + k++; + if(k->keycode == -1) { // value not in table + int c = ascii; + return c ? c : -1; + } + + // Check the state of the shift keys. ALT has highest + // priority, followed by Control, followed by Shift. + // Select the appropriate table entry based on shift state. + + int c; + if(state & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) + c = k->alt; + else if(state & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)) + c = k->ctrl; + else if(state & SHIFT_PRESSED) + c = k->shift; + else { + // If it is a letter key, use the ASCII value supplied + // by NT to take into account the CapsLock state. + if(isupper(keycode)) + c = ascii; + else + c = k->normal; + } + + if(c != -1) + if(ascii and not (right_alt_same_as_left ? (state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) : (state & LEFT_ALT_PRESSED))) + if(isalnum(keycode)) + return ascii; + if(ISEXT(c)) + return EXTVAL(c) << 8; + + return c; +} + +// ------------------------------------------------------------------ + +bool is_numpad_key(const INPUT_RECORD& inp) { + + if(not (inp.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY)) { + switch(inp.Event.KeyEvent.wVirtualKeyCode) { + case 0x0C: + case VK_PRIOR: + case VK_NEXT: + case VK_END: + case VK_HOME: + case VK_LEFT: + case VK_UP: + case VK_RIGHT: + case VK_DOWN: + case VK_INSERT: + case VK_DELETE: + case VK_NUMPAD0: + case VK_NUMPAD1: + case VK_NUMPAD2: + case VK_NUMPAD3: + case VK_NUMPAD4: + case VK_NUMPAD5: + case VK_NUMPAD6: + case VK_NUMPAD7: + case VK_NUMPAD8: + case VK_NUMPAD9: + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ +// Numpad translation table + +#elif defined(__MSDOS__) or defined(__OS2__) + +const word numpad_keys[] = { + 0x4737, 0x4838, 0x4939, 0x0000, + 0x4B34, 0x0000, 0x4D36, 0x0000, + 0x4F31, 0x5032, 0x5133, + 0x5230, 0x532e +}; + +#endif + +// ------------------------------------------------------------------ +// Get key stroke + +gkey kbxget_raw(int mode) { +// mode - =0 - wait for key is pressed (returns code) +// =1 - test if keystroke is available (returns code if YES, +// otherwise returns 0) +// =2 - return Shifts key status + gkey k; + + #if defined(__USE_NCURSES__) + + int key; + if(mode == 2) { + // We can't do much but we can at least this :-) + k = kbxget_raw(1); + key = 0; + switch(k) { + case Key_C_Brk: + key = GCTRL; + break; + case Key_S_Tab: + case Key_S_Home: + case Key_S_Del: + case Key_S_Ins: + case Key_S_Lft: + case Key_S_Rgt: + case Key_S_End: + key = LSHIFT; + break; + } + return key; + } + + // Get keystroke + key = gkbd_cursgetch(mode); + if(key == ERR) + return 0; + + // Prefix for Meta-key or Alt-key sequences + if(key == 27) { + int key2 = gkbd_cursgetch(TRUE); + // If no key follows, it is no Meta- or Alt- seq, but a single Esc + if(key2 == ERR) + k = Key_Esc; + // Compute the right keycode for the alt sequence + else if((key2 >= '1') and (key2 <= '9')) + k = 0x7800 + ((key2 - '1') << 8); + else if(key2 == '0') + k = 0x8100; + else if(isalpha(key2)) + k = (scancode_table[key2]); + else { + // No correct Alt-sequence; ungetch last key and return Esc + if (mode != 1) + ungetch(key2); + k = Key_Esc; + } + + if((key2 != ERR) and (mode == 1)) + ungetch(key2); + } + // Curses sequence; lookup in nice table above + else if(key > KEY_CODE_YES) + k = (gkbd_curstable[key - KEY_MIN]); + else if(key == '\015') + k = Key_Ent; + else if(key == '\011') + k = Key_Tab; + else + k = key; + + if(mode == 1) + ungetch(key); + + #elif defined(__MSDOS__) + + if(gkbd.extkbd) + mode |= 0x10; + + i86 cpu; + cpu.ah((byte)mode); + cpu.genint(0x16); + if(mode & 0x01) + if(cpu.flags() & 0x40) // if ZF is set, no key is available + return 0; + k = (gkey)cpu.ax(); + + if((mode & ~0x10) == 0) { + if((KCodAsc(k) == 0xE0) and (KCodScn(k) != 0)) { + if(kbxget_raw(2) & (LSHIFT | RSHIFT)) { + KCodAsc(k) = 0; + KCodScn(k) |= 0x80; + } + } + else + switch(KCodScn(k)) { + case 0x47: + case 0x48: + case 0x49: + case 0x4B: + case 0x4D: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + { + int shifts = kbxget_raw(2); + if(shifts & (LSHIFT | RSHIFT)) { + if(shifts & NUMLOCK) + KCodAsc(k) = 0; + else { + KCodAsc(k) = 0; + KCodScn(k) |= 0x80; + } + } + } + break; + default: + break; + } + } + + // If you test shift/alt/ctrl status with bios calls (e.g., using + // bioskey (2) or bioskey (0x12)) then you should also use bios calls + // for testing for keys. This can be done with by bioskey (1) or + // bioskey (0x11). Failing to do so can cause trouble in multitasking + // environments like DESQview/X. (Taken from DJGPP documentation) + if((mode & 0x02) == 1) + kbxget_raw(1); + + #elif defined(__OS2__) + + KBDKEYINFO kb; + mode &= 0xF; + if(mode == 0) + KbdCharIn(&kb, IO_WAIT, 0); + else if(mode == 2) { + KbdPeek(&kb, 0); + if(kb.fbStatus) + return (gkey)(kb.fsState & (RSHIFT|LSHIFT|GCTRL|ALT)); + else + return 0; + } + else { + KbdPeek(&kb, 0); + if(!(kb.fbStatus & 0x40)) + return 0; + } + KCodScn(k) = kb.chScan; + KCodAsc(k) = kb.chChar; + if(0x000 == KCodKey(k)) + return KEY_BRK; + if(0xE0 == KCodScn(k)) + KCodScn(k) = 0x1C; + else { + if(0xE0 == KCodAsc(k)) { + // If key on the alphanumeric part then don't touch it. + // This need to enter for example, russian 'p' char (code 0xe0) + if(KCodScn(k) >= 0x38) { + KCodAsc(k) = 0x00; + if(kb.fsState & (LSHIFT | RSHIFT)) + KCodScn(k) |= 0x80; + } + else + KCodScn(k) = 0x00; + } + else + switch(KCodScn(k)) { + case 0x47: + case 0x48: + case 0x49: + case 0x4B: + case 0x4D: + case 0x4F: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + if(kb.fsState & (LSHIFT | RSHIFT)) { + if(kb.fsState & NUMLOCK) + KCodAsc(k) = 0; + else { + KCodAsc(k) = 0; + KCodScn(k) |= 0x80; + } + } + break; + default: + break; + } + } + + #elif defined(__WIN32__) + + INPUT_RECORD inp; + DWORD nread; + + if(mode == 2) { + return 0; + } + else if(mode & 0x01) { + + // Peek at next key + k = 0; + PeekConsoleInput(gkbd_hin, &inp, 1, &nread); + if(nread) { + if((inp.EventType & KEY_EVENT) and inp.Event.KeyEvent.bKeyDown) { + int kc = gkbd_nt2bios(inp); + if((kc != -1) or (inp.Event.KeyEvent.wVirtualKeyCode == 0xBA)) { + k = (gkey)kc; + return k; + } + } + // Discard other events + ReadConsoleInput(gkbd_hin, &inp, 1, &nread); + } + } + else { + + // Get next key + inp.Event.KeyEvent.bKeyDown = false; + while(1) { + + PeekConsoleInput(gkbd_hin, &inp, 1, &nread); + if(not nread) { + WaitForSingleObject(gkbd_hin, 1000); + continue; + } + + if(inp.EventType == KEY_EVENT and inp.Event.KeyEvent.bKeyDown) { + bool alt_pressed = (inp.Event.KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED|RIGHT_ALT_PRESSED)) ? true : false; + // bool right_alt_pressed = (inp.Event.KeyEvent.dwControlKeyState & RIGHT_ALT_PRESSED) ? true : false; + bool enhanced_key = (inp.Event.KeyEvent.dwControlKeyState & ENHANCED_KEY) ? true : false; + bool numpad_key = is_numpad_key(inp); + int vk = inp.Event.KeyEvent.wVirtualKeyCode; + char raw_ch = inp.Event.KeyEvent.uChar.AsciiChar; + int kc; + int test; + char ch; + + if(enhanced_key and (raw_ch == 0xE0)) + inp.Event.KeyEvent.uChar.AsciiChar = raw_ch = 0; + if(gkbd_nt) + test = (inp.Event.KeyEvent.uChar.AsciiChar and not alt_pressed and vk != -1) or (alt_pressed and vk == -1) or (alt_pressed and numpad_key); + else + test = (inp.Event.KeyEvent.uChar.AsciiChar and not alt_pressed and vk != -1) or (alt_pressed and vk == -1) or (alt_pressed and numpad_key) or (vk == 0xBA); + if(test) { + // Ascii char + if(gkbd_nt and not (alt_pressed and numpad_key)) { + ch = raw_ch; + ReadConsoleInput(gkbd_hin, &inp, 1, &nread); + } + else { + ReadConsole(gkbd_hin, &ch, 1, &nread, NULL); + } + if(alt_pressed) { + k = (gkey)ch; + break; + } + if(gkbd_nt) { + if(ch == '\x5E' or ch == '\x7E' or ch == '\x60' or ch == '\xF9' or ch == '\xEF') + inp.Event.KeyEvent.wVirtualKeyCode = (word)(ch << 8); + } + else { + if(ch == '\x5E' or ch == '\x7E' or ch == '\x60' or ch == '\x27' or ch == '\x2E') + inp.Event.KeyEvent.wVirtualKeyCode = (word)(ch << 8); + } + inp.Event.KeyEvent.uChar.AsciiChar = ch; + } + else { + // Control keycode + ReadConsoleInput(gkbd_hin, &inp, 1, &nread); + } + kc = gkbd_nt2bios(inp); + if(kc != -1) { + k = (gkey)kc; + break; + } + } + else { + // Discard other events + ReadConsoleInput(gkbd_hin, &inp, 1, &nread); + } + } + } + + #elif defined(__UNIX__) + + if(mode == 2) { + return 0; + } + else if(mode & 0x01) { + + // Peek at next key + return gkbd_input_pending() ? 0xFFFF : 0; + } + else { + + k = gkbd_getmappedkey(); + } + + #endif + + return k; +} + + +// ------------------------------------------------------------------ +// Get key stroke + +gkey kbxget(int mode) { + + return keyscanxlat(kbxget_raw(mode)); +} + + +// ------------------------------------------------------------------ +// Returns keycode of waiting key or zero if none + +gkey kbxhit() { + + return kbxget(0x01); +} + + +// ------------------------------------------------------------------ +// Clears internal keyboard buffer + +void kbclear() { + + while(gkbd.kbuf != NULL) { + + KBuf *kbuf = gkbd.kbuf->next; + throw_free(gkbd.kbuf); + gkbd.kbuf = kbuf; + } +} + + +// ------------------------------------------------------------------ +// Clear keyboard buffer + +void clearkeys() { + + while(kbxhit()) + kbxget(0x00); +} + + +// ------------------------------------------------------------------ +// Puts a keystroke into the CXL keyboard "buffer" + +int kbput(gkey xch) { + + KBuf* kbuf; + KBuf* temp; + + // allocate space for another keypress record + kbuf=(KBuf*)throw_malloc(sizeof(KBuf)); + + // find last record in linked list + if((temp=gkbd.kbuf)!=NULL) + for(;temp->next!=NULL;temp=temp->next); + + // add new record to end of linked list + kbuf->next=NULL; + kbuf->prev=temp; + if(temp != NULL) + temp->next=kbuf; + + // add keypress info to new record + kbuf->xch=xch; + + // if kbuf pointer was NULL, point it to new record + if(gkbd.kbuf == NULL) + gkbd.kbuf=kbuf; + + // return normally + return 0; +} + + +// ------------------------------------------------------------------ +// Put keys into the real keyboard buffer + +gkey kbput_(gkey xch) { + + #if defined(__MSDOS__) + + #if defined(__DJGPP__) + if(gkbd.extkbd) { + i86 cpu; + + cpu.ah(0x05); + cpu.cx((word)xch); + cpu.genint(0x16); + } + else { + #endif + + #define BufStart (word)peek(0x40,0x80) + #define BufEnd (word)peek(0x40,0x82) + #define BufHead (word)peek(0x40,0x1A) + #define BufTail (word)peek(0x40,0x1C) + #define BufTail_(a) poke(0x40,0x1C,(word)(a)) + + word OldBufTail; + + OldBufTail = BufTail; + if(BufTail == BufEnd-2) + BufTail_(BufStart); + else + BufTail_(BufTail+2); + + if(BufTail == BufHead) + BufTail_(OldBufTail); + else { + poke(0x40, OldBufTail, xch); + } + + #if defined(__DJGPP__) + } + #endif + + #endif + + return xch; +} + + +// ------------------------------------------------------------------ +// Put keys into the real keyboard buffer + +void kbputs_(char* str) { + + char* p; + + for(p=str; *p ;p++) + kbput_(gkey((scancode(*p)<<8)|*p)); +} + + +// ------------------------------------------------------------------ +// Change defined "on-key" list pointer + +KBnd* chgonkey(KBnd* list) { + + KBnd* temp; + + temp = gkbd.onkey; + gkbd.onkey = list; + + return temp; +} + + +// ------------------------------------------------------------------ +// Frees all active onkey definitions from memory + +void freonkey() { + + KBnd* temp; + + // free all onkey records in linked list + while(gkbd.onkey!=NULL) { + temp = gkbd.onkey->prev; + throw_free(gkbd.onkey); + gkbd.onkey = temp; + } +} + + +// ------------------------------------------------------------------ +// Attaches/detaches a key to a function + +int setonkey(gkey keycode, VfvCP func, gkey pass) { + + // search for a keycode that is already defined + KBnd* onkey = gkbd.onkey; + while(onkey) { + if(onkey->keycode == keycode) + break; + onkey = onkey->prev; + } + + // check to see if a key detachment is being requested + if(func == NULL) { + + // if no defined onkey was found, then error + if(onkey == NULL) + return 2; + + // delete record from linked list + KBnd* prev = onkey->prev; + KBnd* next = onkey->next; + if(prev) + prev->next = next; + if(next) + next->prev = prev; + if(onkey == gkbd.onkey) + gkbd.onkey = prev; + + // free memory allocated for deleted record + throw_free(onkey); + } + else { + + // if key was found, change func pointer + // otherwise create a new onkey record + if(onkey) + onkey->func = func; + else { + + // allocate memory for new record + onkey = (KBnd*)throw_malloc(sizeof(KBnd)); + if(onkey == NULL) + return 1; + + // add new record to linked list + if(gkbd.onkey) + gkbd.onkey->next = onkey; + onkey->prev = gkbd.onkey; + onkey->next = NULL; + gkbd.onkey = onkey; + + // save info in onkey record + gkbd.onkey->keycode = keycode; + gkbd.onkey->func = func; + gkbd.onkey->pass = pass; + } + } + + // return normally + return 0; +} + + +// ------------------------------------------------------------------ + +gkey key_tolower(gkey __keycode) { + + if(isupper(KCodAsc(__keycode))) + return (gkey)(__keycode + 'a' - 'A'); + return __keycode; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdbase.h b/goldlib/gall/gkbdbase.h new file mode 100644 index 0000000..4338ff5 --- /dev/null +++ b/goldlib/gall/gkbdbase.h @@ -0,0 +1,167 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Keyboard functions. +// ------------------------------------------------------------------ + +#ifndef __gkbdbase_h +#define __gkbdbase_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Simple types + +typedef word gkey; + + +// ------------------------------------------------------------------ +// Keycode object + +inline gkey& KCodKey(gkey &key) { return key; } +inline byte& KCodAsc(gkey &key) { return *(((byte *)&key)+0); } +inline byte& KCodScn(gkey &key) { return *(((byte *)&key)+1); } + + +// ------------------------------------------------------------------ +// Definition of kbuf record + +struct KBuf { + KBuf* prev; // previous record + KBuf* next; // next record + gkey xch; // keypress +}; + + +// ------------------------------------------------------------------ +// Definition of onkey record + +struct KBnd { + KBnd* prev; // pointer to previous record + KBnd* next; // pointer to next record + gkey keycode; // Scan/ASCII code of trap key + VfvCP func; // address of onkey function + gkey pass; // key to pass back, 0=don't pass +}; + + +// ------------------------------------------------------------------ +// Definition of keyboard info record + +class GKbd { + +public: + + KBuf* kbuf; // Pointer to head record in key buffer + KBnd* onkey; // Pointer to head record in onkey list + KBnd* curronkey; // Pointer to current onkey record + int inmenu; // In-menu flag used by menuing functions + int source; // Source of keypress 0=kb, 1=kbuf, 2=mouse + int extkbd; // Extended keyboard 0=none, 1=yes + int polling; // Keyboard polling enabled + Clock tickinterval; // Minimum interval between ticks + Clock tickvalue; // Value from last tick + VfvCP tickfunc; // Function to call when a tick is generated + Clock tickpress; // Tick value at last keypress + bool inidle; // In-idle flag used by tickfunc + bool quitall; // Quit-all flag for menus etc. + + void Init(); + GKbd(); + ~GKbd(); +}; + +extern GKbd gkbd; + + +// ------------------------------------------------------------------ +// Keyboard status codes returned from kbstat() + +#define RSHIFT 1 // right shift pressed +#define LSHIFT 2 // left shift pressed +#define GCTRL 4 // [Ctrl] pressed +#define ALT 8 // [Alt] pressed +#define SCRLOCK 16 // [Scroll Lock] toggled +#define NUMLOCK 32 // [Num Lock] toggled +#define CAPSLOCK 64 // [Caps Lock] toggled +#define INS 128 // [Ins] toggled + + +// ------------------------------------------------------------------ + +extern gkey scancode_table[]; +extern bool right_alt_same_as_left; + + +// ------------------------------------------------------------------ +// Function prototypes + +KBnd* chgonkey (KBnd* kblist); +void clearkeys (); +void freonkey (); +int setonkey (gkey keycode, VfvCP func, gkey pass); +gkey getxch (int __tick=false); +void kbclear (); +gkey kbmhit (); +gkey kbxget (int mode=0); +gkey kbxhit (); +int kbput (gkey xch); +word kbput_ (gkey xch); +void kbputs_ (char* str); +byte scancode (gkey ch); +gkey waitkey (); +gkey waitkeyt (int duration); + +gkey key_tolower(gkey __keycode); + +gkey keyscanxlat(gkey k); + +gkey __kbxget(int __mode=0, long __ticks=0, VfvCP __idlefunc=NULL); + +void gkbdtickpressreset(); +void gkbdtickvaluereset(); + + +// ------------------------------------------------------------------ +// Inline functions + +inline gkey getxchtick() { return getxch(true); } +inline void kbdsettickfunc(VfvCP func) { gkbd.tickfunc = func; } + + +// ------------------------------------------------------------------ +// Shorthand definitions of keyboard scancodes + +#define KEY_BRK 0xFFFF // ^Break return from _KeyHit()/_KeyGet() + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdcode.h b/goldlib/gall/gkbdcode.h new file mode 100644 index 0000000..8d33d0f --- /dev/null +++ b/goldlib/gall/gkbdcode.h @@ -0,0 +1,465 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Define mnemonic symbols for full set of PC-Compatible non-display +// control and extended keycodes. +// ------------------------------------------------------------------ + +#ifndef __gkbdcode_h +#define __gkbdcode_h + + +// ------------------------------------------------------------------ +// Notes and Caveats (from the original TCXL 6.0 TCXLCOD.H file) +// +// 1. The keycode symbols suffixed with 'G' and marked in the 'G' +// column are the "Grey" keys around the numeric keypad or in a +// separate cursor-key cluster on "enhanced" keyboards. Those +// marked in the 'N' column are on numeric keypad. +// 2. The keycodes marked in the 'E' column are only available on +// "enhanced" 101/102-key keyboards with extended keyboard BIOS +// support enabled. The extended BIOS returns keycodes containing +// 0xE0 to distinguish duplicated keys, which are marked in the +// 'T' column. +// 3. If an "enhanced" keyboard and extended BIOS is detected, the +// DEFAULT is to enable extended BIOS support and translation of +// any duplicate extended keycodes. +// 4. Keycodes are ordered by character-code, then scan-code. +// 5. Control-Break, which has an actual keycode of 0x000 is +// returned as 0xFFFF. +// 6. The ASCII control-code names are shown in square brackets. +// 7. The Key_M_??? mouse-return codes are those returned by +// _MouGet(). +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#define Key_Lsr '<' +#define Key_Gtr '>' +#define Key_Multi '*' +#define Key_Plus '+' +#define Key_Minus '-' + + +// ------------------------------------------------------------------ + //- Normal key -------- N G E T - +#define Key_0 '0' // <0> - - - - +#define Key_1 '1' // <1> - - - - +#define Key_2 '2' // <2> - - - - +#define Key_3 '3' // <3> - - - - +#define Key_4 '4' // <4> - - - - +#define Key_5 '5' // <5> - - - - +#define Key_6 '6' // <6> - - - - +#define Key_7 '7' // <7> - - - - +#define Key_8 '8' // <8> - - - - +#define Key_9 '9' // <9> - - - - + +#define Key_A 0x1E61 // - - - - +#define Key_B 0x3062 // - - - - +#define Key_C 0x2E63 // - - - - +#define Key_D 0x2064 // - - - - +#define Key_E 0x1265 // - - - - +#define Key_F 0x2166 // - - - - +#define Key_G 0x2267 // - - - - +#define Key_H 0x2368 // - - - - +#define Key_I 0x1769 // - - - - +#define Key_J 0x246a // - - - - +#define Key_K 0x256b // - - - - +#define Key_L 0x266c // - - - - +#define Key_M 0x326d // - - - - +#define Key_N 0x316e // - - - - +#define Key_O 0x186f // - - - - +#define Key_P 0x1970 //

- - - - +#define Key_Q 0x1071 // - - - - +#define Key_R 0x1372 // - - - - +#define Key_S 0x1F73 // - - - - +#define Key_T 0x1474 // - - - - +#define Key_U 0x1675 // - - - - +#define Key_V 0x2F76 // - - - - +#define Key_W 0x1177 // - - - - +#define Key_X 0x2D78 // - - - - +#define Key_Y 0x1579 // - - - - +#define Key_Z 0x2C7A // - - - - +#define Key_StrG 0x372A // <*> - G - - +#define Key_PlsG 0x4E2B // <+> - G - - +#define Key_Com 0x332C // <,> - - - - +#define Key_MinG 0x4A2D // <-> - G - - +#define Key_Dot 0x342E // <.> - - - - +#define Key_BS 0x0E08 // - - - - +#define Key_Cent 0x4C00 // N - E - +#define Key_Del 0x5300 // N - - - +#define Key_DelG 0x53E0 // Grey - G E T +#define Key_Dwn 0x5000 // N - - - +#define Key_DwnG 0x50E0 // Grey - G E T +#define Key_End 0x4F00 // N - - - +#define Key_EndG 0x4FE0 // Grey - G E T +#define Key_Ent 0x1C0D // - - - - +#define Key_EntG 0xE00D // Grey - G E T +#define Key_Esc 0x011B // - - - - +#define Key_F1 0x3B00 // - - - - +#define Key_F2 0x3C00 // - - - - +#define Key_F3 0x3D00 // - - - - +#define Key_F4 0x3E00 // - - - - +#define Key_F5 0x3F00 // - - - - +#define Key_F6 0x4000 // - - - - +#define Key_F7 0x4100 // - - - - +#define Key_F8 0x4200 // - - - - +#define Key_F9 0x4300 // - - - - +#define Key_F10 0x4400 // - - - - +#define Key_F11 0x8500 // - - E - +#define Key_F12 0x8600 // - - E - +#define Key_Home 0x4700 // N - - - +#define Key_HomeG 0x47E0 // Grey - G E T +#define Key_Ins 0x5200 // N - - - +#define Key_InsG 0x52E0 // Grey - G E T +#define Key_Lft 0x4B00 // N - - - +#define Key_LftG 0x4BE0 // Grey - G E T +#define Key_PgDn 0x5100 // N - - - +#define Key_PgDnG 0x51E0 // Grey - G E T +#define Key_PgUp 0x4900 // N - - - +#define Key_PgUpG 0x49E0 // Grey - G E T +#define Key_Rgt 0x4D00 // N - - - +#define Key_RgtG 0x4DE0 // Grey - G E T +#define Key_Space 0x3920 // - - - - +#define Key_Tab 0x0F09 // - - - - +#define Key_Up 0x4800 // N - - - +#define Key_UpG 0x48E0 // Grey - G E T +#define Key_Quo 0x2827 // <'> - - - - +#define Key_Min 0x0C2D // <-> - - - - +#define Key_Sls 0x352F // - - - - +#define Key_Smi 0x273B // <;> - - - - +#define Key_Equ 0x0D3D // <=> - - - - +#define Key_Lbr 0x1A5B // <[> - - - - +#define Key_Bsl 0x2B5C // <\> - - - - +#define Key_Rbr 0x1B5D // <]> - - - - +#define Key_Grv 0x2960 // <`> - - - - + +// ------------------------------------------------------------------ + //- Shift key --------- N G E T - +#define Key_S_0 0x0B29 // <0 )> - - - - +#define Key_S_1 0x0221 // <1 !> - - - - +#define Key_S_2 0x0340 // <2 @> - - - - +#define Key_S_3 0x0423 // <3 #> - - - - +#define Key_S_4 0x0524 // <4 $> - - - - +#define Key_S_5 0x0625 // <5 %> - - - - +#define Key_S_6 0x075E // <6 ^> - - - - +#define Key_S_7 0x0826 // <7 &> - - - - +#define Key_S_8 0x092A // <8 *> - - - - +#define Key_S_9 0x0A28 // <9 (> - - - - +#define Key_S_A 0x1E41 // - - - - +#define Key_S_B 0x3042 // - - - - +#define Key_S_C 0x2E43 // - - - - +#define Key_S_D 0x2044 // - - - - +#define Key_S_E 0x1245 // - - - - +#define Key_S_F 0x2146 // - - - - +#define Key_S_G 0x2247 // - - - - +#define Key_S_H 0x2348 // - - - - +#define Key_S_I 0x1749 // - - - - +#define Key_S_J 0x244a // - - - - +#define Key_S_K 0x254b // - - - - +#define Key_S_L 0x264c // - - - - +#define Key_S_M 0x324d // - - - - +#define Key_S_N 0x314e // - - - - +#define Key_S_O 0x184f // - - - - +#define Key_S_P 0x1950 //

- - - - +#define Key_S_Q 0x1051 // - - - - +#define Key_S_R 0x1352 // - - - - +#define Key_S_S 0x1F53 // - - - - +#define Key_S_T 0x1454 // - - - - +#define Key_S_U 0x1655 // - - - - +#define Key_S_V 0x2F56 // - - - - +#define Key_S_W 0x1157 // - - - - +#define Key_S_X 0x2D58 // - - - - +#define Key_S_Y 0x1559 // - - - - +#define Key_S_Z 0x2C5a // - - - - +#define Key_S_Quo 0x2822 // <' "> - - - - +#define Key_S_Com 0x333C // <, >> - - - - +#define Key_S_Min 0x0C5F // <- _> - - - - +#define Key_S_Dot 0x343E // <. <> - - - - +#define Key_S_Sls 0x353F // - - - - +#define Key_S_Smi 0x273A // <; :> - - - - +#define Key_S_Equ 0x0D2B // <= +> - - - - +#define Key_S_Lbr 0x1A7B // <[ {> - - - - +#define Key_S_Bsl 0x2B7C // <\ |> - - - - +#define Key_S_Rbr 0x1B7D // <] }> - - - - +#define Key_S_Grv 0x297E // <` ~> - - - - +#define Key_S_Num5 0x4C35 // S N - - - +#define Key_S_F1 0x5400 // S - - - - +#define Key_S_F2 0x5500 // S - - - - +#define Key_S_F3 0x5600 // S - - - - +#define Key_S_F4 0x5700 // S - - - - +#define Key_S_F5 0x5800 // S - - - - +#define Key_S_F6 0x5900 // S - - - - +#define Key_S_F7 0x5A00 // S - - - - +#define Key_S_F8 0x5B00 // S - - - - +#define Key_S_F9 0x5C00 // S - - - - +#define Key_S_F10 0x5D00 // S - - - - +#define Key_S_F11 0x8700 // S - - E - +#define Key_S_F12 0x8800 // S - - E - +#define Key_S_Tab 0x0F00 // S - - - - +#if not defined(__UNIX__) or defined(__USE_NCURSES__) +#define Key_S_Ins 0xD200 // S Grey - G E T +#define Key_S_Lft 0xCB00 // S Grey - G E T +#define Key_S_PgDn 0xD100 // S Grey - G E T +#define Key_S_PgUp 0xC900 // S Grey - G E T +#define Key_S_Rgt 0xCD00 // S Grey - G E T +#define Key_S_Up 0xC800 // S Grey - G E T +#define Key_S_Dwn 0xD000 // S Grey - G E T +#define Key_S_End 0xCF00 // S Grey - G E T +#define Key_S_Home 0xC700 // S Grey - G E T +#define Key_S_Del 0xD300 // S N - - - +#else +#define Key_S_Home 0x4737 // S N - - - +#define Key_S_HomeG 0x47E0 // S Grey - G E T +#define Key_S_Ins 0x5230 // S N - - - +#define Key_S_InsG 0x52E0 // S Grey - G E T +#define Key_S_Lft 0x4B34 // S N - - - +#define Key_S_LftG 0x4BE0 // S Grey - G E T +#define Key_S_PgDn 0x5133 // S N - - - +#define Key_S_PgDnG 0x51E0 // S Grey - G E T +#define Key_S_PgUp 0x4939 // S N - - - +#define Key_S_PgUpG 0x49E0 // S Grey - G E T +#define Key_S_Rgt 0x4D36 // S N - - - +#define Key_S_RgtG 0x4DE0 // S Grey - G E T +#define Key_S_Up 0x4838 // S N - - - +#define Key_S_UpG 0x48E0 // S Grey - G E T +#define Key_S_Dwn 0x5032 // S N - - - +#define Key_S_DwnG 0x50E0 // S Grey - G E T +#define Key_S_End 0x4F31 // S N - - - +#define Key_S_EndG 0x4FE0 // S Grey - G E T +#define Key_S_Del 0x532E // S N - - - +#define Key_S_DelG 0x53E0 // S Grey - G E T +#endif + +// ------------------------------------------------------------------ + //- Control key ------- N G E T - +#define Key_C_2 0x0300 // C <2 @> [NUL] - - - - +#define Key_C_A 0x1E01 // C [SOH] - - - - +#define Key_C_B 0x3002 // C [STX] - - - - +#define Key_C_C 0x2E03 // C [ETX] - - - - +#define Key_C_D 0x2004 // C [EOT] - - - - +#define Key_C_E 0x1205 // C [ENQ] - - - - +#define Key_C_F 0x2106 // C [ACK] - - - - +#define Key_C_G 0x2207 // C [BEL] - - - - +#define Key_C_H 0x2308 // C [BS] - - - - +#define Key_C_I 0x1709 // C [HT] - - - - +#define Key_C_J 0x240A // C [LF] - - - - +#define Key_C_K 0x250B // C [VT] - - - - +#define Key_C_L 0x260C // C [FF] - - - - +#define Key_C_M 0x320D // C [CR] - - - - +#define Key_C_N 0x310E // C [SO] - - - - +#define Key_C_O 0x180F // C [SI] - - - - +#define Key_C_P 0x1910 // C

[DLE] - - - - +#define Key_C_Q 0x1011 // C [DC1] - - - - +#define Key_C_R 0x1312 // C [DC2] - - - - +#define Key_C_S 0x1F13 // C [DC3] - - - - +#define Key_C_T 0x1414 // C [DC4] - - - - +#define Key_C_U 0x1615 // C [NAK] - - - - +#define Key_C_V 0x2F16 // C [SYN] - - - - +#define Key_C_W 0x1117 // C [ETB] - - - - +#define Key_C_X 0x2D18 // C [CAN] - - - - +#define Key_C_Y 0x1519 // C [EM] - - - - +#define Key_C_Z 0x2C1A // C [SUB] - - - - +#define Key_C_StrG 0x7200 // C <*> Grey - G E - +#define Key_C_PlsG 0x9000 // C <+> Grey - G E - +#define Key_C_Min 0x0C1F // C <- _> - - - - +#define Key_C_MinG 0x8E00 // C <-> Grey - G E - +#define Key_C_6 0x071E // C <7 &> [RS] - - - - +#define Key_C_Brk 0xFFFF // C Grey - - - - +#define Key_C_BS 0x0E7F // C [RUB] - - - - +#define Key_C_5Num 0x8F00 // C N - E - +#define Key_C_Del 0x9300 // C - - E - +#define Key_C_DelG 0x93E0 // C Grey - G E T +#define Key_C_Dwn 0x9100 // C - - E - +#define Key_C_DwnG 0x91E0 // C Grey - G E T +#define Key_C_End 0x7500 // C N - - - +#define Key_C_EndG 0x75E0 // C Grey - G E T +#define Key_C_EntG 0xE00A // C Grey - G E T +#define Key_C_Ent 0x1C0A // C [LF] - - - - +#define Key_C_F1 0x5E00 // C - - - - +#define Key_C_F2 0x5F00 // C - - - - +#define Key_C_F3 0x6000 // C - - - - +#define Key_C_F4 0x6100 // C - - - - +#define Key_C_F5 0x6200 // C - - - - +#define Key_C_F6 0x6300 // C - - - - +#define Key_C_F7 0x6400 // C - - - - +#define Key_C_F8 0x6500 // C - - - - +#define Key_C_F9 0x6600 // C - - - - +#define Key_C_F10 0x6700 // C - - - - +#define Key_C_F11 0x8900 // C - - E - +#define Key_C_F12 0x8A00 // C - - E - +#define Key_C_Home 0x7700 // C N - - - +#define Key_C_HomeG 0x77E0 // C Grey - G E T +#define Key_C_Ins 0x9200 // C - - E - +#define Key_C_InsG 0x92E0 // C Grey - G E T +#define Key_C_Lft 0x7300 // C N - - - +#define Key_C_LftG 0x73E0 // C Grey - G E T +#define Key_C_PgDn 0x7600 // C N - - - +#define Key_C_PgDnG 0x76E0 // C Grey - G E T +#define Key_C_PgUp 0x8400 // C N - - - +#define Key_C_PgUpG 0x84E0 // C Grey - G E T +#define Key_C_Rgt 0x7400 // C N - - - +#define Key_C_RgtG 0x74E0 // C Grey - G E T +#define Key_C_Tab 0x9400 // C - - E - +#define Key_C_Up 0x8D00 // C - - E - +#define Key_C_UpG 0x8DE0 // C Grey - G E T +#define Key_C_Lbr 0x1A1B // C <[ {> [ESC] - - - - +#define Key_C_Bsl 0x2B1C // C <\ |> [FS] - - - - +#define Key_C_Rbr 0x1B1D // C <] }> [GS] - - - - + +// ------------------------------------------------------------------ + //- Alt key ----------- N G E T - +#define Key_A_0 0x8100 // A <0 )> - - - - +#define Key_A_1 0x7800 // A <1 !> - - - - +#define Key_A_2 0x7900 // A <2 @> - - - - +#define Key_A_3 0x7A00 // A <3 #> - - - - +#define Key_A_4 0x7B00 // A <4 ^> - - - - +#define Key_A_5 0x7C00 // A <5 %> - - - - +#define Key_A_6 0x7D00 // A <6 %> - - - - +#define Key_A_7 0x7E00 // A <7 &> - - - - +#define Key_A_8 0x7F00 // A <8 *> - - - - +#define Key_A_9 0x8000 // A <9 (> - - - - +#define Key_A_A 0x1E00 // A - - - - +#define Key_A_B 0x3000 // A - - - - +#define Key_A_C 0x2E00 // A - - - - +#define Key_A_D 0x2000 // A - - - - +#define Key_A_E 0x1200 // A - - - - +#define Key_A_F 0x2100 // A - - - - +#define Key_A_G 0x2200 // A - - - - +#define Key_A_H 0x2300 // A - - - - +#define Key_A_I 0x1700 // A - - - - +#define Key_A_J 0x2400 // A - - - - +#define Key_A_K 0x2500 // A - - - - +#define Key_A_L 0x2600 // A - - - - +#define Key_A_M 0x3200 // A - - - - +#define Key_A_N 0x3100 // A - - - - +#define Key_A_O 0x1800 // A - - - - +#define Key_A_P 0x1900 // A

- - - - +#define Key_A_Q 0x1000 // A - - - - +#define Key_A_R 0x1300 // A - - - - +#define Key_A_S 0x1F00 // A - - - - +#define Key_A_T 0x1400 // A - - - - +#define Key_A_U 0x1600 // A - - - - +#define Key_A_V 0x2F00 // A - - - - +#define Key_A_W 0x1100 // A - - - - +#define Key_A_X 0x2D00 // A - - - - +#define Key_A_Y 0x1500 // A - - - - +#define Key_A_Z 0x2C00 // A - - - - +#define Key_A_Quo 0x2800 // A <' "> - - E - +#define Key_A_PlsG 0x4E00 // A <+> Grey - G E - +#define Key_A_Com 0x3300 // A <, <> - - E - +#define Key_A_Min 0x8200 // A <- _> - - - - +#define Key_A_MinG 0x4A00 // A <-> Grey - G E - +#define Key_A_Dot 0x3400 // A <. >> - - E - +#define Key_A_Sls 0x3500 // A - - E - +#define Key_A_Smi 0x2700 // A <; :> - - E - +#define Key_A_Equ 0x8300 // A <= +> - - - - +#define Key_A_BS 0x0E00 // A - - E - +#define Key_A_5Num 0x4C00 // A N - E - +#define Key_A_Del 0xA300 // A - - E - +#define Key_A_DelG 0xA300 // A Grey - G E - +#define Key_A_Dwn 0xA000 // A - - E - +#define Key_A_DwnG 0xA000 // A Grey - G E - +#define Key_A_End 0x9F00 // A - - E - +#define Key_A_EndG 0x9F00 // A Grey - G E - +#define Key_A_EntG 0xA600 // A - - E - +#define Key_A_Esc 0x0100 // A - - E - +#define Key_A_F1 0x6800 // A - - - - +#define Key_A_F2 0x6900 // A - - - - +#define Key_A_F3 0x6A00 // A - - - - +#define Key_A_F4 0x6B00 // A - - - - +#define Key_A_F5 0x6C00 // A - - - - +#define Key_A_F6 0x6D00 // A - - - - +#define Key_A_F7 0x6E00 // A - - - - +#define Key_A_F8 0x6F00 // A - - - - +#define Key_A_F9 0x7000 // A - - - - +#define Key_A_F10 0x7100 // A - - - - +#define Key_A_F11 0x8B00 // A - - E - +#define Key_A_F12 0x8C00 // A - - E - +#define Key_A_Home 0x9700 // A - - E - +#define Key_A_HomeG 0x9700 // A Grey - G E - +#define Key_A_Ins 0xA200 // A - - E - +#define Key_A_InsG 0xA200 // A Grey - G E - +#define Key_A_Lft 0x9B00 // A - - E - +#define Key_A_LftG 0x9B00 // A Grey - G E - +#define Key_A_PgDn 0xA100 // A - - E - +#define Key_A_PgDnG 0xA100 // A Grey - G E - +#define Key_A_PgUp 0x9900 // A - - E - +#define Key_A_PgUpG 0x9900 // A Grey - G E - +#define Key_A_Rgt 0x9D00 // A - - E - +#define Key_A_Up 0x9800 // A - - E - +#define Key_A_UpG 0x9800 // A Grey - G E - +#define Key_A_Lbr 0x1A00 // A <[ {> - - E - +#define Key_A_Bsl 0x2B00 // A <\ |> - - E - +#define Key_A_Rbr 0x1B00 // A <] }> - - E - +#define Key_A_Grv 0x2900 // A <` ~> - - E - + +// ------------------------------------------------------------------ + //- Mouse KeyCode Returns ------- +#define Key_M_Scn 0xD4 // Scan-code +#define Key_M_Clk 0x30 // Single-click keycodes +#define Key_M_ClkL 0xD431 // Left-button +#define Key_M_ClkR 0xD432 // Right-button +#define Key_M_ClkM 0xD434 // Middle-button + +#define Key_M_DClk 0x20 // Double-click keycodes +#define Key_M_DClkL 0xD421 // Left-button +#define Key_M_DClkR 0xD422 // Right-button +#define Key_M_DClkM 0xD424 // Middle-button + +#define Key_M_Prs 0x30 // Single-press keycodes +#define Key_M_PrsL 0xD431 // Left-button +#define Key_M_PrsR 0xD432 // Right-button +#define Key_M_PrsM 0xD434 // Middle-button +#define Key_M_Rel 0x40 // Single-release keycodes +#define Key_M_RelL 0xD441 // Left-button +#define Key_M_RelR 0xD442 // Right-button +#define Key_M_RelM 0xD444 // Middle-button + +#define Key_M_Mov 0x50 // Mouse motion keycodes +#define Key_M_Up 0xD450 // Motion [Up] +#define Key_M_Dwn 0xD451 // Motion [Down] +#define Key_M_Lft 0xD452 // Motion [Left] +#define Key_M_Rgt 0xD453 // Motion [Right] + + +// ------------------------------------------------------------------ +// Goldware internal keycodes + +#define Key_Tick 0x0200 // Timer tick +#define Key_Auto 0xFD00 // Auto macro +#define Key_Macro 0xFE00 // Macro + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdgetm.cpp b/goldlib/gall/gkbdgetm.cpp new file mode 100644 index 0000000..75ddd80 --- /dev/null +++ b/goldlib/gall/gkbdgetm.cpp @@ -0,0 +1,328 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Keyboard functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#ifdef GOLD_MOUSE +#include +#endif + + +// ------------------------------------------------------------------ +// Event sources + +const int GEVT_KEYBOARD = 0; +const int GEVT_BUFFER = 1; +const int GEVT_MOUSE = 2; +const int GEVT_TICK = 3; + + +// ------------------------------------------------------------------ + +void gkbdtickpressreset() { + + gkbd.tickpress = gclock(); +} + + +// ------------------------------------------------------------------ + +void gkbdtickvaluereset() { + + gkbd.tickvalue = gclock(); +} + + +// ------------------------------------------------------------------ + +gkey kbmhit() { + + gkey k; + + // Check for keypress in internal buffer or keyboard + if(gkbd.kbuf) { + gkbd.source = GEVT_BUFFER; + k = gkbd.kbuf->xch; + } + else { + gkbd.source = GEVT_KEYBOARD; + k = kbxhit(); + } + + return k; +} + + +// ------------------------------------------------------------------ + +static void kbd_call_func(VfvCP func) { + + int row, col; + bool hidden = vcurhidden(); + vposget(&row,&col); + _menu_t* menu = gwin.cmenu; + (*func)(); + gwin.cmenu = menu; + vposset(row,col); + if(hidden) + vcurhide(); + else + vcurshow(); +} + + +// ------------------------------------------------------------------ + +static _item_t* find_hotkey(_menu_t* wmenu, gkey xch) { + + _item_t* witem; + _item_t* item; + + // do while more items in this menu + for(witem=wmenu->item; witem!=NULL; witem=witem->prev) { + + // if hot key matches keypress, return its item address + if(witem->hotkey==xch and (!(witem->fmask&M_NOSEL)) and witem->select!=NULL) + return witem; + + // if current item has a child menu, process it + if(witem->child!=NULL) { + item = find_hotkey((_menu_t*)witem->child, xch); + if(item!=NULL) + return item; + } + } + + // return address of item found + return witem; +} + + +// ------------------------------------------------------------------ + +static void makeextkey(gkey xshift, gkey& xkey) { + + switch(xkey) { + case Key_Home: + case Key_C_Home: + if(xshift & ALT) + xkey = Key_A_HomeG; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_End: + case Key_C_End: + if(xshift & ALT) + xkey = Key_A_EndG; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_Up: + if(xshift & ALT) + xkey = Key_A_UpG; + else if(xshift & GCTRL) + xkey = Key_C_Up; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_Dwn: + if(xshift & ALT) + xkey = Key_A_DwnG; + else if(xshift & GCTRL) + xkey = Key_C_Dwn; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_Lft: + if(xshift & ALT) + xkey = Key_A_LftG; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_Rgt: + if(xshift & ALT) + xkey = Key_A_RgtG; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_PgUp: + if(xshift & ALT) + xkey = Key_A_PgUpG; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_PgDn: + if(xshift & ALT) + xkey = Key_A_PgDnG; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_Ins: + if(xshift & ALT) + xkey = Key_A_InsG; + else if(xshift & GCTRL) + xkey = Key_C_Ins; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + + case Key_Del: + if(xshift & ALT) + xkey = Key_A_DelG; + else if(xshift & GCTRL) + xkey = Key_C_Del; + if(xshift & (LSHIFT | RSHIFT)) + KCodScn(xkey) |= 0x80; + break; + } +} + + +// ------------------------------------------------------------------ + +extern int blanked; + +gkey getxch(int __tick) { + + gkey k; + + while(1) { + + // Keyboard polling loop + if(gkbd.polling) { + while(not kbmhit()) { + Clock thistick = gclock(); + long tickdiff = thistick - gkbd.tickvalue; + if(tickdiff < 0) { + gkbd.tickvalue = thistick; + tickdiff = gkbd.tickinterval + 1; + } + if(tickdiff > gkbd.tickinterval) { + gkbd.tickvalue = thistick; + if(gkbd.tickfunc) { + gkbd.inidle = true; + (*gkbd.tickfunc)(); + gkbd.inidle = false; + } + if(__tick) + kbput(Key_Tick); + } + if(gmtsk.detected) + gmtsk.timeslice(); + } + } + + // Get key from internal buffer or keyboard + if(gkbd.kbuf) { + gkbd.source = GEVT_BUFFER; + k = gkbd.kbuf->xch; + KBuf* _kbuf = gkbd.kbuf->next; + throw_free(gkbd.kbuf); + gkbd.kbuf = _kbuf; + if(gkbd.kbuf) + gkbd.kbuf->prev = NULL; + } + else { + gkbd.source = GEVT_KEYBOARD; + k = kbxget(); + gkey s = kbxget(2); // Read shift status + if(not gkbd.extkbd) { + if(s & (LSHIFT|RSHIFT|GCTRL|ALT)) + makeextkey(s,k); + } + } + + // Note time of keypress unless it's a tick + if(k != Key_Tick) + gkbdtickpressreset(); + + // Search through onkey linked list for a + // matching defined onkey. If one is found, + // then save the current environment, call the + // onkey's function, and restore the environment. + + if(not blanked) { + KBnd* _onkey = gkbd.onkey; + while(_onkey) { + if(_onkey->keycode == k) { + gkbd.curronkey = _onkey; + kbd_call_func(_onkey->func); + #ifdef GOLD_MOUSE + if(gkbd.inmenu and gmou.FreeCursor()) + return 0; + #endif + break; + } + _onkey = _onkey->prev; + } + if(_onkey) { + if(not _onkey->pass or (_onkey->pass >= 0xFE00)) + k = 0; + else + k = _onkey->pass; + } + else { + + // Search for a menu hot key. If one is found, + // then save the current environment, call the + // hotkey's function, and restore the environment. + + if(gwin.menu) { + _item_t* item = find_hotkey(gwin.menu,k); + if(item) { + kbd_call_func(item->select); + #ifdef GOLD_MOUSE + if(gkbd.inmenu and gmou.FreeCursor()) + return 0; + #endif + k = 0; + } + } + } + } + + // If we still have a keycode, exit the loop + if(k) + break; + } + + // Return keycode + return k; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdunix.cpp b/goldlib/gall/gkbdunix.cpp new file mode 100644 index 0000000..1bba588 --- /dev/null +++ b/goldlib/gall/gkbdunix.cpp @@ -0,0 +1,640 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Unix keyboard functions. Based on SLang source code. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +int gkbd_stdin = -1; + + +// ------------------------------------------------------------------ + +static termios gkbd_oldtty; + + +// ------------------------------------------------------------------ + +static bool gkbd_tty_inited = false; +static bool gkbd_tty_open = false; + + +// ------------------------------------------------------------------ + +int gkbd_tty_init() { + + gsig_block_signals(); + + gkbd_tty_open = false; + + if((gkbd_stdin == -1) or (isatty(gkbd_stdin) != 1)) { + + gkbd_stdin = open("/dev/tty", O_RDWR); + + if(gkbd_stdin >= 0) + gkbd_tty_open = true; + + if(not gkbd_tty_open) { + gkbd_stdin = fileno(stderr); + if(isatty(gkbd_stdin) != 1) { + gkbd_stdin = fileno (stdin); + if(isatty(gkbd_stdin) != 1) + return -1; + } + } + } + + while(GET_TERMIOS(gkbd_stdin, &gkbd_oldtty) == -1) { + if(errno != EINTR) { + gsig_unblock_signals(); + return -1; + } + } + + termios newtty; + + while(GET_TERMIOS(gkbd_stdin, &newtty) == -1) { + if(errno != EINTR) { + gsig_unblock_signals(); + return -1; + } + } + + newtty.c_oflag &= ~OPOST; + + newtty.c_lflag = ISIG | NOFLSH; + + newtty.c_iflag &= ~(ECHO | INLCR | ICRNL | IXON); + + newtty.c_cc[VMIN] = 1; + newtty.c_cc[VEOF] = 1; + newtty.c_cc[VTIME] = 0; + newtty.c_cc[VINTR] = NULL_VALUE; + newtty.c_cc[VQUIT] = NULL_VALUE; + newtty.c_cc[VSUSP] = NULL_VALUE; + + while(SET_TERMIOS(gkbd_stdin, &newtty) == -1) { + if(errno != EINTR) { + gsig_unblock_signals(); + return -1; + } + } + + gkbd_tty_inited = true; + + gsig_unblock_signals(); + + return 0; +} + + +// ------------------------------------------------------------------ + +void gkbd_tty_reset() { + + gsig_block_signals(); + + if(not gkbd_tty_inited) { + gsig_unblock_signals(); + return; + } + + while((SET_TERMIOS(gkbd_stdin, &gkbd_oldtty) == -1) and (errno == EINTR)) + ; + + if(gkbd_tty_open) { + while((close(gkbd_stdin) == -1) and (errno == EINTR)) + ; + gkbd_tty_open = false; + gkbd_stdin = -1; + } + + gkbd_tty_inited = false; + + gsig_unblock_signals(); +} + + +// ------------------------------------------------------------------ + +int gkbd_sys_input_pending(int tsecs) { + + static fd_set read_fd_set; + struct timeval wait; + long usecs, secs; + + if(tsecs >= 0) { + secs = tsecs / 10; + usecs = (tsecs % 10) * 100000; + } + else { + tsecs = -tsecs; + secs = tsecs / 1000; + usecs = (tsecs % 1000) * 1000; + } + + wait.tv_sec = secs; + wait.tv_usec = usecs; + + FD_ZERO(&read_fd_set); + FD_SET(gkbd_stdin, &read_fd_set); + + return select(gkbd_stdin+1, &read_fd_set, NULL, NULL, &wait); +} + + +// ------------------------------------------------------------------ + +uint gkbd_sys_getkey() { + + while(1) { + int ret = gkbd_sys_input_pending(100); + if(ret == 0) + continue; + if(ret != -1) + break; + if(errno == EINTR) + continue; + break; + } + + char c; + + while(read(gkbd_stdin, &c, 1) == -1) { + if(errno == EINTR) + continue; + if(errno == EAGAIN) { + sleep(1); + continue; + } + #ifndef __DJGPP__ + if(errno == EWOULDBLOCK) { + sleep(1); + continue; + } + #endif + return (uint)-1; + } + + return (uint)c; +} + + +// ------------------------------------------------------------------ + +uint gkbd_input_buffer_len = 0; +char gkbd_input_buffer[GKBD_MAX_INPUT_BUFFER_LEN]; + + +// ------------------------------------------------------------------ + +uint gkbd_getkey() { + + uint imax; + uint ch; + + if(gkbd_input_buffer_len) { + ch = (uint)*gkbd_input_buffer; + gkbd_input_buffer_len--; + imax = gkbd_input_buffer_len; + memcpy(gkbd_input_buffer, gkbd_input_buffer+1, imax); + } + else { + ch = gkbd_sys_getkey(); + } + + return ch; +} + + +// ------------------------------------------------------------------ + +void gkbd_ungetkey_string(char *s, uint n) { + + char* bmax; + char* b1; + char* b; + + if(gkbd_input_buffer_len + n + 3 > GKBD_MAX_INPUT_BUFFER_LEN) + return; + + b = gkbd_input_buffer; + bmax = (b - 1) + gkbd_input_buffer_len; + b1 = bmax + n; + while(bmax >= b) + *b1-- = *bmax--; + bmax = b + n; + while(b < bmax) + *b++ = *s++; + gkbd_input_buffer_len += n; +} + + +// ------------------------------------------------------------------ + +int gkbd_input_pending(int tsecs) { + + if(gkbd_input_buffer_len) + return gkbd_input_buffer_len; + + int n = gkbd_sys_input_pending(tsecs); + if(n <= 0) + return 0; + + char c = (char)gkbd_getkey(); + gkbd_ungetkey_string(&c, 1); + + return n; +} + + +// ------------------------------------------------------------------ + +void gkbd_flush_input() { + + gkbd_input_buffer_len = 0; + while(gkbd_sys_input_pending(0) > 0) + gkbd_sys_getkey(); +} + + +// ------------------------------------------------------------------ + +struct gkbd_key_type { + + char str[7]; + bool active; + uint keysym; + gkbd_key_type* next; +}; + + +// ------------------------------------------------------------------ + +#define UPPER_CASE_KEY(x) (((x) >= 'a') and ((x) <= 'z') ? (x) - 32 : (x)) +#define LOWER_CASE_KEY(x) (((x) >= 'A') and ((x) <= 'Z') ? (x) + 32 : (x)) + + +// ------------------------------------------------------------------ + +gkbd_key_type* gkbd_keymap = NULL; + + +// ------------------------------------------------------------------ + +void gkbd_keymap_init() { + + gkbd_keymap = (gkbd_key_type*)calloc(256, sizeof(gkbd_key_type)); +} + + +// ------------------------------------------------------------------ + +void gkbd_keymap_reset() { + + if(gkbd_keymap) { + for(int n=0; n<256; n++) { + gkbd_key_type* next = gkbd_keymap[n].next; + while(next) { + gkbd_key_type* current = next; + next = current->next; + free(current); + } + } + free(gkbd_keymap); + gkbd_keymap = NULL; + } +} + + +// ------------------------------------------------------------------ + +static gkbd_key_type* malloc_key(char *str) { + + gkbd_key_type* key = (gkbd_key_type*)malloc(sizeof(gkbd_key_type)); + + memset(key, 0, sizeof(gkbd_key_type)); + memcpy(key->str, str, *str); + + return key; +} + + +// ------------------------------------------------------------------ +// Convert things like "^A" to 1 etc... The 0th char is the strlen +// INCLUDING the length character itself. + +static char* gkbd_process_keystring(char* s) { + + static char str[32]; + char ch; + + int i = 1; + while(*s != 0) { + ch = *s++; + if(ch == '^') { + ch = *s++; + if(ch == 0) { + if(i < 32) + str[i++] = '^'; + break; + } + ch = UPPER_CASE_KEY(ch); + if(ch == '?') + ch = 127; + else + ch = ch - 'A' + 1; + } + + if(i >= 32) + break; + str[i++] = ch; + } + str[0] = i; + + return str; +} + + +// ------------------------------------------------------------------ + +static int key_string_compare(char* a, char* b, uint len) { + + char* amax = a + len; + + while(a < amax) { + + int cha = *a++; + int chb = *b++; + + if(cha == chb) + continue; + + int cha_up = UPPER_CASE_KEY(cha); + int chb_up = UPPER_CASE_KEY(chb); + + if(cha_up == chb_up) { + // Use case-sensitive result. + return cha - chb; + } + // Use case-insensitive result. + return cha_up - chb_up; + } + + return 0; +} + + +// ------------------------------------------------------------------ +// This function also performs an insertion in an ordered way. + +static int find_the_key(char* s, gkbd_key_type** keyp) { + + *keyp = NULL; + + char* str = gkbd_process_keystring(s); + + uint str_len = str[0]; + if(str_len == 1) + return 0; + + char ch = str[1]; + gkbd_key_type* key = gkbd_keymap + ch; + + if(str_len == 2) { + if(key->next) + return -2; + + key->str[0] = str_len; + key->str[1] = ch; + + *keyp = key; + return 0; + } + + // insert the key definition + while(1) { + + gkbd_key_type* last = key; + key = key->next; + + if(key and key->str) { + + uint key_len = key->str[0]; + uint len = key_len; + if(len > str_len) + len = str_len; + + int cmp = key_string_compare(str+1, key->str+1, len-1); + + if(cmp > 0) + continue; + + if(cmp == 0) { + if(key_len != str_len) + return -2; + + *keyp = key; + + return 0; + } + // Drop to cmp < 0 case + } + + gkbd_key_type* neew = malloc_key(str); + + neew->next = key; + last->next = neew; + + *keyp = neew; + + return 0; + } +} + + +// ------------------------------------------------------------------ + +int gkbd_define_keysym(char* s, uint keysym) { + + gkbd_key_type* key; + + int ret = find_the_key(s, &key); + + if((ret != 0) or (key == NULL)) + return ret; + + key->active = true; + key->keysym = keysym; + + return 0; +} + + +// ------------------------------------------------------------------ + +uint gkbd_last_key_char = 0; + +static gkbd_key_type* gkbd_do_key() { + + gkbd_last_key_char = gkbd_getkey(); + + if(gkbd_last_key_char == (uint)-1) + return NULL; + + char input_ch = (char)gkbd_last_key_char; + + gkbd_key_type* key = gkbd_keymap + input_ch; + + // if the next one is null, then we know this MAY be it. + while(key->next == NULL) { + + if(key->active) + return key; + + // Try its opposite case counterpart + char chlow = LOWER_CASE_KEY(input_ch); + if(input_ch == chlow) + input_ch = UPPER_CASE_KEY(input_ch); + + key = gkbd_keymap + input_ch; + if(not key->active) + return NULL; + } + + if(gkbd_input_pending(1) == 0) + if(key->active) + return key; + + // It appears to be a prefix character in a key sequence. + + uint len = 1; // already read one character + key = key->next; // Now we are in the key list + gkbd_key_type* kmax = NULL; // set to end of list + gkbd_key_type* next; + + while(1) { + + gkbd_last_key_char = gkbd_getkey(); + + len++; + + if(gkbd_last_key_char == (uint)-1) + break; + + input_ch = (char)gkbd_last_key_char; + + char key_ch = 0; + char chup = UPPER_CASE_KEY(input_ch); + + while(key != kmax) { + if(key->str[0] > len) { + key_ch = key->str[len]; + if(chup == UPPER_CASE_KEY(key_ch)) + break; + } + key = key->next; + } + + if(key == kmax) + break; + + // If the input character is lowercase, check to see if there is + // a lowercase match. If so, set key to it. Note: the + // algorithm assumes the sorting performed by key_string_compare. + + if(input_ch != key_ch) { + next = key->next; + while(next != kmax) { + if(next->str[0] > len) { + char next_ch = next->str[len]; + if(next_ch == input_ch) { + key = next; + break; + } + if(next_ch != chup) + break; + } + next = next->next; + } + } + + // Ok, we found the first position of a possible match. If it + // is exact, we are done. + + if(key->str[0] == len + 1) + return key; + + // Apparently, there are some ambiguities. Read next key to + // resolve the ambiguity. Adjust kmax to encompass ambiguities. + + next = key->next; + while(next != kmax) { + if(next->str[0] > len) { + char key_ch = next->str[len]; + if(chup != UPPER_CASE_KEY(key_ch)) + break; + } + next = next->next; + } + kmax = next; + } + + return NULL; +} + + +// ------------------------------------------------------------------ + +uint gkbd_getmappedkey() { + + gkbd_key_type* key = gkbd_do_key(); + if((key == NULL) or (not key->active)) { + gkbd_flush_input(); + return (uint)-1; + } + + return key->keysym; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdunix.h b/goldlib/gall/gkbdunix.h new file mode 100644 index 0000000..957093b --- /dev/null +++ b/goldlib/gall/gkbdunix.h @@ -0,0 +1,72 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Unix keyboard functions. Based on SLang source code. +// ------------------------------------------------------------------ + +#ifndef __gkbdunix_h +#define __gkbdunix_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +const int GKBD_MAX_INPUT_BUFFER_LEN = 1024; + + +// ------------------------------------------------------------------ + +extern int gkbd_stdin; + + +// ------------------------------------------------------------------ + +int gkbd_tty_init(); +void gkbd_tty_reset(); +int gkbd_sys_input_pending(int tsecs=0); +uint gkbd_sys_getkey(); + + +// ------------------------------------------------------------------ + +extern uint gkbd_last_key_char; + +uint gkbd_getkey(); +void gkbd_ungetkey_string(char *s, uint n); +int gkbd_input_pending(int tsecs=0); +void gkbd_flush_input(); +void gkbd_keymap_init(); +void gkbd_keymap_reset(); +int gkbd_define_keysym(char* s, uint keysym); +uint gkbd_getmappedkey(); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gkbdwait.cpp b/goldlib/gall/gkbdwait.cpp new file mode 100644 index 0000000..5132081 --- /dev/null +++ b/goldlib/gall/gkbdwait.cpp @@ -0,0 +1,67 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Keyboard functions +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Halts execution until a key is pressed + +gkey waitkey() { + + clearkeys(); + return getxch(); +} + + +// ------------------------------------------------------------------ +// Halts execution until a key is pressed or the specified time +// period has expired + +gkey waitkeyt(int duration) { + + clearkeys(); + Clock stop = gclock() + duration; + Clock sliced_time = gclock(); + while(1) { + if(kbmhit()) + return getxch(); + if(gclock() >= stop) + return 0; + if(gclock() - sliced_time >= 10) { + if(gkbd.tickfunc) + (*gkbd.tickfunc)(); + sliced_time = gclock(); + } + gmtsk.timeslice(); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/glog.cpp b/goldlib/gall/glog.cpp new file mode 100644 index 0000000..59daac9 --- /dev/null +++ b/goldlib/gall/glog.cpp @@ -0,0 +1,196 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Log file class. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +struct tm* glog::time_now; +int glog::count = 0; +time_t glog::secs_now; +char glog::timebuf[20]; + + +// ------------------------------------------------------------------ + +glog::glog() { + + bufsize = 0; + logtype = GLOG_FD; + progname = NULL; + status = GOLD_NO_ERROR; + storelines = -1; +} + + +// ------------------------------------------------------------------ + +glog::~glog() { + + close(); +} + + +// ------------------------------------------------------------------ + +int glog::open(const char* filename, const char* name, const char* shortname, int type, uint bufsz, int shflag) { + + fp.fopen(filename, "at", shflag); + if(fp.status) { + status = fp.status; + return status; + } + + count++; + bufsize = bufsz; + fp.setvbuf(NULL, bufsize ? _IOFBF : _IONBF, bufsize); + + init(name, shortname, type); + + return status; +} + + +// ------------------------------------------------------------------ + +void glog::close() { + + fp.fclose(); + count--; +} + + +// ------------------------------------------------------------------ + +void glog::init(const char* name, const char* shortname, int type) { + + lineswritten = 0; + logtype = (type!=GLOG_NONE) ? type : logtype; + progname = name ? name : progname; + shortprogname = shortname ? shortname : (shortprogname ? shortprogname : progname); +} + + +// ------------------------------------------------------------------ + +void glog::printf(const char* format, ...) { + + va_list argptr; + char buf[256]; + char logbuf[256]; + + secs_now = time(NULL); + time_now = localtime(&secs_now); + + lineswritten++; + + if(lineswritten == 1) { + + switch(logtype) { + + case GLOG_FD: + sprintf(logbuf, "\n---------- %s, %s\n", strftimei(timebuf, 20, "%a %d %b %y", time_now), progname); + break; + + case GLOG_MAX: + sprintf(logbuf, "\n+ %s %4.4s Begin, %s\n", strftimei(timebuf, 20, "%d %b %H:%M:%S", time_now), shortprogname, progname); + break; + + case GLOG_BINK: + sprintf(logbuf, "\n> %s %4.4s %s\n", strftimei(timebuf, 20, "%d-%b %H:%M:%S", time_now), shortprogname, progname); + break; + + case GLOG_QBBS: + sprintf(logbuf, "\n%s **************************************************\n%s %s\n", strftimei(timebuf, 20, "%d-%b-%y %H:%M", time_now), timebuf, progname); + break; + + case GLOG_DB: + sprintf(logbuf, "\n%s %s\n", strftimei(timebuf, 20, "%m/%d/%y %H:%M", time_now), progname); + break; + } + + if(fp.isopen()) + fp.printf("%s", logbuf); + } + + *buf = NUL; + va_start(argptr, format); + vsprintf(buf, format, argptr); + va_end(argptr); + + if(*buf == '!') + store(); + + switch(logtype) { + + case GLOG_FD: + sprintf(logbuf, "%c %s %s", *buf, strftimei(timebuf, 10, "%H:%M:%S", time_now), buf+2); + break; + + case GLOG_MAX: + sprintf(logbuf, "%c %s %4.4s %s", *buf, strftimei(timebuf, 20, "%d %b %H:%M:%S", time_now), shortprogname, buf+2); + break; + + case GLOG_BINK: + sprintf(logbuf, "%c %s %4.4s %s", *buf, strftimei(timebuf, 20, "%d-%b %H:%M:%S", time_now), shortprogname, buf+2); + break; + + case GLOG_QBBS: + sprintf(logbuf, "%s %s", strftimei(timebuf, 20, "%d-%b-%y %H:%M", time_now), buf+2); + break; + + case GLOG_DB: + sprintf(logbuf, "%s %s", strftimei(timebuf, 20, "%m/%d/%y %H:%M", time_now), buf+2); + break; + } + if(fp.isopen()) { + fp.printf("%s\n", logbuf); + fp.fflush(); + } + if(storelines != -1) { + if(storelines < GLOG_STORELINES) + strxcpy(storeline[storelines], logbuf, 79); + storelines++; + } +} + + +// ------------------------------------------------------------------ + +void glog::store() { + + if(storelines == -1) + storelines = 0; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/glog.h b/goldlib/gall/glog.h new file mode 100644 index 0000000..f4feed2 --- /dev/null +++ b/goldlib/gall/glog.h @@ -0,0 +1,99 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Log file class. +// ------------------------------------------------------------------ + +#ifndef __glog_h +#define __glog_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Log types + +const int GLOG_NONE = -1; +const int GLOG_FD = 0; +const int GLOG_MAX = 1; +const int GLOG_BINK = 2; +const int GLOG_QBBS = 3; +const int GLOG_DB = 4; + + +// ------------------------------------------------------------------ + +const int GLOG_STORELINES = 10; + + +// ------------------------------------------------------------------ +// Logfile base class + +class glog { + +private: + + gfile fp; + + static int count; + static struct tm* time_now; + static time_t secs_now; + static char timebuf[20]; + +protected: + + uint bufsize; + int logtype; + const char* progname; + const char* shortprogname; + int lineswritten; + +public: + + int status; + + char storeline[GLOG_STORELINES][79]; + int storelines; + + glog(); + ~glog(); + + int open(const char* filename, const char* name, const char* shortname=NULL, int type=GLOG_NONE, uint bufsz=0, int shflag=SH_DENYWR); + void close(); + + void init(const char* name=NULL, const char* shortname=NULL, int type=GLOG_NONE); + void printf(const char* format, ...) __attribute__ ((format (printf, 2, 3))); + + void store(); +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/glzh.cpp b/goldlib/gall/glzh.cpp new file mode 100644 index 0000000..28a03d5 --- /dev/null +++ b/goldlib/gall/glzh.cpp @@ -0,0 +1,651 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Digital Dynamics conversion of 1988 LZH (LHarc) encoding functions +// Based on Japanese version 29-NOV-1988 +// LZSS coded by Haruhiko Okumura +// Adaptive Huffman Coding coded by Haruyasu Yoshizaki +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// LZSS Parameters + +#define LZH_N 4096 // Size of string buffer +#define LZH_F 60 // Size of look-ahead buffer +#define LZH_THRESHOLD 2 +#define LZH_NIL LZH_N // End of tree's node + +static char lzh_text_buf[LZH_N + LZH_F - 1]; +static short int lzh_match_position, lzh_match_length, lzh_lson[LZH_N + 1], lzh_rson[LZH_N + 257], lzh_dad[LZH_N + 1]; + + +// ------------------------------------------------------------------ +// Initializing tree + +static void glzh_init_tree(void) { + short int i; + + for(i = LZH_N + 1; i <= LZH_N + 256; i++) + lzh_rson[i] = LZH_NIL; // root + for(i = 0; i < LZH_N; i++) + lzh_dad[i] = LZH_NIL; // node +} + + +// ------------------------------------------------------------------ +// Inserting node to the tree +// Only used during encoding + +static void glzh_insert_node(short int r) { + short int i, p, cmp; + char *key; + unsigned c; + + cmp = 1; + key = lzh_text_buf+r; + p = LZH_N + 1 + key[0]; + lzh_rson[r] = lzh_lson[r] = LZH_NIL; + lzh_match_length = 0; + for(;;) { + if(cmp >= 0) { + if(lzh_rson[p] != LZH_NIL) + p = lzh_rson[p]; + else { + lzh_rson[p] = r; + lzh_dad[r] = p; + return; + } + } else { + if(lzh_lson[p] != LZH_NIL) + p = lzh_lson[p]; + else { + lzh_lson[p] = r; + lzh_dad[r] = p; + return; + } + } + for(i = 1; i < LZH_F; i++) + if((cmp = key[i] - lzh_text_buf[p + i]) != 0) + break; + if(i > LZH_THRESHOLD) { + if(i > lzh_match_length) { + lzh_match_position = ((r - p) & (LZH_N - 1)) - 1; + if((lzh_match_length = i) >= LZH_F) + break; + } + if(i == lzh_match_length) { + if((c = ((r - p) & (LZH_N - 1)) - 1) < lzh_match_position) { + lzh_match_position = c; + } + } + } + } + lzh_dad[r] = lzh_dad[p]; + lzh_lson[r] = lzh_lson[p]; + lzh_rson[r] = lzh_rson[p]; + lzh_dad[lzh_lson[p]] = r; + lzh_dad[lzh_rson[p]] = r; + if(lzh_rson[lzh_dad[p]] == p) + lzh_rson[lzh_dad[p]] = r; + else + lzh_lson[lzh_dad[p]] = r; + lzh_dad[p] = LZH_NIL; // remove p +} + + +// ------------------------------------------------------------------ +// Deleting node from the tree + +static void glzh_delete_node(short int p) { + short int q; + + if(lzh_dad[p] == LZH_NIL) + return; // unregistered + if(lzh_rson[p] == LZH_NIL) + q = lzh_lson[p]; + else + if(lzh_lson[p] == LZH_NIL) + q = lzh_rson[p]; + else { + q = lzh_lson[p]; + if(lzh_rson[q] != LZH_NIL) { + do { + q = lzh_rson[q]; + } while (lzh_rson[q] != LZH_NIL); + lzh_rson[lzh_dad[q]] = lzh_lson[q]; + lzh_dad[lzh_lson[q]] = lzh_dad[q]; + lzh_lson[q] = lzh_lson[p]; + lzh_dad[lzh_lson[p]] = q; + } + lzh_rson[q] = lzh_rson[p]; + lzh_dad[lzh_rson[p]] = q; + } + lzh_dad[q] = lzh_dad[p]; + if(lzh_rson[lzh_dad[p]] == p) + lzh_rson[lzh_dad[p]] = q; + else + lzh_lson[lzh_dad[p]] = q; + lzh_dad[p] = LZH_NIL; +} + + +// ------------------------------------------------------------------ +// Huffman coding parameters + +// character code (= 0..LZH_N_CHAR-1) +#define LZH_N_CHAR (256 - LZH_THRESHOLD + LZH_F) +// Size of table +#define LZH_T (LZH_N_CHAR * 2 - 1) +// root position +#define LZH_R (LZH_T - 1) +// update when cumulative frequency reaches to this value +#define MAX_FREQ 0x8000 + +// ------------------------------------------------------------------ +// Tables for encoding/decoding upper 6 bits of sliding dictionary pointer + +// ------------------------------------------------------------------ +// encoder table + +static char lzh_p_len[64] = { + 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 +}; + +static char lzh_p_code[64] = { + 0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68, + 0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C, + 0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC, + 0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, + 0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE, + 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF +}; + + +// ------------------------------------------------------------------ +// decoder table + +static char lzh_d_code[256] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F, + 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, + 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, + 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, + 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17, + 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B, + 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F, + 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, + 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, + 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B, + 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, +}; + +static char lzh_d_len[256] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, +}; + + +// ------------------------------------------------------------------ + +static unsigned short lzh_freq[LZH_T + 1]; // cumulative freq table +static short int lzh_prnt[LZH_T + LZH_N_CHAR]; +static short int lzh_son[LZH_T + 1]; + +static unsigned short lzh_getbuf = 0; +static char lzh_getlen = 0; + + +// ------------------------------------------------------------------ +// get one bit + +static int glzh_getbit(char *inbuf, long *incnt, long inlen) { + short int i; + + while(lzh_getlen <= 8) { + if((*incnt)>=inlen) + i=0; + else + i=inbuf[(*incnt)++]; + lzh_getbuf |= i << (8 - lzh_getlen); + lzh_getlen += 8; + } + i = lzh_getbuf; + lzh_getbuf <<= 1; + lzh_getlen--; + return (i < 0); +} + + +// ------------------------------------------------------------------ +// get a byte + +static short int glzh_getbyte(char *inbuf, long *incnt, long inlen) { + unsigned short i; + + while(lzh_getlen <= 8) { + if((*incnt)>=inlen) + i=0; + else + i=inbuf[(*incnt)++]; + lzh_getbuf |= i << (8 - lzh_getlen); + lzh_getlen += 8; + } + i = lzh_getbuf; + lzh_getbuf <<= 8; + lzh_getlen -= 8; + return i >> 8; +} + + +// ------------------------------------------------------------------ + +static unsigned lzh_putbuf = 0; +static char lzh_putlen = 0; + + +// ------------------------------------------------------------------ +// output c bits + +static void glzh_putcode(short int l, unsigned short c, char *outbuf, long *outlen) { + + lzh_putbuf |= c >> lzh_putlen; + if((lzh_putlen += l) >= 8) { + outbuf[(*outlen)++]=(lzh_putbuf >> 8); + if((lzh_putlen -= 8) >= 8) { + outbuf[(*outlen)++]=lzh_putbuf; + lzh_putlen -= 8; + lzh_putbuf = c << (l - lzh_putlen); + } + else { + lzh_putbuf <<= 8; + } + } +} + + +// ------------------------------------------------------------------ +// initialize freq tree + +static void glzh_start_huff() { + short int i, j; + + lzh_getbuf = 0; + lzh_getlen = 0; + lzh_putbuf = 0; + lzh_putlen = 0; + + for(i = 0; i < LZH_N_CHAR; i++) { + lzh_freq[i] = 1; + lzh_son[i] = i + LZH_T; + lzh_prnt[i + LZH_T] = i; + } + i = 0; j = LZH_N_CHAR; + while(j <= LZH_R) { + lzh_freq[j] = lzh_freq[i] + lzh_freq[i + 1]; + lzh_son[j] = i; + lzh_prnt[i] = lzh_prnt[i + 1] = j; + i += 2; j++; + } + lzh_freq[LZH_T] = 0xffff; + lzh_prnt[LZH_R] = 0; +} + + +// ------------------------------------------------------------------ +// reconstruct freq tree + +static void glzh_reconst() { + short int i, j, k; + unsigned short f, l; + + // halven cumulative freq for leaf nodes + j = 0; + for(i = 0; i < LZH_T; i++) { + if(lzh_son[i] >= LZH_T) { + lzh_freq[j] = (lzh_freq[i] + 1) / 2; + lzh_son[j] = lzh_son[i]; + j++; + } + } + // make a tree : first, connect children nodes + for(i = 0, j = LZH_N_CHAR; j < LZH_T; i += 2, j++) { + k = i + 1; + f = lzh_freq[j] = lzh_freq[i] + lzh_freq[k]; + for(k = j - 1; f < lzh_freq[k]; k--); + k++; + l = (j - k) * 2; + + memmove(lzh_freq+k+1, lzh_freq+k, l); + lzh_freq[k] = f; + memmove(lzh_son+k+1, lzh_son+k, l); + lzh_son[k] = i; + } + // connect parent nodes + for(i = 0; i < LZH_T; i++) { + if((k = lzh_son[i]) >= LZH_T) + lzh_prnt[k] = i; + else + lzh_prnt[k] = lzh_prnt[k + 1] = i; + } +} + + +// ------------------------------------------------------------------ +// update freq tree + +static void glzh_update(short int c) +{ + short int i, j, k, l; + + if (lzh_freq[LZH_R] == MAX_FREQ) + glzh_reconst(); + c = lzh_prnt[c + LZH_T]; + do { + k = ++lzh_freq[c]; + + /* swap nodes to keep the tree freq-ordered */ + if(k > lzh_freq[l = c + 1]) { + while(k > lzh_freq[++l]); + l--; + lzh_freq[c] = lzh_freq[l]; + lzh_freq[l] = k; + + i = lzh_son[c]; + lzh_prnt[i] = l; + if(i < LZH_T) + lzh_prnt[i + 1] = l; + + j = lzh_son[l]; + lzh_son[l] = i; + + lzh_prnt[j] = c; + if(j < LZH_T) + lzh_prnt[j + 1] = c; + lzh_son[c] = j; + + c = l; + } + } while((c = lzh_prnt[c]) != 0); // do it until reaching the root +} + + +// ------------------------------------------------------------------ + +static unsigned short lzh_code, lzh_len; + + +// ------------------------------------------------------------------ + +static void glzh_encode_char(unsigned short c, char *outbuf, long *outlen) { + unsigned short i; + short int j, k; + + i = 0; + j = 0; + k = lzh_prnt[c + LZH_T]; + + // search connections from leaf node to the root + do { + i >>= 1; + // if node's address is odd, output 1 + // else output 0 + if(k & 1) + i += 0x8000; + j++; + } while ((k = lzh_prnt[k]) != LZH_R); + glzh_putcode(j, i, outbuf, outlen); + lzh_code = i; + lzh_len = j; + glzh_update(c); +} + + +// ------------------------------------------------------------------ + +static void glzh_encode_position(unsigned short c, char *outbuf, long *outlen) { + unsigned short i; + + // output upper 6 bits with encoding + i = c >> 6; + glzh_putcode(lzh_p_len[i], (unsigned)lzh_p_code[i] << 8, outbuf, outlen); + + // output lower 6 bits directly + glzh_putcode(6, (c & 0x3f) << 10, outbuf, outlen); +} + + +// ------------------------------------------------------------------ + +static void glzh_encode_end(char *outbuf, long *outlen) { + + if(lzh_putlen) + outbuf[(*outlen)++]=(lzh_putbuf >> 8); +} + + +// ------------------------------------------------------------------ + +static short int glzh_decode_char(char *inbuf, long *incnt, long inlen) { + unsigned short c; + + c = lzh_son[LZH_R]; + // start searching tree from the root to leaves. + // choose node #(lzh_son[]) if input bit == 0 + // else choose #(lzh_son[]+1) (input bit == 1) + while (c < LZH_T) { + c += glzh_getbit(inbuf,incnt,inlen); + c = lzh_son[c]; + } + c -= LZH_T; + glzh_update(c); + return c; +} + + +// ------------------------------------------------------------------ + +static short int glzh_decode_position(char *inbuf, long *incnt, long inlen) { + unsigned short i, j, c; + + // decode upper 6 bits from given table + i = glzh_getbyte(inbuf,incnt,inlen); + c = (unsigned)lzh_d_code[i] << 6; + j = lzh_d_len[i]; + // input lower 6 bits directly + j -= 2; + while(j--) + i = (i << 1) + glzh_getbit(inbuf,incnt,inlen); + return c | i & 0x3f; +} + + +// ------------------------------------------------------------------ +// Encoding/Compressing: returns length of outbuf + +long glzh_encode(char *inbuf, long inlen, char *outbuf) { + short int i, c, len, r, s, last_match_length; + long incnt,outlen; // textsize=0; + + incnt=0; + memcpy(outbuf,&inlen,sizeof(inlen)); + outlen=sizeof(inlen); + if(not inlen) { + return(outlen); + } + glzh_start_huff(); + glzh_init_tree(); + s = 0; + r = LZH_N - LZH_F; + for(i = s; i < r; i++) + lzh_text_buf[i] = ' '; + for(len = 0; len len) + lzh_match_length = len; + if(lzh_match_length <= LZH_THRESHOLD) { + lzh_match_length = 1; + glzh_encode_char(lzh_text_buf[r],outbuf,&outlen); + } else { + glzh_encode_char(255 - LZH_THRESHOLD + lzh_match_length, outbuf, &outlen); + glzh_encode_position(lzh_match_position, outbuf, &outlen); + } + last_match_length = lzh_match_length; + for(i = 0; i 0); + glzh_encode_end(outbuf, &outlen); + + return(outlen); +} + + +// ------------------------------------------------------------------ +// Decoding/Uncompressing: returns length of outbuf + +long glzh_decode(char *inbuf, long inlen, char *outbuf) { + short int i, j, k, r, c; + unsigned long int count; + long incnt,textsize; + + incnt=0; + memcpy(&textsize, inbuf, sizeof(textsize)); + incnt+=sizeof(textsize); + if(textsize == 0) { + return(textsize); + } + glzh_start_huff(); + for(i = 0; i < LZH_N - LZH_F; i++) + *(lzh_text_buf+i) = ' '; + r = LZH_N - LZH_F; + for(count = 0; count < textsize; ) { + c = glzh_decode_char(inbuf,&incnt,inlen); + if(c < 256) { + outbuf[count]=c; + *(lzh_text_buf+r) = c; + r++; + r &= (LZH_N - 1); + count++; + } + else { + i = (r - glzh_decode_position(inbuf,&incnt,inlen) - 1) & (LZH_N - 1); + j = c - 255 + LZH_THRESHOLD; + for (k = 0; k < j && count +#if defined(__MSDOS__) +#include +#endif + + +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) +#if defined(__WATCOMC__) + +inline short peek(unsigned segment, unsigned offset) { return *((short *)MK_FP(segment,offset)); } +inline char peekb(unsigned segment, unsigned offset) { return *((char *)MK_FP(segment,offset)); } +inline void poke(unsigned segment, unsigned offset, short value) { *((short *)MK_FP(segment,offset)) = value; } +inline void pokeb(unsigned segment, unsigned offset, char value) { *((char *)MK_FP(segment,offset)) = value; } + +#elif defined(__DJGPP__) + +#include +#include + +inline short peek (unsigned segment, unsigned offset) { return _farpeekw(_dos_ds, segment*16 + offset); } +inline char peekb(unsigned segment, unsigned offset) { return _farpeekb(_dos_ds, segment*16 + offset); } +inline void poke (unsigned segment, unsigned offset, short value) { _farpokew(_dos_ds, segment*16 + offset, value); } +inline void pokeb(unsigned segment, unsigned offset, char value) { _farpokeb(_dos_ds, segment*16 + offset, value); } + +#endif +#endif + + +// ------------------------------------------------------------------ + +#define HEX_DUMP1 1 +#define HEX_DUMP2 2 + +char* HexDump16(char* strbuf, const char* memptr, int limit, const char* fmt, int fmtno=0); +inline char* HexDump16(char* strbuf, const char* memptr, int limit, int fmtno) { return HexDump16(strbuf, memptr, limit, NULL, fmtno); } + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmemdbg.cpp b/goldlib/gall/gmemdbg.cpp new file mode 100644 index 0000000..fe1a2d0 --- /dev/null +++ b/goldlib/gall/gmemdbg.cpp @@ -0,0 +1,695 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Memory management routines with debugging features. +// Based on free code from SNIPPETS 9404 by Walter Bright. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Global vars + +int throw_alloc_extra = 0; + +#if defined(GTHROW_LOG) +glog* throw_log = NULL; +#define TLOG if(throw_log) throw_log +#endif + + +// ------------------------------------------------------------------ + + +#define gmem_strdup strdup +#define gmem_malloc malloc +#define gmem_calloc calloc +#define gmem_realloc realloc +#define gmem_free free + + +// ------------------------------------------------------------------ + +#if defined(GTHROW_DEBUG) + + +// ------------------------------------------------------------------ +// Various values + +const dword BEFOREVAL = 0x12345678L; +const dword AFTERVAL = 0x87654321L; + +const byte BADVAL = 0xFF; +const byte MALLOCVAL = 0xEE; + +const size_t BAD_SIZE = 0xFFFFFFFF; +const size_t MALLOC_SIZE = 0xEEEEEEEE; + + +// ------------------------------------------------------------------ +// Struct + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +struct Throw { + Throw* next; + Throw* prev; + const char* file; + int line; + int index; + size_t nbytes; + dword beforeval; + char data[1]; +}; + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + +struct ThrowIndex { + Throw* pointer; +}; + + +// ------------------------------------------------------------------ +// Internal vars + +int throw_inited = 0; +int throw_count; +ulong throw_allocations = 0; +Throw throw_alloclist; +int throw_max_count = 0; +Throw** throw_index = NULL; +int throw_index_size = 0; +int throw_index_free = 0; +int throw_last_free = -1; +ulong throw_index_cache_hits = 0; +int throw_overhead = sizeof(Throw) - 1; + +#define throw_index_init_size 1000 +#define throw_index_increment 100 + + +// ------------------------------------------------------------------ +// Inlined functions + +inline Throw* throw_ptrtodl(const void* ptr) { return (Throw*)((const char*)ptr-sizeof(Throw)+1); } +inline void* throw_dltoptr(Throw* dl) { return (void*)dl->data; } + + +// ------------------------------------------------------------------ + +int throw_index_find_free() { + + if(throw_last_free != -1) { + throw_index_cache_hits++; + return throw_last_free; + } + else if(throw_index_free) { + Throw** i = throw_index; + for(int n=0; n 0) and (diff < last_diff)) { + last_candidate = *i; + last_diff = diff; + } + } + return last_candidate; +} + + +// ------------------------------------------------------------------ + +Throw* throw_find_underrun(Throw* pointer) { + + Throw* last_candidate = NULL; + long last_diff = LONG_MAX; + Throw** i = throw_index; + for(int n=0; n 0) and (diff < last_diff)) { + last_candidate = *i; + last_diff = diff; + } + } + return last_candidate; +} + + +// ------------------------------------------------------------------ +// Dump pointer information to the log + +#if defined(GTHROW_LOG) + +void throw_printdl(Throw* dl) { + + char buf[100]; + + char* ptr = (char*)throw_dltoptr(dl); + TLOG->printf(": Ptr (%p,%u) at [%s,%u].", ptr, dl->nbytes, CleanFilename(dl->file), (uint)dl->line); + TLOG->printf(": %s", HexDump16(buf, ptr, dl->nbytes, HEX_DUMP2)); + +} + +#else + +inline void throw_printdl(Throw* dl) {} + +#endif + + +// ------------------------------------------------------------------ +// Debugging new + +void throw_new_debug(const void* __ptr, const char* __file, int __line) { + + if(__ptr == NULL) { + #if defined(GTHROW_LOG) + TLOG->errmemory(__file, __line); + TLOG->printf("! A memory allocation failed (out of memory)."); + TLOG->printf("+ Advice: Restart."); + #endif + MemoryErrorExit(); + } +} + + +// ------------------------------------------------------------------ +// Debugging strdup() + +char* throw_strdup_debug(const char* __str, const char* __file, int __line) { + + char* _ptr = (char*)(__str ? throw_calloc_debug(1, strlen(__str)+1, __file, __line) : NULL); + return _ptr ? strcpy(_ptr, __str) : _ptr; +} + + +// ------------------------------------------------------------------ +// Debugging malloc() + +void* throw_malloc_debug(size_t __size, const char* __file, int __line) { + + void* _ptr = throw_calloc_debug(1, __size, __file, __line); + if(_ptr) + memset(_ptr, MALLOCVAL, __size); + return _ptr; +} + + +// ------------------------------------------------------------------ +// Debugging calloc() + +void* throw_calloc_debug(size_t __items, size_t __size, const char* __file, int __line) { + + __size *= __items; + __size += throw_alloc_extra; + + if(__size == 0) { + #if defined(GTHROW_LOG) + TLOG->errmemory(__file, __line); + TLOG->printf("! Attempted to allocate zero bytes of memory."); + TLOG->printf("+ Advice: This is a bug. Please report to the Author."); + #endif + MemoryErrorExit(); + } + + size_t _siz = sizeof(Throw) + __size + sizeof(AFTERVAL) - 1; + + Throw* dl = (Throw*)calloc(_siz, 1); + if(dl == NULL) { + #if defined(GTHROW_LOG) + TLOG->errmemory(__file, __line); + TLOG->printf("! A memory allocation failed (out of memory)."); + TLOG->printf(": Needed %u (%Xh) bytes.", (uint)__size, (uint)__size); + if(__size == BAD_SIZE) { + TLOG->printf("+ Info: Value could be from free'd data."); + TLOG->printf("+ Info: This indicates a serious bug."); + TLOG->printf("+ Advice: Report to the Author immediately."); + } + else if(__size == MALLOC_SIZE) { + TLOG->printf("+ Info: Value could be from uninitialized data"); + TLOG->printf("+ Info: This indicates a serious bug."); + TLOG->printf("+ Advice: Report to the Author immediately."); + } + else { + TLOG->printf("+ Advice: Restart."); + } + #endif + MemoryErrorExit(); + } + + dl->index = throw_index_add(dl); + + dl->file = __file; + dl->line = __line; + dl->nbytes = __size; + dl->beforeval = BEFOREVAL; + *(dword*)&(dl->data[__size]) = AFTERVAL; + + dl->next = throw_alloclist.next; + dl->prev = &throw_alloclist; + throw_alloclist.next = dl; + if(dl->next != NULL) + dl->next->prev = dl; + + throw_count++; + throw_max_count = maximum_of_two(throw_count, throw_max_count); + throw_allocations++; + + return throw_dltoptr(dl); +} + + +// ------------------------------------------------------------------ +// Debugging realloc() + +void* throw_realloc_debug(void* __oldptr, size_t __size, const char* __file, int __line) { + + void* _ptr; + Throw* dl = throw_ptrtodl(__oldptr); + + if(__size == 0) { + throw_free_debug(__oldptr,__file,__line); + _ptr = NULL; + } + else if(__oldptr == NULL) { + _ptr = throw_malloc_debug(__size,__file,__line); + } + else { + _ptr = throw_malloc_debug(__size,__file,__line); + if(dl->nbytes < __size) + __size = dl->nbytes; + memcpy(_ptr,__oldptr,__size); + throw_free_debug(__oldptr,__file,__line); + } + return _ptr; +} + + +// ------------------------------------------------------------------ +// Debugging free() + +void throw_free_debug(void* __ptr, const char* __file, int __line) { + + Throw* dl; + Throw* overrun_dl = NULL; + Throw* underrun_dl = NULL; + + if(__ptr == NULL) + return; + int inerr = false; + if(throw_count <= 0) { + #if defined(GTHROW_LOG) + TLOG->errmemory(__file, __line); + TLOG->printf("! More free's than allocs."); + TLOG->printf("+ Info: This indicates a potentially serious bug."); + TLOG->printf("+ Advice: Report to the Author immediately."); + #endif + goto err; + } + dl = throw_ptrtodl(__ptr); + if(dl->nbytes == BAD_SIZE) { + #if defined(GTHROW_LOG) + TLOG->errpointer(__file, __line); + TLOG->printf("! A memory allocation was already free'd."); + #endif + goto err2; + } + if(dl->beforeval != BEFOREVAL) { + #if defined(GTHROW_LOG) + TLOG->errpointer(__file, __line); + TLOG->printf("! An allocated memory region was underrun."); + #endif + dl->prev = dl->next = NULL; + dl->file = NULL; + underrun_dl = throw_find_underrun(dl); + goto err2; + } + if(*(dword*)&dl->data[dl->nbytes] != AFTERVAL) { + #if defined(GTHROW_LOG) + TLOG->errpointer(__file, __line); + TLOG->printf("! An allocated memory region was overrun."); + #endif + overrun_dl = throw_find_overrun(dl); + inerr = true; + } + + if(inerr) + goto err2; + + if(dl->prev) + dl->prev->next = dl->next; + if(dl->next) + dl->next->prev = dl->prev; + + throw_index_remove(dl->index); + + memset(dl,BADVAL,sizeof(*dl)+dl->nbytes); + throw_count--; + + free(dl); + return; + +err2: + throw_printdl(dl); + if(underrun_dl) { + #if defined(GTHROW_LOG) + TLOG->printf("! Possibly caused by overrun in this allocation:"); + throw_printdl(underrun_dl); + if(*(dword*)&underrun_dl->data[underrun_dl->nbytes] != AFTERVAL) + TLOG->printf("! Overrun of previous allocation confirmed."); + #endif + } + if(overrun_dl) { + #if defined(GTHROW_LOG) + TLOG->printf("! Possibly cause - Underrun in this allocation:"); + throw_printdl(overrun_dl); + if(overrun_dl->beforeval != BEFOREVAL) + TLOG->printf("! Underrun of previous allocation confirmed."); + #endif + } + #if defined(GTHROW_LOG) + TLOG->printf(": Detected while freeing the allocation."); + TLOG->printf("+ Info: This indicates a serious bug."); + TLOG->printf("+ Advice: Report to the Author immediately."); + #endif +err: + //PointerErrorExit(); + ; +} + + +// ------------------------------------------------------------------ +// Check all allocations + +void throw_check_debug(const char* __file, int __line) { + + Throw* dl = throw_alloclist.next; + while(dl != NULL) { + throw_checkptr_debug(throw_dltoptr(dl), __file, __line); + dl = dl->next; + } +} + + +// ------------------------------------------------------------------ +// Check individual allocation + +void throw_checkptr_debug(const void* __ptr, const char* __file, int __line) { + + int inerr = false; + Throw* dl; + Throw* overrun_dl = NULL; + Throw* underrun_dl = NULL; + if(__ptr == NULL) { + #if defined(GTHROW_LOG) + TLOG->errpointer(__file, __line); + TLOG->printf("! Found NULL pointer instead of allocated memory."); + #endif + goto err3; + } + dl = throw_ptrtodl(__ptr); + if(dl->beforeval != BEFOREVAL) { + #if defined(GTHROW_LOG) + TLOG->errpointer(__file, __line); + TLOG->printf("! An allocated memory region was underrun."); + #endif + dl->prev = dl->next = NULL; + dl->file = NULL; + underrun_dl = throw_find_underrun(dl); + goto err2; + } + if(*(dword*)&dl->data[dl->nbytes] != AFTERVAL) { + #if defined(GTHROW_LOG) + TLOG->errpointer(__file, __line); + TLOG->printf("! An allocated memory region was overrun."); + #endif + overrun_dl = throw_find_overrun(dl); + inerr = true; + } + if(inerr) + goto err2; + return; + +err2: + throw_printdl(dl); + if(underrun_dl) { + #if defined(GTHROW_LOG) + TLOG->printf("! Possibly caused by overrun in this allocation:"); + throw_printdl(underrun_dl); + if(*(dword*)&underrun_dl->data[underrun_dl->nbytes] != AFTERVAL) + TLOG->printf("! Overrun of previous allocation confirmed."); + #endif + } + if(overrun_dl) { + #if defined(GTHROW_LOG) + TLOG->printf("! Possibly cause - Underrun in this allocation:"); + throw_printdl(overrun_dl); + if(overrun_dl->beforeval != BEFOREVAL) + TLOG->printf("! Underrun of previous allocation confirmed."); + #endif + } +err3: + #if defined(GTHROW_LOG) + TLOG->printf(": Detected while checking the allocation."); + TLOG->printf("+ Info: This indicates a serious bug."); + TLOG->printf("+ Advice: Report to the Author immediately."); + #endif + PointerErrorExit(); +} + + +// ------------------------------------------------------------------ +// Termination function + +static void throw_term(void) { + + if(throw_inited) { + #if defined(GTHROW_LOG) + if(throw_count) + TLOG->printf("! Detected %i unfree'd memory allocation%s.", throw_count, throw_count==1?"":"s"); + if(not error_exit) { + Throw* dl = throw_alloclist.next; + int count = throw_count; + for(; dl; ) { + Throw* dl_next = dl->next; + throw_printdl(dl); + throw_free_debug(throw_dltoptr(dl), __FILE__, __LINE__); + dl = dl_next; + } + throw_count = count; + if(throw_count) { + TLOG->printf("+ Info: The memory should have been free'd before exit."); + TLOG->printf("+ Info: This indicates a potentially serious bug."); + TLOG->printf("+ Advice: Report to the Author immediately."); + } + } + #endif + free(throw_index); + throw_inited = 0; + } +} + + +// ------------------------------------------------------------------ +// Init function + +void throw_init() { + + if(throw_inited == 0) { + throw_count = 0; + throw_alloclist.next = NULL; + throw_alloclist.prev = NULL; + throw_alloclist.file = __FILE__; + throw_alloclist.line = __LINE__; + throw_alloclist.nbytes = 0; + throw_alloclist.beforeval = BEFOREVAL; + throw_alloclist.data[0] = 0xFF; + throw_inited++; + atexit(throw_term); + } +} + +// ------------------------------------------------------------------ + +#ifdef gmem_strdup +#undef gmem_strdup +#define gmem_strdup(a) throw_strdup_debug(a, file, line) +#undef gmem_malloc +#define gmem_malloc(a) throw_malloc_debug(a, file, line) +#undef gmem_calloc +#define gmem_calloc(a,b) throw_calloc_debug(a, b, file, line) +#undef gmem_realloc +#define gmem_realloc(a,b) throw_realloc_debug(a, b, file, line) +#undef gmem_free +#define gmem_free(a) throw_free_debug(a, file, line) +#endif + +#endif + + +// ------------------------------------------------------------------ + +void* throw_outofmem_report(const char* file, int line, uint size) { + + #if defined(GTHROW_LOG) + TLOG->errmemory(file, line); + if(size == 0) { + TLOG->printf("! Attempted to allocate zero bytes of memory."); + TLOG->printf("+ Advice: This is a bug. Please report to the Author."); + } + else { + TLOG->printf("! A memory allocation failed (out of memory)."); + TLOG->printf(": Needed %u (%Xh) bytes.", size, size); + TLOG->printf("+ Advice: Restart."); + } + #else + NW(file); + NW(line); + NW(size); + #endif + MemoryErrorExit(); + return NULL; +} + + +// ------------------------------------------------------------------ + +void throw_xnew_debug(void* ptr, const char* file, int line) { + + if(ptr == NULL) + throw_outofmem_report(file, line, 0); +} + + +// ------------------------------------------------------------------ + +char* throw_xstrdup_debug(const char* str, const char* file, int line) { + + char* s = gmem_strdup(str); + return s ? s : (char*)throw_outofmem_report(file, line, strlen(str)); +} + + +// ------------------------------------------------------------------ + +void* throw_xmalloc_debug(size_t size, const char* file, int line) { + + void* p = gmem_malloc(size+throw_alloc_extra); + return p ? p : throw_outofmem_report(file, line, size); +} + + +// ------------------------------------------------------------------ + +void* throw_xcalloc_debug(size_t items, size_t size, const char* file, int line) { + + void* p = gmem_calloc(items, size+throw_alloc_extra); + return p ? p : throw_outofmem_report(file, line, items*size); +} + + +// ------------------------------------------------------------------ + +void* throw_xrealloc_debug(void* ptr, size_t size, const char* file, int line) { + + void* p = gmem_realloc(ptr, size+throw_alloc_extra); + return p ? p : throw_outofmem_report(file, line, size); +} + + +// ------------------------------------------------------------------ + +void throw_xfree_debug(void* ptr, const char* file, int line) { + + if(ptr) + gmem_free(ptr); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmemdbg.h b/goldlib/gall/gmemdbg.h new file mode 100644 index 0000000..e7f284a --- /dev/null +++ b/goldlib/gall/gmemdbg.h @@ -0,0 +1,163 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Memory management routines with debugging features. +// Based on free code from SNIPPETS 9404 by Walter Bright. +// ------------------------------------------------------------------ + +#ifndef __gdbgtmem_h +#define __gdbgtmem_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Global variables + +extern int throw_alloc_extra; + +#if defined(GTHROW_LOG) +class glog; +extern glog* throw_log; +#endif + + +// ------------------------------------------------------------------ +// Prototypes + +void throw_init(); + +void throw_check(); +void throw_checkptr(void* ptr); + +char* throw_strdup(const char* str); +void* throw_malloc(size_t size); +void* throw_calloc(size_t items, size_t size); +void* throw_realloc(void* ptr, size_t size); +void throw_free(void* ptr); + +char* throw_xstrdup(const char* str); +void* throw_xmalloc(size_t size); +void* throw_xcalloc(size_t items, size_t size); +void* throw_xrealloc(void* ptr, size_t size); +void throw_xfree(void* ptr); + +void* throw_outofmem(); +void* throw_outofmem_report(const char* file, int line); + + +// ------------------------------------------------------------------ +// Debugging prototypes + +void throw_new_debug(const void* ptr, const char* file, int line); +char* throw_strdup_debug(const char* str, const char* file, int line); +void* throw_malloc_debug(size_t size, const char* file, int line); +void* throw_calloc_debug(size_t items, size_t size, const char* file, int line); +void* throw_realloc_debug(void* ptr, size_t size, const char* file, int line); +void throw_free_debug(void* ptr, const char* file, int line); +void throw_check_debug(const char* file, int line); +void throw_checkptr_debug(const void* ptr, const char* file, int line); + +void throw_xnew_debug(void* ptr, const char* file, int line); +char* throw_xstrdup_debug(const char* str, const char* file, int line); +void* throw_xmalloc_debug(size_t size, const char* file, int line); +void* throw_xcalloc_debug(size_t items, size_t size, const char* file, int line); +void* throw_xrealloc_debug(void* ptr, size_t size, const char* file, int line); +void throw_xfree_debug(void* ptr, const char* file, int line); + + +// ------------------------------------------------------------------ +// Macro functions + +#if defined(GTHROW_DEBUG) +# define throw_new(p) throw_new_debug((p),__FILE__,__LINE__) +# define throw_alloc(p) throw_new_debug((p),__FILE__,__LINE__) +# define throw_strdup(p) throw_strdup_debug((p),__FILE__,__LINE__) +# define throw_malloc(s) throw_malloc_debug((s),__FILE__,__LINE__) +# define throw_calloc(i,s) throw_calloc_debug((i),(s),__FILE__,__LINE__) +# define throw_realloc(p,s) throw_realloc_debug((p),(s),__FILE__,__LINE__) +# define throw_free(p) throw_free_debug((p),__FILE__,__LINE__) +# define throw_check() throw_check_debug(__FILE__,__LINE__) +# define throw_checkptr(p) throw_checkptr_debug((p),__FILE__,__LINE__) +#else +# define throw_new(p) throw_xnew_debug((p),__FILE__,__LINE__) +# define throw_alloc(p) throw_xnew_debug((p),__FILE__,__LINE__) +# define throw_strdup(p) throw_xstrdup_debug((p),__FILE__,__LINE__) +# define throw_malloc(s) throw_xmalloc_debug((s),__FILE__,__LINE__) +# define throw_calloc(i,s) throw_xcalloc_debug((i),(s),__FILE__,__LINE__) +# define throw_realloc(p,s) throw_xrealloc_debug((p),(s),__FILE__,__LINE__) +# define throw_free(p) throw_xfree_debug((p),__FILE__,__LINE__) +# define throw_check() +# define throw_checkptr(p) +# define throw_init() +#endif + +#define throw_xnew(p) throw_xnew_debug((p),__FILE__,__LINE__) +#define throw_xstrdup(p) throw_xstrdup_debug((p),__FILE__,__LINE__) +#define throw_xmalloc(s) throw_xmalloc_debug((s),__FILE__,__LINE__) +#define throw_xcalloc(i,s) throw_xcalloc_debug((i),(s),__FILE__,__LINE__) +#define throw_xrealloc(p,s) throw_xrealloc_debug((p),(s),__FILE__,__LINE__) +#define throw_xfree(p) throw_xfree_debug((p),__FILE__,__LINE__) + + +// ------------------------------------------------------------------ +// Special purpose macros + +#define throw_release(m) { throw_free(m); (m) = NULL; } +#define throw_xrelease(m) { throw_xfree(m); (m) = NULL; } + +#define throw_delete(p) { delete (p); (p) = NULL; } +#define throw_xdelete(p) { if(p) delete (p); (p) = NULL; } + +#define throw_deletearray(p) { delete[] (p); (p) = NULL; } +#define throw_xdeletearray(p) { if(p) delete[] (p); (p) = NULL; } + +#define throw_mallox(__items, __size, __cache) throw_malloc((__items+__cache+1)*__size) +#define throw_callox(__items, __size, __cache) throw_calloc(__items+__cache+1, __size) +#define throw_reallox(__ptr, __items, __size, __cache) (((__items % __cache) and __ptr) ? (void*)__ptr : throw_realloc(__ptr, (__items+__cache+1)*__size)); + +#define throw_xmallox(__items, __size, __cache) throw_xmalloc((__items+__cache+1)*__size) +#define throw_xcallox(__items, __size, __cache) throw_xcalloc(__items+__cache+1, __size) +#define throw_xreallox(__ptr, __items, __size, __cache) (((__items % __cache) and __ptr) ? (void*)__ptr : throw_xrealloc(__ptr, (__items+__cache+1)*__size)); + + +// ------------------------------------------------------------------ + +#if defined(GTHROWCHKPTR_ENABLE) +# define THROW_CHECKPTR(p) throw_checkptr(p) +# define THROW_CHECK() throw_check() +#else +# define THROW_CHECKPTR(p) +# define THROW_CHECK() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmemi86.h b/goldlib/gall/gmemi86.h new file mode 100644 index 0000000..060253c --- /dev/null +++ b/goldlib/gall/gmemi86.h @@ -0,0 +1,234 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Intel 80x86 interrupt portable wrapper class. +// ------------------------------------------------------------------ + +#ifndef __gmemi86_h +#define __gmemi86_h + + +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(__WATCOMC__) + +#define GREGPACK REGPACK + +#elif defined(__DJGPP__) + +#include +#define GREGPACK __dpmi_regs + +#elif defined(__BORLANDC__) + +#define GREGPACK REGS + +#else + +#error not supported! + +#endif + + +// ------------------------------------------------------------------ + +class i86 { + +protected: + + GREGPACK r; + #if defined(__BORLANDC__) + SREGS sr; + #endif + +public: + + inline uint al() { return r.h.al; } + inline uint ah() { return r.h.ah; } + inline uint bl() { return r.h.bl; } + inline uint bh() { return r.h.bh; } + inline uint cl() { return r.h.cl; } + inline uint ch() { return r.h.ch; } + inline uint dl() { return r.h.dl; } + inline uint dh() { return r.h.dh; } + #ifdef __DJGPP__ + inline uint ax() { return r.x.ax; } + inline uint bx() { return r.x.bx; } + inline uint cx() { return r.x.cx; } + inline uint dx() { return r.x.dx; } + inline uint bp() { return r.x.bp; } + inline uint si() { return r.x.si; } + inline uint di() { return r.x.di; } + inline uint ds() { return r.x.ds; } + inline uint es() { return r.x.es; } + inline uint flags() { return r.x.flags; } + #else + inline uint ax() { return r.w.ax; } + inline uint bx() { return r.w.bx; } + inline uint cx() { return r.w.cx; } + inline uint dx() { return r.w.dx; } + inline uint bp() { return r.w.bp; } + inline uint si() { return r.w.si; } + inline uint di() { return r.w.di; } + #if defined(__BORLANDC__) + inline uint ds() { return sr.w.ds; } + inline uint es() { return sr.w.es; } + #else + inline uint ds() { return r.w.ds; } + inline uint es() { return r.w.es; } + #endif + inline uint flags() { return r.w.flags; } + #endif + + inline void al(ulong b) { r.h.al = (byte)b; } + inline void ah(ulong b) { r.h.ah = (byte)b; } + inline void bl(ulong b) { r.h.bl = (byte)b; } + inline void bh(ulong b) { r.h.bh = (byte)b; } + inline void cl(ulong b) { r.h.cl = (byte)b; } + inline void ch(ulong b) { r.h.ch = (byte)b; } + inline void dl(ulong b) { r.h.dl = (byte)b; } + inline void dh(ulong b) { r.h.dh = (byte)b; } + #ifdef __DJGPP__ + inline void ax(ulong w) { r.x.ax = (word)w; } + inline void bx(ulong w) { r.x.bx = (word)w; } + inline void cx(ulong w) { r.x.cx = (word)w; } + inline void dx(ulong w) { r.x.dx = (word)w; } + inline void bp(ulong w) { r.x.bp = (word)w; } + inline void si(ulong w) { r.x.si = (word)w; } + inline void di(ulong w) { r.x.di = (word)w; } + inline void ds(ulong w) { r.x.ds = (word)w; } + inline void es(ulong w) { r.x.es = (word)w; } + inline void flags(ulong w) { r.x.flags = (word)w; } + #else + inline void ax(ulong w) { r.w.ax = (word)w; } + inline void bx(ulong w) { r.w.bx = (word)w; } + inline void cx(ulong w) { r.w.cx = (word)w; } + inline void dx(ulong w) { r.w.dx = (word)w; } + inline void bp(ulong w) { r.w.bp = (word)w; } + inline void si(ulong w) { r.w.si = (word)w; } + inline void di(ulong w) { r.w.di = (word)w; } + #if defined(__BORLANDC__) + inline void ds(ulong w) { sr.w.ds = (word)w; } + inline void es(ulong w) { sr.w.es = (word)w; } + #else + inline void ds(ulong w) { r.w.ds = (word)w; } + inline void es(ulong w) { r.w.es = (word)w; } + #endif + inline void flags(ulong w) { r.w.flags = (word)w; } + #endif + + void genint(int intno); +}; + + +// ------------------------------------------------------------------ +// Inline implementations + +inline void i86::genint(int intno) { + + #if defined(__BORLANDC__) + #if defined(__DPMI32__) + int386x(intno, &r, &r, &sr); + #else + int86x(intno, &r, &r, &sr); + #endif + #elif defined(__DJGPP__) + __dpmi_int(intno, &r); + #else + intr(intno, &r); + #endif +} + + +#if defined(__WATCOMC__) and defined(__386__) +inline int __dpmi_allocate_dos_memory(long len, int &buf) { + + i86 cpu; + // Determine how much is available + cpu.ax(0x100); + cpu.bx(65535u); + cpu.genint(0x31); + if(len > (long)cpu.bx()*16L) + return -1; + cpu.ax(0x100); + cpu.bx(len); + cpu.genint(0x31); + *buffer = (int) cpu.dx(); + return (int) cpu.ax(); +} + + +inline void __dpmi_free_dos_memory(int buffer) { + + i86 cpu; + cpu.ax(0x101); + cpu.dx((word) buffer); + cpu.genint(0x31); +} +#endif + + +// ------------------------------------------------------------------ +// A more portable version of MK_FP() + +#if defined(__WATCOMC__) and defined(__386__) + +#define gmkfp(s,o) ((s << 4) + o) + +#elif defined(__DJGPP__) + +#include +#include + +inline void *gmkfp(unsigned short seg, unsigned short ofs) { + if(not (_crt0_startup_flags & _CRT0_FLAG_NEARPTR)) + if(not __djgpp_nearptr_enable()) + return (void *)0; + return (void *)(seg*16 + ofs + __djgpp_conventional_base); +} + +#else + +#define gmkfp(s,o) MK_FP(s,o) + +#endif + + +// ------------------------------------------------------------------ + +#endif +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmemutil.cpp b/goldlib/gall/gmemutil.cpp new file mode 100644 index 0000000..d48b51f --- /dev/null +++ b/goldlib/gall/gmemutil.cpp @@ -0,0 +1,69 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Miscellaneous memory functions +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Dump 16 bytes as hex and characters + +char* HexDump16(char* strbuf, const char* memptr, int limit, const char* fmt, int fmtno) { + + int n; + word mem[16]; + char str[17]; + word* mptr=mem; + char* sptr=str; + const char* fmts[] = { + fmt, + "%02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X %s", + "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %s" + }; + + limit = (limit > 16) ? 16 : limit; + + for(n=0; n= ' ' ? *memptr : '.'; + } + for(; n<16; n++, memptr++) { + *mptr++ = 0; + *sptr++ = '.'; + } + *sptr = NUL; + + sprintf(strbuf, fmts[fmtno], + mem[0], mem[1], mem[2], mem[3], mem[4], mem[5], mem[6], mem[7], + mem[8], mem[9], mem[10], mem[11], mem[12], mem[13], mem[14], mem[15], + str + ); + + return strbuf; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmnubase.h b/goldlib/gall/gmnubase.h new file mode 100644 index 0000000..dc1b42c --- /dev/null +++ b/goldlib/gall/gmnubase.h @@ -0,0 +1,134 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Menu class. +// ------------------------------------------------------------------ + +#ifndef __gmnubase_h +#define __gmnubase_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Menu items + +typedef struct _item_t GMnuItm; + + +// ------------------------------------------------------------------ +// Menu class + +class GMnu { + +protected: + + int bordertype; + int bordercolor; + + int textcolor; + int quickcolor; + int noselcolor; + int barcolor; + int shadowcolor; + + const char* title; + int titlepos; + int titlecolor; + + int deschdl; + int descrow; + int desccolumn; + int desccolor; + + int helpnumber; + + int beginrow; + int begincolumn; + int beginwidth; + int beginheight; + + VfvCP menuopen; + int itemmask; + + int escape; + int finaltag; + int status; + + int depth; + struct { + int tag; + int type; + int winrow; + int wincolumn; + int winwidth; + int winheight; + int itemrow; + int itemcolumn; + } stack[10]; + +public: + + void Init(); + + void SetBorder(int type, int color); + void SetColor(int text, int quick, int nosel, int bar, int shadow=-1); + void SetTitle(const char* title, int color, int pos=TCENTER); + void SetTitle(const char* title); + void SetDesc(int hdl, int row, int col, int color); + void SetPos(int row, int col, int width=0, int height=0); + void SetEsc(int option); + void SetHelp(int help); + void SetMask(int mask); + void SetTag(int tag); + + void Begin(int type=M_VERT); + void BeginPullDown(int type=0) { Begin(M_VERT|M_PD|type); } + void End(); + void Start(); + + void Item(int tag, const char* text); + void Item(int tag, const char* text, int fmask); + void Item(int tag, const char* text, VfvCP select, int fmask=M_CLOSE); + void Item(int tag, const char* text, int fmask, VfvCP select, gkey hotkey=0); + void ItemDesc(const char* text); + void ItemFuncs(VfvCP before, VfvCP after); + + void SetNextItem(int tag); + void DisableItem(int tag); + void EnableItem(int tag); + + GMnuItm* FindItem(int tag); + + int FinalTag() { return finaltag; } +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmoubase.cpp b/goldlib/gall/gmoubase.cpp new file mode 100644 index 0000000..70cede2 --- /dev/null +++ b/goldlib/gall/gmoubase.cpp @@ -0,0 +1,455 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Mousing. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +#ifdef GOLD_MOUSE + +// ------------------------------------------------------------------ + +GMou gmou; + + +// ------------------------------------------------------------------ + +GMou::GMou() { + + detected = false; + Reset(); +} + + +// ------------------------------------------------------------------ + +GMou::~GMou() { + + Reset(); +} + + +// ------------------------------------------------------------------ + +void GMou::SetLevel(int __level) { + + if(detected) { + level = __level; + if(level < GMOU_LEVEL_NONE) + level = GMOU_LEVEL_NONE; + else if(level > GMOU_LEVEL_FULL) + level = GMOU_LEVEL_FULL; + } + else { + level = GMOU_LEVEL_NONE; + } +} + + +// ------------------------------------------------------------------ + +void GMou::Reset() { + + level = GMOU_LEVEL_NONE; + hidden = 1; + hit.button = 0; + hit.count = 0; + hit.row = 0; + hit.column = 0; + if(detected) + Init(); +} + + +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ +// DOS MOUSING - BEGIN +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) + + +// ------------------------------------------------------------------ + +void GMou::Init() { + + i86 cpu; + cpu.ax(MSMOUSE_RESET_DRIVER); + cpu.genint(MSMOUSE_INT); + if(cpu.ax()) + detected = true; +} + + +// ------------------------------------------------------------------ + +void GMou::ClearEvents() { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_GET_BUTTON_PRESS); + cpu.bx(GMOU_LEFT_BUTTON); + cpu.genint(MSMOUSE_INT); + cpu.ax(MSMOUSE_GET_BUTTON_PRESS); + cpu.bx(GMOU_RIGHT_BUTTON); + cpu.genint(MSMOUSE_INT); + cpu.ax(MSMOUSE_GET_BUTTON_RELEASE); + cpu.bx(GMOU_LEFT_BUTTON); + cpu.genint(MSMOUSE_INT); + cpu.ax(MSMOUSE_GET_BUTTON_RELEASE); + cpu.bx(GMOU_RIGHT_BUTTON); + cpu.genint(MSMOUSE_INT); + } +} + + +// ------------------------------------------------------------------ + +void GMou::GetStatus() { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_GET_BUTTONS_AND_POSITION); + cpu.genint(MSMOUSE_INT); + hit.button = cpu.bx(); + hit.count = 0; + hit.column = cpu.cx() / gvid->curr.screen.cwidth; + hit.row = cpu.dx() / gvid->curr.screen.cheight; + } +} + + +// ------------------------------------------------------------------ + +void GMou::GetPress(int __button) { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_GET_BUTTON_PRESS); + cpu.bx((word)__button); + cpu.genint(MSMOUSE_INT); + hit.button = cpu.ax(); + hit.count = cpu.bx(); + hit.column = cpu.cx() / gvid->curr.screen.cwidth; + hit.row = cpu.dx() / gvid->curr.screen.cheight; + } +} + + +// ------------------------------------------------------------------ + +void GMou::GetRelease(int __button) { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_GET_BUTTON_RELEASE); + cpu.bx((word)__button); + cpu.genint(MSMOUSE_INT); + hit.button = cpu.ax(); + hit.count = cpu.bx(); + hit.column = cpu.cx() / gvid->curr.screen.cwidth; + hit.row = cpu.dx() / gvid->curr.screen.cheight; + } +} + + +// ------------------------------------------------------------------ + +void GMou::SetCursor(int __curtype, int __smask, int __cmask) { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_SET_TEXT_CURSOR); + cpu.bx((word)__curtype); + cpu.cx((word)__smask); + cpu.dx((word)__cmask); + cpu.genint(MSMOUSE_INT); + } +} + + +// ------------------------------------------------------------------ + +void GMou::SetPosition(int __row, int __col) { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_SET_CURSOR_POSITION); + cpu.cx((word)(__col * gvid->curr.screen.cwidth)); + cpu.dx((word)(__row * gvid->curr.screen.cheight)); + cpu.genint(MSMOUSE_INT); + } +} + + +// ------------------------------------------------------------------ + +void GMou::HideCursor() { + + if(level) { + if(not hidden) { + i86 cpu; + cpu.ax(MSMOUSE_HIDE_CURSOR); + cpu.genint(MSMOUSE_INT); + hidden = true; + } + } +} + + +// ------------------------------------------------------------------ + +void GMou::ShowCursor() { + + if(level) { + i86 cpu; + cpu.ax(MSMOUSE_SHOW_CURSOR); + cpu.genint(MSMOUSE_INT); + hidden = false; + } +} + + +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ +// DOS MOUSING - END +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ + +#endif + + +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ +// OS/2 MOUSING - BEGIN +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ + +#if defined(__OS2__) + + +// ------------------------------------------------------------------ + +void GMou::Init() { + + #if 0 + if(MouOpen(NULL, &hmou) == 0) { + USHORT _mask = MOUSE_BN1_DOWN|MOUSE_BN2_DOWN|MOUSE_BN3_DOWN; + MouSetEventMask(&_mask, hmou); + detected = true; + } + #endif +} + + +// ------------------------------------------------------------------ + +void GMou::ClearEvents() { + + if(level) { + MouFlushQue(hmou); + } +} + + +// ------------------------------------------------------------------ + +void GMou::GetStatus() { + + if(level) { + PTRLOC _pos; + MouGetPtrPos(&_pos, hmou); + hit.button = 0; + hit.count = 0; + hit.column = _pos.col; + hit.row = _pos.row; + MOUEVENTINFO _event; + USHORT _wait = MOU_NOWAIT; + if(MouReadEventQue(&_event, &_wait, hmou) == 0) { + if(_event.fs & (MOUSE_BN1_DOWN|MOUSE_MOTION_WITH_BN1_DOWN)) + hit.button |= GMOU_LEFT_PRESSED; + if(_event.fs & (MOUSE_BN2_DOWN|MOUSE_MOTION_WITH_BN2_DOWN)) + hit.button |= GMOU_RIGHT_PRESSED; + if(_event.fs & (MOUSE_BN3_DOWN|MOUSE_MOTION_WITH_BN3_DOWN)) + hit.button |= GMOU_MIDDLE_PRESSED; + } + } +} + + +// ------------------------------------------------------------------ + +void GMou::GetPress(int __button) { + + NW(__button); + #if 0 + if(level) { + hit.button = 0; + hit.count = 0; + hit.column = 0; + hit.row = 0; + MOUQUEINFO _que; + MouGetNumQueEl(&_que, hmou); + hit.count = _que.cEvents; + if(hit.count) { + MOUEVENTINFO _event; + USHORT _wait = MOU_WAIT; + if(MouReadEventQue(&_event, &_wait, hmou) == 0) { + if(_event.fs & (MOUSE_BN1_DOWN|MOUSE_MOTION_WITH_BN1_DOWN)) + hit.button |= GMOU_LEFT_PRESSED; + if(_event.fs & (MOUSE_BN2_DOWN|MOUSE_MOTION_WITH_BN2_DOWN)) + hit.button |= GMOU_RIGHT_PRESSED; + if(_event.fs & (MOUSE_BN3_DOWN|MOUSE_MOTION_WITH_BN3_DOWN)) + hit.button |= GMOU_MIDDLE_PRESSED; + hit.column = _event.col; + hit.row = _event.row; + } + } + } + #endif +} + + +// ------------------------------------------------------------------ + +void GMou::GetRelease(int __button) { + + NW(__button); + #if 0 + if(level) { + hit.button = 0; + hit.count = 0; + hit.column = 0; + hit.row = 0; + MOUQUEINFO _que; + MouGetNumQueEl(&_que, hmou); + hit.count = _que.cEvents; + if(hit.count) { + MOUEVENTINFO _event; + USHORT _wait = MOU_WAIT; + if(MouReadEventQue(&_event, &_wait, hmou) == 0) { + if(_event.fs & (MOUSE_BN1_DOWN|MOUSE_MOTION_WITH_BN1_DOWN)) + hit.button |= GMOU_LEFT_PRESSED; + if(_event.fs & (MOUSE_BN2_DOWN|MOUSE_MOTION_WITH_BN2_DOWN)) + hit.button |= GMOU_RIGHT_PRESSED; + if(_event.fs & (MOUSE_BN3_DOWN|MOUSE_MOTION_WITH_BN3_DOWN)) + hit.button |= GMOU_MIDDLE_PRESSED; + hit.column = _event.col; + hit.row = _event.row; + } + } + } + #endif +} + + +// ------------------------------------------------------------------ + +void GMou::SetCursor(int __curtype, int __smask, int __cmask) { + + if(level) { + // Not implemented yet + NW(__curtype); + NW(__smask); + NW(__cmask); + } +} + + +// ------------------------------------------------------------------ + +void GMou::SetPosition(int __row, int __col) { + + if(level) { + PTRLOC _pos; + _pos.row = (USHORT)__row; + _pos.col = (USHORT)__col; + MouSetPtrPos(&_pos, hmou); + } +} + + +// ------------------------------------------------------------------ + +void GMou::HideCursor() { + + if(level) { + if(not hidden) { + NOPTRRECT _rect; + _rect.row = 0; + _rect.col = 0; + _rect.cRow = (USHORT)(gvid->curr.screen.rows-1); + _rect.cCol = (USHORT)(gvid->curr.screen.columns-1); + MouRemovePtr(&_rect, hmou); + hidden = true; + } + } +} + + +// ------------------------------------------------------------------ + +void GMou::ShowCursor() { + + if(level) { + MouDrawPtr(hmou); + hidden = false; + } +} + + +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ +// OS/2 MOUSING - END +// ------------------------------------------------------------------ +// ------------------------------------------------------------------ + +#endif + + +// ------------------------------------------------------------------ +// Dummy definitions when mouse support is not defined + +void GMou::Init() {} +void GMou::ClearEvents() {} +void GMou::GetStatus() {} +void GMou::GetPress(int) {} +void GMou::GetRelease(int) {} +void GMou::SetCursor(int, int, int) {} +void GMou::SetPosition(int, int) {} +void GMou::HideCursor() {} +void GMou::ShowCursor() {} + + +// ------------------------------------------------------------------ + +#endif // GOLD_MOUSE + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmoubase.h b/goldlib/gall/gmoubase.h new file mode 100644 index 0000000..86d9ac4 --- /dev/null +++ b/goldlib/gall/gmoubase.h @@ -0,0 +1,173 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Mousing. +// ------------------------------------------------------------------ + +#ifndef __gmoubase_h +#define __gmoubase_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#ifdef GOLD_MOUSE + +// ------------------------------------------------------------------ +// Mouse constants + +const int GMOU_LEVEL_NONE = 0; // No mouse support +const int GMOU_LEVEL_KEYS = 1; // Mouse movement emulates arrow keys +const int GMOU_LEVEL_CURS = 2; // Free-moving mouse cursor where supported +const int GMOU_LEVEL_FULL = 3; // Full mouse support (MS_KEYS | MS_CURS) + +const int GMOU_EVENT_MAX = 10; + +const int GMOU_LEFT_BUTTON = 0x00; +const int GMOU_RIGHT_BUTTON = 0x01; + +const int GMOU_LEFT_PRESSED = 0x01; +const int GMOU_RIGHT_PRESSED = 0x02; +const int GMOU_MIDDLE_PRESSED = 0x04; + +const int GMOU_MOVED = 0x01; + +const int GMOU_PRESSED_LEFT = 0x02; +const int GMOU_RELEASED_LEFT = 0x04; +const int GMOU_PRESSED_RIGHT = 0x08; +const int GMOU_RELEASED_RIGHT = 0x10; +const int GMOU_PRESSED_MIDDLE = 0x20; +const int GMOU_RELEASED_MIDDLE = 0x40; + +const int GMOU_EVENT_LEFT = GMOU_PRESSED_LEFT | GMOU_RELEASED_LEFT; +const int GMOU_EVENT_RIGHT = GMOU_PRESSED_RIGHT | GMOU_RELEASED_RIGHT; +const int GMOU_EVENT_MIDDLE = GMOU_PRESSED_MIDDLE | GMOU_RELEASED_MIDDLE; + + +// ------------------------------------------------------------------ +// MS MOUSE interrupt + +const word MSMOUSE_INT = 0x33; + + +// ------------------------------------------------------------------ +// MS MOUSE functions + +const word MSMOUSE_RESET_DRIVER = 0x00; +const word MSMOUSE_SHOW_CURSOR = 0x01; +const word MSMOUSE_HIDE_CURSOR = 0x02; +const word MSMOUSE_GET_BUTTONS_AND_POSITION = 0x03; +const word MSMOUSE_SET_CURSOR_POSITION = 0x04; +const word MSMOUSE_GET_BUTTON_PRESS = 0x05; +const word MSMOUSE_GET_BUTTON_RELEASE = 0x06; +const word MSMOUSE_SET_HORIZONTAL_RANGE = 0x07; +const word MSMOUSE_SET_VERTIAL_RANGE = 0x08; +const word MSMOUSE_SET_GRAPHICS_CURSOR = 0x09; +const word MSMOUSE_SET_TEXT_CURSOR = 0x0A; + + +// ------------------------------------------------------------------ +// Mouse class + +class GMou { + + #if 0 + #ifdef __OS2__ + HMOU hmou; + #endif + #endif + +public: + + int detected; // true if a mouse driver was detected + int level; // Mouse support level (GMOU_LEVEL_xxxx) + int hidden; // Depth of cursor hides + + struct { + int button; + int count; + int row; + int column; + } hit; + + GMou(); + ~GMou(); + + void SetLevel(int __level); + + void Reset(); + void Init(); + + void ClearEvents(); + + void GetStatus(); + void GetPress(int __button); + void GetRelease(int __button); + + void SetCursor(int __curtype, int __smask, int __cmask); + + void SetPosition(int __row, int __col); + + void HideCursor(); + void ShowCursor(); + + int Hidden() { return hidden ? true : false; } + + int Enabled() { return level > GMOU_LEVEL_NONE; } + + int FreeCursor() { return level & GMOU_LEVEL_CURS; } + int KeysEmulate() { return level & GMOU_LEVEL_KEYS; } + + int Button() { return hit.button; } + int LeftButton() { return hit.button & GMOU_LEFT_PRESSED; } + int RightButton() { return hit.button & GMOU_RIGHT_PRESSED; } + int MiddleButton() { return hit.button & GMOU_MIDDLE_PRESSED; } + int Count() { return hit.count; } + int Row() { return hit.row; } + int Column() { return hit.column; } + + void GetLeftPress() { GetPress(GMOU_LEFT_BUTTON); } + void GetRightPress() { GetPress(GMOU_RIGHT_BUTTON); } + + void GetLeftRelease() { GetRelease(GMOU_LEFT_BUTTON); } + void GetRightRelease() { GetRelease(GMOU_RIGHT_BUTTON); } +}; + +extern GMou gmou; + + +// ------------------------------------------------------------------ + +#endif // GOLD_MOUSE + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + + diff --git a/goldlib/gall/gmsgattr.cpp b/goldlib/gall/gmsgattr.cpp new file mode 100644 index 0000000..be61024 --- /dev/null +++ b/goldlib/gall/gmsgattr.cpp @@ -0,0 +1,202 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Message attributes. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Add attributes + +void ftn_attr::add(const ftn_attr& b) { + + if(b.pvt()) pvt1(); + if(b.cra()) cra1(); + if(b.rcv()) rcv1(); + if(b.snt()) snt1(); + if(b.att()) att1(); + if(b.trs()) trs1(); + if(b.orp()) orp1(); + if(b.k_s()) k_s1(); + if(b.loc()) loc1(); + if(b.hld()) hld1(); + if(b.rsv()) rsv1(); + if(b.frq()) frq1(); + if(b.rrq()) rrq1(); + if(b.rrc()) rrc1(); + if(b.arq()) arq1(); + if(b.urq()) urq1(); + + if(b.grp()) grp1_(); + if(b.imm()) imm1(); + if(b.dir()) dir1(); + if(b.tfs()) tfs1(); + if(b.kfs()) kfs1(); + if(b.lok()) lok1(); + if(b.a_s()) a_s1(); + if(b.zon()) zon1(); + if(b.hub()) hub1(); + if(b.xma()) xma1(); + if(b.cfm()) cfm1(); + if(b.hir()) hir1(); + if(b.cov()) cov1(); + if(b.sig()) sig1(); + if(b.let()) let1(); + if(b.uns()) uns1(); + + if(b.del()) del1(); + if(b.nwm()) nwm1(); + if(b.rot()) rot1(); + if(b.hex()) hex1(); + if(b.upd()) upd1(); + if(b.tou()) tou1(); + if(b.fmu()) fmu1(); + if(b.scn()) scn1(); + if(b.pos()) pos1(); + if(b.r_o()) r_o1(); + if(b.nok()) nok1(); + if(b.fax()) fax1(); + if(b.prn()) prn1(); +} + + +// ------------------------------------------------------------------ +// Create string representation of an attribute set + +string& ftn_attr::make_string(string& s) const { + + s = ""; + + if(del()) s += "DEL "; + if(rcv()) s += "Rcv "; + if(snt()) s += "Snt "; + if(uns()) s += "Uns "; + if(imm()) s += "Imm "; + if(dir()) s += "Dir "; + if(lok()) s += "Lok "; + if(tfs()) s += "Tfs "; + if(kfs()) s += "Kfs "; + if(pvt()) s += "Pvt "; + if(cra()) s += "Cra "; + if(loc()) s += "Loc "; + if(hld()) s += "Hld "; + if(k_s()) s += "K/s "; + if(frq()) s += "Frq "; + if(urq()) s += "URq "; + if(att()) s += "Att "; + if(arq()) s += "ARq "; + if(rrq()) s += "RRq "; + if(rrc()) s += "RRc "; + if(trs()) s += "Trs "; + if(orp()) s += "Orp "; + if(a_s()) s += "A/s "; + if(zon()) s += "Zon "; + if(hub()) s += "Hub "; + if(xma()) s += "Xma "; + if(cfm()) s += "Cfm "; + if(hir()) s += "Hir "; + if(cov()) s += "Cov "; + if(sig()) s += "Sig "; + if(let()) s += "Let "; + if(fax()) s += "Fax "; + if(rsv()) s += "Rsv "; + if(grp()) s += "Grp "; + if(scn()) s += "Scn "; + if(prn()) s += "Prn "; + + size_t len = s.length(); + while(len and ('!' > s[--len])) + s.erase(len, 1); + + return s; +} + + +// ------------------------------------------------------------------ + +void ftn_attr::get(const string& __s) { + + const char *s = __s.c_str(); + if(striinc("PVT", s)) pvt1(); + if(striinc("CRA", s)) cra1(); + if(striinc("RCV", s)) rcv1(); + if(striinc("SNT", s)) snt1(); + if(striinc("ATT", s)) att1(); + if(striinc("TRS", s)) trs1(); + if(striinc("ORP", s)) orp1(); + if(striinc("K/S", s)) k_s1(); + if(striinc("LOC", s)) loc1(); + if(striinc("HLD", s)) hld1(); + if(striinc("RSV", s)) rsv1(); + if(striinc("FRQ", s)) frq1(); + if(striinc("RRQ", s)) rrq1(); + if(striinc("RRC", s)) rrc1(); + if(striinc("ARQ", s)) arq1(); + if(striinc("URQ", s)) urq1(); + + if(striinc("GRP", s)) grp1_(); + if(striinc("IMM", s)) imm1(); + if(striinc("DIR", s)) dir1(); + if(striinc("TFS", s)) tfs1(); + if(striinc("KFS", s)) kfs1(); + if(striinc("LOK", s)) lok1(); + if(striinc("A/S", s)) a_s1(); + if(striinc("ZON", s)) zon1(); + if(striinc("HUB", s)) hub1(); + if(striinc("XMA", s)) xma1(); + if(striinc("CFM", s)) cfm1(); + if(striinc("HIR", s)) hir1(); + if(striinc("COV", s)) cov1(); + if(striinc("SIG", s)) sig1(); + if(striinc("LET", s)) let1(); + if(striinc("UNS", s)) uns1(); + + if(striinc("DEL", s)) del1(); + if(striinc("NWM", s)) nwm1(); + if(striinc("ROT", s)) rot1(); + if(striinc("HEX", s)) hex1(); + if(striinc("UPD", s)) upd1(); + if(striinc("TOU", s)) tou1(); + if(striinc("FMU", s)) fmu1(); + if(striinc("SCN", s)) scn1(); + if(striinc("POS", s)) pos1(); + if(striinc("R/O", s)) r_o1(); + if(striinc("NOK", s)) nok1(); + if(striinc("FAX", s)) fax1(); + if(striinc("PRN", s)) prn1(); +} + + +// ------------------------------------------------------------------ + +bool ftn_attr::equals(const ftn_attr& b) const { + + return (attr1 == b.attr1) and (attr2 == b.attr2); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gmsgattr.h b/goldlib/gall/gmsgattr.h new file mode 100644 index 0000000..9f70514 --- /dev/null +++ b/goldlib/gall/gmsgattr.h @@ -0,0 +1,494 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Message attributes. +// ------------------------------------------------------------------ + +#ifndef __gmsgattr_h +#define __gmsgattr_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Internal GoldED message attributes + +const ulong GATTR_PVT = 0x00000001UL; // private +const ulong GATTR_CRA = 0x00000002UL; // crash +const ulong GATTR_RCV = 0x00000004UL; // received +const ulong GATTR_SNT = 0x00000008UL; // sent + +const ulong GATTR_ATT = 0x00000010UL; // file attach +const ulong GATTR_TRS = 0x00000020UL; // transit +const ulong GATTR_ORP = 0x00000040UL; // orphaned +const ulong GATTR_K_S = 0x00000080UL; // kill msg when sent + +const ulong GATTR_LOC = 0x00000100UL; // local +const ulong GATTR_HLD = 0x00000200UL; // hold +const ulong GATTR_RSV = 0x00000400UL; // FTS-1 reserved +const ulong GATTR_FRQ = 0x00000800UL; // file request + +const ulong GATTR_RRQ = 0x00001000UL; // return receipt request +const ulong GATTR_RRC = 0x00002000UL; // return receipt +const ulong GATTR_ARQ = 0x00004000UL; // audit request +const ulong GATTR_URQ = 0x00008000UL; // file update request + +const ulong GATTR_GRP = 0x00010000UL; // group msg (hudson) +const ulong GATTR_IMM = 0x00020000UL; // immediate +const ulong GATTR_DIR = 0x00040000UL; // direct +const ulong GATTR_TFS = 0x00080000UL; // truncate file when sent + +const ulong GATTR_KFS = 0x00100000UL; // kill file when sent +const ulong GATTR_LOK = 0x00200000UL; // locked +const ulong GATTR_A_S = 0x00400000UL; // archive msg when sent +const ulong GATTR_ZON = 0x00800000UL; // send through zone gate + +const ulong GATTR_HUB = 0x01000000UL; // host- or hub route +const ulong GATTR_XMA = 0x02000000UL; // xmail: alternate form of compressed mail attached +const ulong GATTR_CFM = 0x04000000UL; // confirmation receipt requested +const ulong GATTR_HIR = 0x08000000UL; // fax: hi-resolution image + +const ulong GATTR_COV = 0x10000000UL; // fax: cover sheet +const ulong GATTR_SIG = 0x20000000UL; // fax: signature +const ulong GATTR_LET = 0x40000000UL; // fax: letterhead +const ulong GATTR_UNS = 0x80000000UL; // unsent - not scanned (internal) + +const ulong GATTR_DEL = 0x00000001UL; // deleted +const ulong GATTR_NWM = 0x00000002UL; // new message (internal) +const ulong GATTR_ROT = 0x00000004UL; // rot-13 encoded (internal) +const ulong GATTR_HEX = 0x00000008UL; // hexdump (internal) + +const ulong GATTR_UPD = 0x00000010UL; // update *.msg time stamp (internal) +const ulong GATTR_TOU = 0x00000020UL; // to-you (internal) +const ulong GATTR_FMU = 0x00000040UL; // from-you (internal) +const ulong GATTR_SCN = 0x00000080UL; // scanned (squish) + +const ulong GATTR_POS = 0x00000100UL; // set line position (internal) +const ulong GATTR_R_O = 0x00000200UL; // area read-only +const ulong GATTR_NOK = 0x00000400UL; // (not used) +const ulong GATTR_FAX = 0x00000800UL; // file attached is a fax image + +const ulong GATTR_PRN = 0x00001000UL; // message is printed (squish) +const ulong GATTR_ANO = 0x00002000UL; // anonymous +const ulong GATTR_UME = 0x00004000UL; // unmoved echo message (adeptxbbs) +const ulong GATTR_UMN = 0x00008000UL; // unmoved net message (adeptxbbs) + +const ulong GATTR_FSC = 0x00010000UL; // fidonet scanned (adeptxbbs) +const ulong GATTR_GSC = 0x00020000UL; // groupmail scanned (adeptxbbs) +const ulong GATTR_RSC = 0x00040000UL; // rfc822 scanned (adeptxbbs) +const ulong GATTR_TRT = 0x00080000UL; // treated: soft cr's & lf's removed (adeptxbbs) + +const ulong GATTR_LZS = 0x00100000UL; // msg is lzss compressed (adeptxbbs) +const ulong GATTR_ARC = 0x00200000UL; // message is stored (adeptxbbs) +const ulong GATTR_TAG = 0x00400000UL; // tagged: used by offline readers (adeptxbbs & wildcat) +const ulong GATTR_RAB = 0x00800000UL; // receivable (wildcat) + +const ulong GATTR_CAR = 0x01000000UL; // carboned (wildcat) +const ulong GATTR_FWD = 0x02000000UL; // forwarded (wildcat) +const ulong GATTR_EFL = 0x04000000UL; // echoflag (wildcat) +const ulong GATTR_HRP = 0x08000000UL; // has replies (wildcat) + +class ftn_attr { + +protected: + + ulong attr1, attr2; + +public: + + ftn_attr() { reset(); } + ftn_attr(const char* s) { get(s); } + ftn_attr(const string& s) { get(s); } + ftn_attr(const ftn_attr& o) { operator=(o); } + + void reset() { attr1 = attr2 = 0; } + + void add(const ftn_attr& b); + void get(const string& s); + string& make_string(string& s) const; + + bool equals(const ftn_attr& b) const; + + ftn_attr& operator=(const char* s) { get(s); return *this; } + ftn_attr& operator=(const string& s) { get(s); return *this; } + ftn_attr& operator=(const ftn_attr& o) { attr1=o.attr1; attr2=o.attr2; return *this; } + + bool operator==(const ftn_attr& b) const { return equals(b); } + bool operator!=(const ftn_attr& b) const { return !equals(b); } + + // ---------------------------------------------------------------- + + int pvt() const { return (attr1 & GATTR_PVT) != 0; } + int cra() const { return (attr1 & GATTR_CRA) != 0; } + int rcv() const { return (attr1 & GATTR_RCV) != 0; } + int snt() const { return (attr1 & GATTR_SNT) != 0; } + + int att() const { return (attr1 & GATTR_ATT) != 0; } + int trs() const { return (attr1 & GATTR_TRS) != 0; } + int orp() const { return (attr1 & GATTR_ORP) != 0; } + int k_s() const { return (attr1 & GATTR_K_S) != 0; } + + int loc() const { return (attr1 & GATTR_LOC) != 0; } + int hld() const { return (attr1 & GATTR_HLD) != 0; } + int rsv() const { return (attr1 & GATTR_RSV) != 0; } + int frq() const { return (attr1 & GATTR_FRQ) != 0; } + + int rrq() const { return (attr1 & GATTR_RRQ) != 0; } + int rrc() const { return (attr1 & GATTR_RRC) != 0; } + int arq() const { return (attr1 & GATTR_ARQ) != 0; } + int urq() const { return (attr1 & GATTR_URQ) != 0; } + + int grp() const { return (attr1 & GATTR_GRP) != 0; } + int imm() const { return (attr1 & GATTR_IMM) != 0; } + int dir() const { return (attr1 & GATTR_DIR) != 0; } + int tfs() const { return (attr1 & GATTR_TFS) != 0; } + + int kfs() const { return (attr1 & GATTR_KFS) != 0; } + int lok() const { return (attr1 & GATTR_LOK) != 0; } + int a_s() const { return (attr1 & GATTR_A_S) != 0; } + int zon() const { return (attr1 & GATTR_ZON) != 0; } + + int hub() const { return (attr1 & GATTR_HUB) != 0; } + int xma() const { return (attr1 & GATTR_XMA) != 0; } + int cfm() const { return (attr1 & GATTR_CFM) != 0; } + int hir() const { return (attr1 & GATTR_HIR) != 0; } + + int cov() const { return (attr1 & GATTR_COV) != 0; } + int sig() const { return (attr1 & GATTR_SIG) != 0; } + int let() const { return (attr1 & GATTR_LET) != 0; } + int uns() const { return (attr1 & GATTR_UNS) != 0; } + + int del() const { return (attr2 & GATTR_DEL) != 0; } + int nwm() const { return (attr2 & GATTR_NWM) != 0; } + int rot() const { return (attr2 & GATTR_ROT) != 0; } + int hex() const { return (attr2 & GATTR_HEX) != 0; } + + int upd() const { return (attr2 & GATTR_UPD) != 0; } + int tou() const { return (attr2 & GATTR_TOU) != 0; } + int fmu() const { return (attr2 & GATTR_FMU) != 0; } + int scn() const { return (attr2 & GATTR_SCN) != 0; } + + int pos() const { return (attr2 & GATTR_POS) != 0; } + int r_o() const { return (attr2 & GATTR_R_O) != 0; } + int nok() const { return (attr2 & GATTR_NOK) != 0; } + int fax() const { return (attr2 & GATTR_FAX) != 0; } + + int prn() const { return (attr2 & GATTR_PRN) != 0; } + int ano() const { return (attr2 & GATTR_ANO) != 0; } + int ume() const { return (attr2 & GATTR_UME) != 0; } + int umn() const { return (attr2 & GATTR_UMN) != 0; } + + int fsc() const { return (attr2 & GATTR_FSC) != 0; } + int gsc() const { return (attr2 & GATTR_GSC) != 0; } + int rsc() const { return (attr2 & GATTR_RSC) != 0; } + int trt() const { return (attr2 & GATTR_TRT) != 0; } + + int lzs() const { return (attr2 & GATTR_LZS) != 0; } + int arc() const { return (attr2 & GATTR_ARC) != 0; } + int tag() const { return (attr2 & GATTR_TAG) != 0; } + int rab() const { return (attr2 & GATTR_RAB) != 0; } + + int car() const { return (attr2 & GATTR_CAR) != 0; } + int fwd() const { return (attr2 & GATTR_FWD) != 0; } + int efl() const { return (attr2 & GATTR_EFL) != 0; } + int hrp() const { return (attr2 & GATTR_HRP) != 0; } + + // ---------------------------------------------------------------- + + void pvt(ulong x) { if(x) attr1 |= GATTR_PVT; else attr1 &= ~GATTR_PVT; } + void cra(ulong x) { if(x) attr1 |= GATTR_CRA; else attr1 &= ~GATTR_CRA; } + void rcv(ulong x) { if(x) attr1 |= GATTR_RCV; else attr1 &= ~GATTR_RCV; } + void snt(ulong x) { if(x) attr1 |= GATTR_SNT; else attr1 &= ~GATTR_SNT; } + + void att(ulong x) { if(x) attr1 |= GATTR_ATT; else attr1 &= ~GATTR_ATT; } + void trs(ulong x) { if(x) attr1 |= GATTR_TRS; else attr1 &= ~GATTR_TRS; } + void orp(ulong x) { if(x) attr1 |= GATTR_ORP; else attr1 &= ~GATTR_ORP; } + void k_s(ulong x) { if(x) attr1 |= GATTR_K_S; else attr1 &= ~GATTR_K_S; } + + void loc(ulong x) { if(x) attr1 |= GATTR_LOC; else attr1 &= ~GATTR_LOC; } + void hld(ulong x) { if(x) attr1 |= GATTR_HLD; else attr1 &= ~GATTR_HLD; } + void rsv(ulong x) { if(x) attr1 |= GATTR_RSV; else attr1 &= ~GATTR_RSV; } + void frq(ulong x) { if(x) attr1 |= GATTR_FRQ; else attr1 &= ~GATTR_FRQ; } + + void rrq(ulong x) { if(x) attr1 |= GATTR_RRQ; else attr1 &= ~GATTR_RRQ; } + void rrc(ulong x) { if(x) attr1 |= GATTR_RRC; else attr1 &= ~GATTR_RRC; } + void arq(ulong x) { if(x) attr1 |= GATTR_ARQ; else attr1 &= ~GATTR_ARQ; } + void urq(ulong x) { if(x) attr1 |= GATTR_URQ; else attr1 &= ~GATTR_URQ; } + + void grp(ulong x) { if(x) attr1 |= GATTR_GRP; else attr1 &= ~GATTR_GRP; } + void imm(ulong x) { if(x) attr1 |= GATTR_IMM; else attr1 &= ~GATTR_IMM; } + void dir(ulong x) { if(x) attr1 |= GATTR_DIR; else attr1 &= ~GATTR_DIR; } + void tfs(ulong x) { if(x) attr1 |= GATTR_TFS; else attr1 &= ~GATTR_TFS; } + + void kfs(ulong x) { if(x) attr1 |= GATTR_KFS; else attr1 &= ~GATTR_KFS; } + void lok(ulong x) { if(x) attr1 |= GATTR_LOK; else attr1 &= ~GATTR_LOK; } + void a_s(ulong x) { if(x) attr1 |= GATTR_A_S; else attr1 &= ~GATTR_A_S; } + void zon(ulong x) { if(x) attr1 |= GATTR_ZON; else attr1 &= ~GATTR_ZON; } + + void hub(ulong x) { if(x) attr1 |= GATTR_HUB; else attr1 &= ~GATTR_HUB; } + void xma(ulong x) { if(x) attr1 |= GATTR_XMA; else attr1 &= ~GATTR_XMA; } + void cfm(ulong x) { if(x) attr1 |= GATTR_CFM; else attr1 &= ~GATTR_CFM; } + void hir(ulong x) { if(x) attr1 |= GATTR_HIR; else attr1 &= ~GATTR_HIR; } + + void cov(ulong x) { if(x) attr1 |= GATTR_COV; else attr1 &= ~GATTR_COV; } + void sig(ulong x) { if(x) attr1 |= GATTR_SIG; else attr1 &= ~GATTR_SIG; } + void let(ulong x) { if(x) attr1 |= GATTR_LET; else attr1 &= ~GATTR_LET; } + void uns(ulong x) { if(x) attr1 |= GATTR_UNS; else attr1 &= ~GATTR_UNS; } + + void del(ulong x) { if(x) attr2 |= GATTR_DEL; else attr2 &= ~GATTR_DEL; } + void nwm(ulong x) { if(x) attr2 |= GATTR_NWM; else attr2 &= ~GATTR_NWM; } + void rot(ulong x) { if(x) attr2 |= GATTR_ROT; else attr2 &= ~GATTR_ROT; } + void hex(ulong x) { if(x) attr2 |= GATTR_HEX; else attr2 &= ~GATTR_HEX; } + + void upd(ulong x) { if(x) attr2 |= GATTR_UPD; else attr2 &= ~GATTR_UPD; } + void tou(ulong x) { if(x) attr2 |= GATTR_TOU; else attr2 &= ~GATTR_TOU; } + void fmu(ulong x) { if(x) attr2 |= GATTR_FMU; else attr2 &= ~GATTR_FMU; } + void scn(ulong x) { if(x) attr2 |= GATTR_SCN; else attr2 &= ~GATTR_SCN; } + + void pos(ulong x) { if(x) attr2 |= GATTR_POS; else attr2 &= ~GATTR_POS; } + void r_o(ulong x) { if(x) attr2 |= GATTR_R_O; else attr2 &= ~GATTR_R_O; } + void nok(ulong x) { if(x) attr2 |= GATTR_NOK; else attr2 &= ~GATTR_NOK; } + void fax(ulong x) { if(x) attr2 |= GATTR_FAX; else attr2 &= ~GATTR_FAX; } + + void prn(ulong x) { if(x) attr2 |= GATTR_PRN; else attr2 &= ~GATTR_PRN; } + void ano(ulong x) { if(x) attr2 |= GATTR_ANO; else attr2 &= ~GATTR_ANO; } + void ume(ulong x) { if(x) attr2 |= GATTR_UME; else attr2 &= ~GATTR_UME; } + void umn(ulong x) { if(x) attr2 |= GATTR_UMN; else attr2 &= ~GATTR_UMN; } + + void fsc(ulong x) { if(x) attr2 |= GATTR_FSC; else attr2 &= ~GATTR_FSC; } + void gsc(ulong x) { if(x) attr2 |= GATTR_GSC; else attr2 &= ~GATTR_GSC; } + void rsc(ulong x) { if(x) attr2 |= GATTR_RSC; else attr2 &= ~GATTR_RSC; } + void trt(ulong x) { if(x) attr2 |= GATTR_TRT; else attr2 &= ~GATTR_TRT; } + + void lzs(ulong x) { if(x) attr2 |= GATTR_LZS; else attr2 &= ~GATTR_LZS; } + void arc(ulong x) { if(x) attr2 |= GATTR_ARC; else attr2 &= ~GATTR_ARC; } + void tag(ulong x) { if(x) attr2 |= GATTR_TAG; else attr2 &= ~GATTR_TAG; } + void rab(ulong x) { if(x) attr2 |= GATTR_RAB; else attr2 &= ~GATTR_RAB; } + + void car(ulong x) { if(x) attr2 |= GATTR_CAR; else attr2 &= ~GATTR_CAR; } + void fwd(ulong x) { if(x) attr2 |= GATTR_FWD; else attr2 &= ~GATTR_FWD; } + void efl(ulong x) { if(x) attr2 |= GATTR_EFL; else attr2 &= ~GATTR_EFL; } + void hrp(ulong x) { if(x) attr2 |= GATTR_HRP; else attr2 &= ~GATTR_HRP; } + + // ------------------------------------------------------------- + + void pvt0() { attr1 &= ~GATTR_PVT; } + void cra0() { attr1 &= ~GATTR_CRA; } + void rcv0() { attr1 &= ~GATTR_RCV; } + void snt0() { attr1 &= ~GATTR_SNT; } + + void att0() { attr1 &= ~GATTR_ATT; } + void trs0() { attr1 &= ~GATTR_TRS; } + void orp0() { attr1 &= ~GATTR_ORP; } + void k_s0() { attr1 &= ~GATTR_K_S; } + + void loc0() { attr1 &= ~GATTR_LOC; } + void hld0() { attr1 &= ~GATTR_HLD; } + void rsv0() { attr1 &= ~GATTR_RSV; } + void frq0() { attr1 &= ~GATTR_FRQ; } + + void rrq0() { attr1 &= ~GATTR_RRQ; } + void rrc0() { attr1 &= ~GATTR_RRC; } + void arq0() { attr1 &= ~GATTR_ARQ; } + void urq0() { attr1 &= ~GATTR_URQ; } + + void grp0() { attr1 &= ~GATTR_GRP; } + void imm0() { attr1 &= ~GATTR_IMM; } + void dir0() { attr1 &= ~GATTR_DIR; } + void tfs0() { attr1 &= ~GATTR_TFS; } + + void kfs0() { attr1 &= ~GATTR_KFS; } + void lok0() { attr1 &= ~GATTR_LOK; } + void a_s0() { attr1 &= ~GATTR_A_S; } + void zon0() { attr1 &= ~GATTR_ZON; } + + void hub0() { attr1 &= ~GATTR_HUB; } + void xma0() { attr1 &= ~GATTR_XMA; } + void cfm0() { attr1 &= ~GATTR_CFM; } + void hir0() { attr1 &= ~GATTR_HIR; } + + void cov0() { attr1 &= ~GATTR_COV; } + void sig0() { attr1 &= ~GATTR_SIG; } + void let0() { attr1 &= ~GATTR_LET; } + void uns0() { attr1 &= ~GATTR_UNS; } + + void del0() { attr2 &= ~GATTR_DEL; } + void nwm0() { attr2 &= ~GATTR_NWM; } + void rot0() { attr2 &= ~GATTR_ROT; } + void hex0() { attr2 &= ~GATTR_HEX; } + + void upd0() { attr2 &= ~GATTR_UPD; } + void tou0() { attr2 &= ~GATTR_TOU; } + void fmu0() { attr2 &= ~GATTR_FMU; } + void scn0() { attr2 &= ~GATTR_SCN; } + + void pos0() { attr2 &= ~GATTR_POS; } + void r_o0() { attr2 &= ~GATTR_R_O; } + void nok0() { attr2 &= ~GATTR_NOK; } + void fax0() { attr2 &= ~GATTR_FAX; } + + void prn0() { attr2 &= ~GATTR_PRN; } + + // ---------------------------------------------------------------- + + void pvt1() { attr1 |= GATTR_PVT; } + void cra1() { attr1 |= GATTR_CRA; } + void rcv1() { attr1 |= GATTR_RCV; } + void snt1() { attr1 |= GATTR_SNT; } + + void att1() { attr1 |= GATTR_ATT; } + void trs1() { attr1 |= GATTR_TRS; } + void orp1() { attr1 |= GATTR_ORP; } + void k_s1() { attr1 |= GATTR_K_S; } + + void loc1() { attr1 |= GATTR_LOC; } + void hld1() { attr1 |= GATTR_HLD; } + void rsv1() { attr1 |= GATTR_RSV; } + void frq1() { attr1 |= GATTR_FRQ; } + + void rrq1() { attr1 |= GATTR_RRQ; } + void rrc1() { attr1 |= GATTR_RRC; } + void arq1() { attr1 |= GATTR_ARQ; } + void urq1() { attr1 |= GATTR_URQ; } + + void grp1_() { attr1 |= GATTR_GRP; } + void imm1() { attr1 |= GATTR_IMM; } + void dir1() { attr1 |= GATTR_DIR; } + void tfs1() { attr1 |= GATTR_TFS; } + + void kfs1() { attr1 |= GATTR_KFS; } + void lok1() { attr1 |= GATTR_LOK; } + void a_s1() { attr1 |= GATTR_A_S; } + void zon1() { attr1 |= GATTR_ZON; } + + void hub1() { attr1 |= GATTR_HUB; } + void xma1() { attr1 |= GATTR_XMA; } + void cfm1() { attr1 |= GATTR_CFM; } + void hir1() { attr1 |= GATTR_HIR; } + + void cov1() { attr1 |= GATTR_COV; } + void sig1() { attr1 |= GATTR_SIG; } + void let1() { attr1 |= GATTR_LET; } + void uns1() { attr1 |= GATTR_UNS; } + + void del1() { attr2 |= GATTR_DEL; } + void nwm1() { attr2 |= GATTR_NWM; } + void rot1() { attr2 |= GATTR_ROT; } + void hex1() { attr2 |= GATTR_HEX; } + + void upd1() { attr2 |= GATTR_UPD; } + void tou1() { attr2 |= GATTR_TOU; } + void fmu1() { attr2 |= GATTR_FMU; } + void scn1() { attr2 |= GATTR_SCN; } + + void pos1() { attr2 |= GATTR_POS; } + void r_o1() { attr2 |= GATTR_R_O; } + void nok1() { attr2 |= GATTR_NOK; } + void fax1() { attr2 |= GATTR_FAX; } + + void prn1() { attr2 |= GATTR_PRN; } + + // ---------------------------------------------------------------- + + void pvtX() { attr1 ^= GATTR_PVT; } + void craX() { attr1 ^= GATTR_CRA; } + void rcvX() { attr1 ^= GATTR_RCV; } + void sntX() { attr1 ^= GATTR_SNT; } + + void attX() { attr1 ^= GATTR_ATT; } + void trsX() { attr1 ^= GATTR_TRS; } + void orpX() { attr1 ^= GATTR_ORP; } + void k_sX() { attr1 ^= GATTR_K_S; } + + void locX() { attr1 ^= GATTR_LOC; } + void hldX() { attr1 ^= GATTR_HLD; } + void rsvX() { attr1 ^= GATTR_RSV; } + void frqX() { attr1 ^= GATTR_FRQ; } + + void rrqX() { attr1 ^= GATTR_RRQ; } + void rrcX() { attr1 ^= GATTR_RRC; } + void arqX() { attr1 ^= GATTR_ARQ; } + void urqX() { attr1 ^= GATTR_URQ; } + + void grpX() { attr1 ^= GATTR_GRP; } + void immX() { attr1 ^= GATTR_IMM; } + void dirX() { attr1 ^= GATTR_DIR; } + void tfsX() { attr1 ^= GATTR_TFS; } + + void kfsX() { attr1 ^= GATTR_KFS; } + void lokX() { attr1 ^= GATTR_LOK; } + void a_sX() { attr1 ^= GATTR_A_S; } + void zonX() { attr1 ^= GATTR_ZON; } + + void hubX() { attr1 ^= GATTR_HUB; } + void xmaX() { attr1 ^= GATTR_XMA; } + void cfmX() { attr1 ^= GATTR_CFM; } + void hirX() { attr1 ^= GATTR_HIR; } + + void covX() { attr1 ^= GATTR_COV; } + void sigX() { attr1 ^= GATTR_SIG; } + void letX() { attr1 ^= GATTR_LET; } + void unsX() { attr1 ^= GATTR_UNS; } + + void delX() { attr2 ^= GATTR_DEL; } + void nwmX() { attr2 ^= GATTR_NWM; } + void rotX() { attr2 ^= GATTR_ROT; } + void hexX() { attr2 ^= GATTR_HEX; } + + void updX() { attr2 ^= GATTR_UPD; } + void touX() { attr2 ^= GATTR_TOU; } + void fmuX() { attr2 ^= GATTR_FMU; } + void scnX() { attr2 ^= GATTR_SCN; } + + void posX() { attr2 ^= GATTR_POS; } + void r_oX() { attr2 ^= GATTR_R_O; } + void nokX() { attr2 ^= GATTR_NOK; } + void faxX() { attr2 ^= GATTR_FAX; } + + void prnX() { attr2 ^= GATTR_PRN; } + +}; + + +// ------------------------------------------------------------------ + +typedef ftn_attr Attr; + + +// ------------------------------------------------------------------ + +inline void AttrAdd(Attr* a, Attr* b) { a->add(*b); } +inline void GetAttribstr(Attr* attr, const char* attrs) { attr->get(attrs); } +inline char* MakeAttrStr(char* str, const Attr* attr) { string tmp; attr->make_string(tmp); strcpy(str, tmp.c_str()); return str; } + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gprnall.h b/goldlib/gall/gprnall.h new file mode 100644 index 0000000..0841456 --- /dev/null +++ b/goldlib/gall/gprnall.h @@ -0,0 +1,41 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Printer functions. +// ------------------------------------------------------------------ + +#ifndef __gprnall_h +#define __gprnall_h + + +// ------------------------------------------------------------------ + +char* CvtPrnstr(char* str, char* prn); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gprnutil.cpp b/goldlib/gall/gprnutil.cpp new file mode 100644 index 0000000..c3935f6 --- /dev/null +++ b/goldlib/gall/gprnutil.cpp @@ -0,0 +1,88 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// GoldED printer definition helper. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// Convert printer definition string to binary codes + +char* CvtPrnstr(char* str, char* prn) { + + int value; + byte len=0; + char buf[256]; + char* ptr=prn; + + while(*ptr) { + switch(*ptr) { + case '$': + ptr++; + do { + sscanf(ptr, "%2x", &value); + buf[len++] = (byte)value; + if(isxdigit(*ptr) and *ptr) // Skip first digit + ptr++; + if(isxdigit(*ptr) and *ptr) // Skip second digit + ptr++; + } while(isxdigit(*ptr) and *ptr); + break; + case '#': + ptr++; + value = atoi(ptr); + buf[len++] = (byte)value; + while(isdigit(*ptr) and *ptr) + ptr++; + break; + case '\"': + ptr++; + while(*ptr != '\"' and *ptr) + buf[len++] = *ptr++; + if(*ptr) + ptr++; + break; + case '\'': + ptr++; + while(*ptr != '\'' and *ptr) + buf[len++] = *ptr++; + if(*ptr) + ptr++; + break; + default: + ptr++; + } + } + + *str = len; + memcpy(str+1, buf, len); + + return str; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gregex.cpp b/goldlib/gall/gregex.cpp new file mode 100644 index 0000000..504badf --- /dev/null +++ b/goldlib/gall/gregex.cpp @@ -0,0 +1,91 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Regular expressions C++ wrapper class. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +gregex::gregex() { + + preg = NULL; +} + + +// ------------------------------------------------------------------ + +gregex::~gregex() { + + reset(); +} + + +// ------------------------------------------------------------------ + +void gregex::reset() { + + if(preg) { + regfree((regex_t*)preg); + throw_delete((regex_t*)preg); + } +} + + +// ------------------------------------------------------------------ + +bool gregex::compile(const char* pattern, int cflags) { + + int cflgs = REG_NOSUB; + if(cflags & extended) cflgs |= REG_EXTENDED; + if(cflags & icase) cflgs |= REG_ICASE; + if(cflags & newline) cflgs |= REG_NEWLINE; + + if(not preg) { + preg = new regex_t; + throw_new(preg); + } + + return (bool)regcomp((regex_t*)preg, pattern, cflgs); +} + + +// ------------------------------------------------------------------ + +bool gregex::match(const char* str, int eflags) { + + int eflgs = 0; + if(eflags & notbol) eflgs |= REG_NOTBOL; + if(eflags & noteol) eflgs |= REG_NOTEOL; + + return not regexec((regex_t*)preg, str, 0, NULL, eflgs); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gregex.h b/goldlib/gall/gregex.h new file mode 100644 index 0000000..34f8a84 --- /dev/null +++ b/goldlib/gall/gregex.h @@ -0,0 +1,73 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Regular expressions C++ wrapper class. +// ------------------------------------------------------------------ + +#ifndef __gregex_h +#define __gregex_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class gregex { + +protected: + + void* preg; + +public: + + enum { + + // cflags + extended = 0x01, + icase = 0x02, + newline = 0x04, + + // eflags + notbol = 0x10, + noteol = 0x20 + }; + + gregex(); + ~gregex(); + + void reset(); + + bool compile(const char* pattern, int cflags=0); + bool match(const char* str, int eflags=0); + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsearch.cpp b/goldlib/gall/gsearch.cpp new file mode 100644 index 0000000..18b62e6 --- /dev/null +++ b/goldlib/gall/gsearch.cpp @@ -0,0 +1,169 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Search with different methods. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +gsearch::gsearch() { + + regexp = NULL; + fuzzyp = NULL; + plainp = NULL; + type = plain; + case_sensitive = false; + reverse = false; + fuzzydegree = 1; + score_success = 1; + score_failure = 0; + score = 0; + found = false; +} + + +// ------------------------------------------------------------------ + +gsearch::~gsearch() { + + delete regexp; + delete fuzzyp; + delete plainp; +} + + +// ------------------------------------------------------------------ + +void gsearch::set_pattern(const char* a) { + + delete regexp; regexp = NULL; + delete fuzzyp; fuzzyp = NULL; + delete plainp; plainp = NULL; + + pattern = a; +} + + +// ------------------------------------------------------------------ + +bool gsearch::search(const string& str) { + + int discard_result; + return search(str, discard_result); +} + + +// ------------------------------------------------------------------ + +bool gsearch::search(const string& str, int& result) { + + return search(str.c_str(), result); +} + + +// ------------------------------------------------------------------ + +bool gsearch::search(const char* str) { + + int discard_result; + return search(str, discard_result); +} + + +// ------------------------------------------------------------------ + +bool gsearch::search(const char* str, int& result) { + + found = false; + + switch(type) { + + case regex: + if(regexp == NULL) { + regexp = new gregex; + throw_new(regexp); + regexp->compile(pattern.c_str(), gregex::extended | (case_sensitive ? 0 : gregex::icase)); + } + found = regexp->match(str); + break; + + case wildcard: + found = gwildmat(str, pattern.c_str(), not case_sensitive); + break; + + case fuzzy: + if(fuzzyp == NULL) { + fuzzyp = new gfuzzy; + throw_new(fuzzyp); + fuzzyp->init(pattern.c_str(), fuzzydegree, case_sensitive); + } + found = fuzzyp->findfirst(str); + break; + + case plain: + if(plainp == NULL) { + plainp = new gbmh; + throw_new(plainp); + plainp->init(pattern.c_str(), not case_sensitive); + } + found = plainp->find(str); + break; + } + + if(reverse) + score = score_failure; + else + score = score_success; + result = score; + return found; +} + + +// ------------------------------------------------------------------ + +gsearch& gsearch::operator=(const gsearch& a) { + + regexp = NULL; + fuzzyp = NULL; + plainp = NULL; + id = a.id; + pattern = a.pattern; + type = a.type; + case_sensitive = a.case_sensitive; + reverse = a.reverse; + score_success = a.score_success; + score_failure = a.score_failure; + + return *this; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsearch.h b/goldlib/gall/gsearch.h new file mode 100644 index 0000000..9969b1e --- /dev/null +++ b/goldlib/gall/gsearch.h @@ -0,0 +1,106 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Search. +// ------------------------------------------------------------------ + +#ifndef __gsearch_h +#define __gsearch_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class gregex; +class gfuzzy; +class gbmh; + + +// ------------------------------------------------------------------ + +class gsearch { + +public: + + enum patterntype { + regex, // Extended regular expressions + wildcard, // Shell-style with wildcards + fuzzy, // Fuzzy matching + plain // Plain BMH match + }; + +protected: + + class gregex* regexp; + class gfuzzy* fuzzyp; + class gbmh* plainp; + +public: + + // Configuration + string id; + string pattern; + patterntype type; + bool case_sensitive; + bool reverse; + int fuzzydegree; + int score_success; + int score_failure; + + gsearch(); + virtual ~gsearch(); + + void set_id(const char* a) { id = a; } + void set_type(patterntype a) { type = a; } + void set_pattern(const char* a); + void set_case_sensitive(bool a) { case_sensitive = a; } + void set_reverse(bool a) { reverse = a; } + void set_fuzzydegree(int a) { fuzzydegree = a; } + void set_score_success(int a) { score_success = a; } + void set_score_failure(int a) { score_failure = a; } + + // Result of last search + bool found; + int score; + + // Search a string for the pattern. + // Return true for success, false for failure. + bool search(const char* string); + bool search(const string& str); + bool search(const char* str, int& result); + bool search(const string& str, int& result); + + gsearch& operator=(const gsearch& a); + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gshare.h b/goldlib/gall/gshare.h new file mode 100644 index 0000000..a6bbe7d --- /dev/null +++ b/goldlib/gall/gshare.h @@ -0,0 +1,66 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gshare_h +#define __gshare_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if not defined(__GNUC__) or defined(__DJGPP__) or defined(__EMX__) or defined(__MINGW32__) +#include +#if defined(__MINGW32__) // SH_COMPAT doesn't work in Mingw32 +#undef SH_COMPAT +#endif +#elif defined(__CYGWIN__) +#define SH_DENYRW 0x10 // Deny read/write +#define SH_DENYWR 0x20 // Deny write +#define SH_DENYRD 0x30 // Deny read +#define SH_DENYNO 0x40 // Deny nothing +#else +#ifndef SH_DENYNO +#define SH_DENYNO 0 +#define SH_DENYRD 0 +#define SH_DENYWR 0 +#define SH_DENYRW 0 +#define SH_COMPAT 0 +#endif +#endif + +#ifndef SH_COMPAT +#define SH_COMPAT SH_DENYNO +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsigunix.cpp b/goldlib/gall/gsigunix.cpp new file mode 100644 index 0000000..8ce5b25 --- /dev/null +++ b/goldlib/gall/gsigunix.cpp @@ -0,0 +1,82 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Unix signal functions. Based on SLang source. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// We are primarily interested in blocking signals that would cause +// the application to reset the tty. These include suspend signals +// and possibly interrupt signals. + +static sigset_t gsig_old_signal_mask; +static volatile uint gsig_blocked_depth; + + +// ------------------------------------------------------------------ + +int gsig_block_signals() { + + sigset_t new_mask; + + gsig_blocked_depth++; + if(gsig_blocked_depth != 1) + return 0; + + sigemptyset(&new_mask); + sigaddset(&new_mask, SIGINT); + sigaddset(&new_mask, SIGQUIT); + #ifdef SIGTSTP + sigaddset(&new_mask, SIGTSTP); + sigaddset(&new_mask, SIGTTIN); + sigaddset(&new_mask, SIGTTOU); + #endif + + sigprocmask(SIG_BLOCK, &new_mask, &gsig_old_signal_mask); + return 0; +} + + +// ------------------------------------------------------------------ + +int gsig_unblock_signals() { + + if(gsig_blocked_depth == 0) + return -1; + + gsig_blocked_depth--; + + if(gsig_blocked_depth != 0) + return 0; + + sigprocmask(SIG_SETMASK, &gsig_old_signal_mask, NULL); + return 0; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsigunix.h b/goldlib/gall/gsigunix.h new file mode 100644 index 0000000..6c771cd --- /dev/null +++ b/goldlib/gall/gsigunix.h @@ -0,0 +1,46 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Unix signal functions. Based on SLang source. +// ------------------------------------------------------------------ + +#ifndef __gsigunix_h +#define __gsigunix_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +int gsig_block_signals(); +int gsig_unblock_signals(); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsnd.cpp b/goldlib/gall/gsnd.cpp new file mode 100644 index 0000000..4e9ed83 --- /dev/null +++ b/goldlib/gall/gsnd.cpp @@ -0,0 +1,494 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Sound class. +// ------------------------------------------------------------------ + +#include +#include +#include + +#if defined(__MSDOS__) +#include +#include +#endif + +#include +#include +#include + +// ------------------------------------------------------------------ + +#ifdef DEBUG +int debug = false; +#endif + + +// ------------------------------------------------------------------ + +gsnd::gsnd() { + + #if defined(__MSDOS__) + mpx = -1; + #if (defined(__WATCOMC__) and defined(__386__)) or defined(__DJGPP__) + buffer = -1; + #else + buffer = NULL; + #endif + data = NULL; + #endif + + api_open = false; + file_open = false; +} + + +// ------------------------------------------------------------------ + +gsnd::~gsnd() { + + if(api_open) + close_api(); + + free_buffer(); +} + + +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) +int gsnd::call_api(uint al, uint bx) { + + if(api_open) { + i86 cpu; + cpu.al(al); + cpu.ah(mpx); + cpu.bx(bx); + cpu.genint(0x2D); + return (int)cpu.ax(); + } + return 0; +} +#endif + + +// ------------------------------------------------------------------ + +void gsnd::free_buffer() { + + #if defined(__MSDOS__) + #if defined(__DJGPP__) or (defined(__WATCOMC__) and defined(__386__)) + if(buffer != -1) { + __dpmi_free_dos_memory(buffer); + buffer = -1; + } + #else + if(buffer) { + farfree(buffer); + buffer = NULL; + } + #endif + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::open_api() { + + #if defined(__MSDOS__) + + i86 cpu; + + // Installation check + for(mpx=0; mpx<256; mpx++) { + cpu.ah(mpx); + cpu.al(GSAPI_INSTALL_CHECK); + cpu.genint(0x2D); + if(cpu.al() == 0xFF) { + #ifdef DEBUG + if(debug) printf("gsnd: examining signature at %04X:%04X for mpx %u\n", cpu.dx(), cpu.di(), mpx); + #endif + amis_signature* signature = (amis_signature*)gmkfp(cpu.dx(), cpu.di()); + #ifdef DEBUG + if(debug) printf("gsnd: version is %04X\n", cpu.cx()); + if(debug) printf("gsnd: manufacturer is \"%8.8s\"\n", signature->manufacturer); + if(debug) printf("gsnd: product name is \"%8.8s\"\n", signature->product_name); + if(debug) printf("gsnd: description is \"%s\"\n", signature->product_description); + #endif + if((cpu.cx() >= 0x0100) and (cpu.cx() < 0x0200)) + if(strnieql(signature->product_name, "GoldSAPI", 8)) + break; + } + } + + // Return if not installed + if(mpx >= 256) { + mpx = -1; + return -1; + } + + // Call the open api function + cpu.al(GSAPI_OPEN_API); + cpu.ah(mpx); + cpu.genint(0x2D); + if(cpu.al()) { + #ifdef DEBUG + if(debug) printf("gsnd: open api returned %02Xh\n", cpu.al()); + #endif + return cpu.al(); + } + #ifdef DEBUG + if(debug) printf("gsnd: using data at %04X:%04X, length %u\n", cpu.dx(), cpu.di(), cpu.cx()); + #endif + data = (gsapidata*)gmkfp(cpu.dx(), cpu.di()); + key_value = cpu.bx(); + + api_open = true; + return 0; + + #elif defined(GUTLOS_FUNCS) + + api_open = true; + return 0; + + #else + + api_open = false; + return -1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::close_api() { + + #if defined(__MSDOS__) + + return call_api(GSAPI_CLOSE_API, key_value); + + #elif defined(GUTLOS_FUNCS) + + if(api_open) { + + if(file_open) + close(); + + api_open = false; + } + + return 0; + + #else + + return -1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::open(const char* file) { + + #if defined(__MSDOS__) + + strcpy(data->parameters, file); + + try_again: + int retval = call_api(GSAPI_OPEN_AND_LOAD_FILE); + switch(retval) { + case 0x01: + close(); + goto try_again; + case 0x02: + free_buffer(); + #if defined(__DJGPP__) or (defined(__WATCOMC__) and defined(__386__)) + if((data->buffer_segment = __dpmi_allocate_dos_memory((data->buffer_length >> 4) + 1, &buffer)) == -1) + return -1; + data->buffer_offset = 0; + #else + buffer = (char*)farmalloc(data->buffer_length); + if(buffer == NULL) + return false; + data->buffer_segment = FP_SEG(buffer); + data->buffer_offset = FP_OFF(buffer); + #endif + retval = call_api(GSAPI_OPEN_AND_LOAD_FILE); + } + + if(retval == 0) + file_open = true; + + #ifdef DEBUG + if(debug) printf("gsnd::open: retval = %04X\n", retval); + #endif + + return retval; + + #elif defined(GUTLOS_FUNCS) + + if(file_open) + close(); + + char buf[_MAX_PATH]; + sprintf(buf, "open %s alias noise wait", file); + if(g_send_mci_string(buf, NULL)) { + file_open = true; + return 0; + } + return -1; + + #else + + NW(file); + return -1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::close() { + + #if defined(__MSDOS__) + + if(file_open) { + file_open = false; + return call_api(GSAPI_CLOSE_FILE); + } + return 1; + + #elif defined(GUTLOS_FUNCS) + + if(file_open) { + g_send_mci_string("close noise wait", NULL); + file_open = false; + return 0; + } + return 0xFFFF; + + #else + + return 0xFFFF; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::play(uint sample_rate) { + + #if defined(__MSDOS__) + + return file_open ? call_api(GSAPI_PLAY, sample_rate) : 1; + + #elif defined(GUTLOS_FUNCS) + + NW(sample_rate); + + if(file_open) { + g_send_mci_string("seek noise to start", NULL); + g_send_mci_string("play noise", NULL); + return 0; + } + return 1; + + #else + + NW(sample_rate); + return 1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::stop() { + + #if defined(__MSDOS__) + + return file_open ? call_api(GSAPI_STOP) : 1; + + #elif defined(GUTLOS_FUNCS) + + if(file_open) { + g_send_mci_string("stop noise wait", NULL); + return 0; + } + return 1; + + #else + + return 1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::pause() { + + #if defined(__MSDOS__) + + return file_open ? call_api(GSAPI_PAUSE) : 1; + + #elif defined(GUTLOS_FUNCS) + + if(file_open) { + g_send_mci_string("pause noise", NULL); + return 0; + } + return 1; + + #else + + return 1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::resume() { + + #if defined(__MSDOS__) + + return file_open ? call_api(GSAPI_RESUME) : 1; + + #elif defined(GUTLOS_FUNCS) + + if(file_open) { + g_send_mci_string("resume noise", NULL); + return 0; + } + return 1; + + #else + + return 1; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::break_loop(int method) { + + #if defined(__MSDOS__) + + return file_open ? call_api(GSAPI_BREAK_LOOP, method) : 1; + + #elif defined(GUTLOS_FUNCS) + + NW(method); + return 0xFFFF; + + #else + + NW(method); + return 0xFFFF; + + #endif +} + + + +// ------------------------------------------------------------------ + +void gsnd::speaker(int onoff) { + + #if defined(__MSDOS__) + + call_api(GSAPI_SPEAKER_ON_OFF, onoff ? 1 : 0); + + #elif defined(GUTLOS_FUNCS) + + // Not implemented + NW(onoff); + + #else + + NW(onoff); + + #endif +} + + +// ------------------------------------------------------------------ + +uint gsnd::get_sample_rate() { + + #if defined(__MSDOS__) + + return file_open ? data->sample_rate : 0; + + #elif defined(GUTLOS_FUNCS) + + return 0; + + #else + + return 0; + + #endif +} + + +// ------------------------------------------------------------------ + +int gsnd::is_playing() { + + #if defined(__MSDOS__) + + if(file_open) + return (int)data->status; + return false; + + #elif defined(GUTLOS_FUNCS) + + char return_buffer[BUFFERSIZE]; + + if(g_send_mci_string("status noise mode wait", return_buffer)) + return strieql(return_buffer, "playing") or strieql(return_buffer, "seeking"); + return 0; + + #else + + return 0; + + #endif +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gsndall.h b/goldlib/gall/gsndall.h new file mode 100644 index 0000000..c0c0da9 --- /dev/null +++ b/goldlib/gall/gsndall.h @@ -0,0 +1,129 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Sound interface class. +// ------------------------------------------------------------------ + +#ifndef __gsndall_h +#define __gsndall_h + + +// ------------------------------------------------------------------ + +#include +#ifdef __OS2__ +#define INCL_BASE +#include +#endif +#ifdef __WIN32__ +#include +#endif + + +// ------------------------------------------------------------------ + +#ifdef DEBUG +extern int debug; +#endif + + +// ------------------------------------------------------------------ + +class gsnd { + +protected: + + #if defined(__MSDOS__) + int mpx; + #if defined(__DJGPP__) or (defined(__WATCOMC__) and defined(__386__)) + int buffer; + #else + char* buffer; + #endif + gsapidata* data; + uint key_value; + int call_api(uint al, uint bx=0); + #endif + + int api_open; + int file_open; + + void free_buffer(); + +public: + + gsnd(); + ~gsnd(); + + // API open/close + int open_api(); + int close_api(); + + // Sound file open/close + int open(const char* file); + int close(); + + // Sound play and control + int play(uint sample_rate=0); + int stop(); + int pause(); + int resume(); + int break_loop(int method=0); + void speaker(int onoff); + + // Information + uint get_sample_rate(); + int api_is_open() { return api_open; } + int is_playing(); +}; + + +// ------------------------------------------------------------------ + +class gsound { + +protected: + + int installed; + +public: + + gsound(); + ~gsound(); + + int load(const char* file); + int unload(); + int play(); + int stop(); + + int is_playing(); + + int is_installed() { return installed; } +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsndsapi.h b/goldlib/gall/gsndsapi.h new file mode 100644 index 0000000..1696461 --- /dev/null +++ b/goldlib/gall/gsndsapi.h @@ -0,0 +1,83 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __g_sapi_h +#define __g_sapi_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Goldware Sound API version + +#define GSAPI_VERSION 0x0100 + + +// ------------------------------------------------------------------ +// Goldware Sound API functions + +#define GSAPI_INSTALL_CHECK 0x00 +#define GSAPI_OPEN_API 0x10 +#define GSAPI_CLOSE_API 0x11 +#define GSAPI_OPEN_AND_LOAD_FILE 0x12 +#define GSAPI_CLOSE_FILE 0x13 +#define GSAPI_PLAY 0x14 +#define GSAPI_STOP 0x15 +#define GSAPI_PAUSE 0x16 +#define GSAPI_RESUME 0x17 +#define GSAPI_BREAK_LOOP 0x18 +#define GSAPI_SPEAKER_ON_OFF 0x19 + + +// ------------------------------------------------------------------ +// Goldware Sound API data structure + +struct gsapidata { + word driver_version; + word dsp_version; + word io_port; + byte irq_number; + byte dma_channel; + word sample_rate; + volatile word status; +#if defined(__DJGPP__) or (defined(__WATCOMC__) and defined(__386__)) + int buffer_segment; + int buffer_offset; +#else + word buffer_segment; + word buffer_offset; +#endif + long buffer_length; + char parameters[80]; +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsndwrap.cpp b/goldlib/gall/gsndwrap.cpp new file mode 100644 index 0000000..2aa1eb5 --- /dev/null +++ b/goldlib/gall/gsndwrap.cpp @@ -0,0 +1,94 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Sound interface class. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +static gsnd* snd = NULL; + + +// ------------------------------------------------------------------ + +gsound::gsound() { + + snd = new gsnd; + installed = (snd->open_api() != -1); +} + + +// ------------------------------------------------------------------ + +gsound::~gsound() { + + snd->close_api(); + delete snd; +} + + +// ------------------------------------------------------------------ + +int gsound::load(const char* file) { + + return snd->open(file); +} + + +// ------------------------------------------------------------------ + +int gsound::unload() { + + return snd->close(); +} + + +// ------------------------------------------------------------------ + +int gsound::play() { + + return snd->play(); +} + + +// ------------------------------------------------------------------ + +int gsound::stop() { + + return snd->stop(); +} + + +// ------------------------------------------------------------------ + +int gsound::is_playing() { + + return snd->is_playing(); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsrchmgr.cpp b/goldlib/gall/gsrchmgr.cpp new file mode 100644 index 0000000..6a09d05 --- /dev/null +++ b/goldlib/gall/gsrchmgr.cpp @@ -0,0 +1,94 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Search manager. +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +search_item::search_item() { + + logic = logic_or; + + where.from = false; + where.to = false; + where.subject = false; + where.body = false; + where.tagline = false; + where.tearline = false; + where.origin = false; + where.signature = false; + where.kludges = false; +} + + +// ------------------------------------------------------------------ + +search_item::~search_item() { + +} + + +// ------------------------------------------------------------------ + +search_item& search_item::operator=(const search_item& a) { + + gsearch::operator=(a); + + logic = a.logic; + where.from = a.where.from; + where.to = a.where.to; + where.subject = a.where.subject; + where.body = a.where.body; + where.tagline = a.where.tagline; + where.tearline = a.where.tearline; + where.origin = a.where.origin; + where.signature = a.where.signature; + where.kludges = a.where.kludges; + + return *this; +} + + +// ------------------------------------------------------------------ + +search_manager::search_manager() : gwinput2(window) { + + direction = direction_forward; + messages = messages_new; + action = action_read; + areas = areas_current; +} + + +// ------------------------------------------------------------------ + +search_manager::~search_manager() { + +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gsrchmgr.h b/goldlib/gall/gsrchmgr.h new file mode 100644 index 0000000..d6f1651 --- /dev/null +++ b/goldlib/gall/gsrchmgr.h @@ -0,0 +1,142 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Search manager. +// ------------------------------------------------------------------ + +#ifndef __gsrchmgr_h +#define __gsrchmgr_h + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +class search_item : public gsearch { + +public: + + enum item_logic { + logic_and, + logic_or + }; + + struct item_where { + bool from; + bool to; + bool subject; + bool body; + bool tagline; + bool tearline; + bool origin; + bool signature; + bool kludges; + }; + + item_logic logic; + item_where where; + + search_item(); + virtual ~search_item(); + + search_item& operator=(const search_item& a); + +}; + + +// ------------------------------------------------------------------ + +class search_manager : public gwinput2 { + +public: + + enum { + if_nothing, + id_pattern1, id_logic1, id_options1, + id_pattern2, id_logic2, id_options2, + id_pattern3, id_logic3, id_options3, + id_pattern4, id_logic4, id_options4, + id_pattern5, id_logic5, id_options5, + id_pattern6, id_logic6, id_options6, + id_pattern7, id_logic7, id_options7, + id_pattern8, id_logic8, id_options8, + id_pattern9, id_logic9, id_options9, + id_direction, + id_messages, + id_action, + id_areas + }; + + enum search_direction { + direction_backward, + direction_forward + }; + + enum search_messages { + messages_new, + messages_unread, + messages_all + }; + + enum search_action { + action_read, + action_mark, + action_delete, + action_write, + action_copy, + action_move + }; + + enum search_areas { + areas_current, + areas_tagged, + areas_all + }; + + vector items; + + search_direction direction; + search_messages messages; + search_action action; + search_areas areas; + + gwindow window; + + search_manager(); + virtual ~search_manager(); + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrall.h b/goldlib/gall/gstrall.h new file mode 100644 index 0000000..43c4751 --- /dev/null +++ b/goldlib/gall/gstrall.h @@ -0,0 +1,164 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// String manipulation functions. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GSTRALL_H +#define __GSTRALL_H + + +// ------------------------------------------------------------------ +// Required headers + +#include +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(__EMX__) +#include +#define strupr(s) (char *)_nls_strupr((unsigned char *)(s)) +#define strlwr(s) (char *)_nls_strlwr((unsigned char *)(s)) +#elif defined(__GNUC__) +#define stricmp strcasecmp +#define strnicmp strncasecmp +char* strupr(char* s); +char* strlwr(char* s); +#endif + + +// ------------------------------------------------------------------ +// Function prototypes + +bool strblank(const char* str); +int strchg(char* str, char oldch, char newch); +char* stridela(const char* substr, char* str); +int strnicmpw(const char* str1, const char* str2, int len); +const char* striinc(const char* str1, const char* str2); +char* strins(const char* instr, char* str, int st_pos); +char* strischg(char* str, const char* find, const char* replace); +char* strrjust(char* str); +char* strschg(char* str, const char* find, const char* replace); +char* strsetsz(char* str, int newsize); +char* strshl(char* str, int count); +char* strshr(char* str, int count); +char* strsrep(char* str, const char* search, const char* replace); +char* strltrim(char* str); +char* strtrim(char* str); +char* struplow(char* str); + +char* longdotstr(long num); // Convert a long to a dotted string: xxx.xxx.xxx.xxx +char* longdotstr(char* str, long num); // Convert a long to a dotted string: xxx.xxx.xxx.xxx +char* StripQuotes(char* str); + +// Safe versions of strcpy, strcat, sequencial strcat... +char* strxcpy(char* d, const char* s, int n); +char* strxcat(char *dest, const char *src, size_t max); +char* strxmerge(char *dest, size_t max, ...); + +char* strc2p(char* str); +char* strnp2c(char* str, int n); +char* strnp2cc(char* dest, const char* str, int n); +char* strp2c(char* str); + +const char* strlword(const char* str); +const char* strrword(const char* str); + +char* strrevname(char* reversedname, const char* name); +char* strunrevname(char* unreversedname, const char* name); + + +// ------------------------------------------------------------------ +// Inliners + +#define STRNP2C(str) strnp2c(str, sizeof(str)-1) + +inline char* strbtrim(char* st) { return strtrim(strltrim(st)); } + +inline bool streql(const char* str1, const char* str2) { return not strcmp(str1,str2); } +inline bool strieql(const char* str1, const char* str2) { return not stricmp(str1,str2); } +inline bool strneql(const char* str1, const char* str2, int n) { return not strncmp(str1,str2,n); } +inline bool strnieql(const char* str1, const char* str2, int n) { return not strnicmp(str1,str2,n); } + +inline const char* strskip_to(const char* p, char* s) { return p+strcspn(p, s); } +inline char* strskip_to(char* p, char* s) { return p+strcspn(p, s); } + +inline const char* strskip_to(const char* p, char c) { while((*p != c) and *p) p++; return p; } +inline char* strskip_to(char* p, char c) { while((*p != c) and *p) p++; return p; } + +inline const char* strskip_txt(const char* p) { while(*p and not isspace(*p)) p++; return p; } +inline char* strskip_txt(char* p) { while(*p and not isspace(*p)) p++; return p; } + +inline const char* strskip_wht(const char* p) { while(*p and isspace(*p)) p++; return p; } +inline char* strskip_wht(char* p) { while(*p and isspace(*p)) p++; return p; } + +inline const char* strskip_digits(const char* p) { return p+strspn(p, "0123456789"); } +inline char* strskip_digits(char* p) { return p+strspn(p, "0123456789"); } + +#if defined(_MSC_VER) or (defined(__GNUC__) and not defined(__DJGPP__)) or defined(__WATCOMC__) +inline char * stpcpy(char* dest, const char* src) { + while ((*dest++ = *src++) != NUL) {} + return --dest; +} +#endif + +#ifndef isoctal +#define isoctal(c) (((c) >= '0') and ((c) <= '7')) +#endif + +char* strcvtc(char* s); + + +// ------------------------------------------------------------------ +// String tokenizer class + +class GTok { + +protected: + + const char* separator; + char* token; + +public: + + GTok(char* sep=NULL); + + char* First(char* buf) { token = strtok(buf, separator); return token; } + char* Next() { token = strtok(NULL, separator); return token; } + char* Token() { return token; } +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrarr.h b/goldlib/gall/gstrarr.h new file mode 100644 index 0000000..56e7990 --- /dev/null +++ b/goldlib/gall/gstrarr.h @@ -0,0 +1,64 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// String manipulation routines. +// ------------------------------------------------------------------ + +#ifndef __gstrarr_h +#define __gstrarr_h + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +typedef vector gstrarray; + + +// ------------------------------------------------------------------ + +inline void tokenize(gstrarray& array, const char* str, const char* delim = NULL) { + if(delim == NULL) + delim = ", \t"; + char* tmp = throw_xstrdup(str); + char* token = strtok(tmp, delim); + while(token) { + array.push_back(token); + token = strtok(NULL, delim); + } + throw_xfree(tmp); +} + + +// ------------------------------------------------------------------ + +#endif // __gstrarr_h + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrbags.cpp b/goldlib/gall/gstrbags.cpp new file mode 100644 index 0000000..781d497 --- /dev/null +++ b/goldlib/gall/gstrbags.cpp @@ -0,0 +1,165 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// String bag class. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +const int BLOCKSIZE = 4096; + + +// ------------------------------------------------------------------ + +GStrBag::GStrBag() { + + items = 0; + bagsize = 0; + bag = NULL; + blocksize = BLOCKSIZE; + currno = 0; +} + + +// ------------------------------------------------------------------ + +GStrBag::~GStrBag() { + + Reset(); +} + + +// ------------------------------------------------------------------ + +void GStrBag::Reset() { + + if(bag != NULL) + throw_release(bag); +} + + +// ------------------------------------------------------------------ + +int GStrBag::Add(const char* string) { + + return Add(string, strlen(string)+1); +} + + +// ------------------------------------------------------------------ + +int GStrBag::Add(const void* data, int length) { + + if(items == 0) + bag = (char*)throw_malloc(blocksize); + int currsize = bagsize + (items*sizeof(int)); + int currsizeblks = (currsize/blocksize) + 1; + int newsizeblks = ((currsize+length+sizeof(int))/blocksize) + 1; + if(newsizeblks != currsizeblks) + bag = (char*)throw_realloc(bag, newsizeblks*blocksize); + memmove(bag+bagsize+length, bag+bagsize, items*sizeof(int)); + memcpy(bag+bagsize, data, length); + ((int*)(bag+bagsize+length))[items] = bagsize; + bagsize += length; + return items++; +} + + +// ------------------------------------------------------------------ + +void GStrBag::Change(int index, const char* string) { + + Change(index, string, strlen(string)+1); +} + + +// ------------------------------------------------------------------ + +void GStrBag::Change(int index, const void* data, int length) { + + int oldpos = Pos(index); + int oldlen = bag ? strlen(bag+oldpos)+1 : 0; + int lendiff = length - oldlen; + int oldsize = bagsize+(items*sizeof(int)); + int movesize = oldsize - oldpos - oldlen; + int currsizeblks = (oldsize/blocksize) + 1; + int newsizeblks = ((oldsize+lendiff)/blocksize) + 1; + if(lendiff > 0) { + if(newsizeblks != currsizeblks) + bag = (char*)throw_realloc(bag, oldsize+lendiff); + memmove(bag+oldpos+length, bag+oldpos+oldlen, movesize); + } + else if(lendiff < 0) { + memmove(bag+oldpos+length, bag+oldpos+oldlen, movesize); + if(newsizeblks != currsizeblks) + bag = (char*)throw_realloc(bag, oldsize+lendiff); + } + memcpy(bag+oldpos, data, length); + bagsize += lendiff; + for(int n=index+1; n + + +// ------------------------------------------------------------------ + +class GStrBag { + +protected: + + char* bag; + int bagsize; + int items; + int currno; + +public: + + GStrBag(); + virtual ~GStrBag(); + + int blocksize; + + void Reset(); + + int Add(const char* string); + int Add(const void* data, int length); + + void Change(int index, const char* string); + void Change(int index, const void* data, int length); + + virtual int Count() { return items; } + + int CurrNo() { return currno; } + void CurrNo(int c) { currno = c; } + + int& Pos(int i) { return ((int*)(bag+bagsize))[i]; } + const char* Index(int i) { return bag ? bag + Pos(i) : NULL; } + + int First() { if(Count() < 1) return false; currno = 0; return true; } + int Next() { if(currno >= (Count()-1)) return false; currno++; return true; } + const char* Current() { return Index(currno); } + + const char* operator[](int i); +}; + + +// ------------------------------------------------------------------ + +class GStrBag2 : public GStrBag { + +public: + + GStrBag2() : GStrBag() {} + + inline int Count() { return items / 2; } + + inline int Add(const char* str1, const char* str2) { GStrBag::Add(str1); return GStrBag::Add(str2); } + inline int Add(const void* data, int length, const char* string) { GStrBag::Add(data, length); return GStrBag::Add(string); } + + inline void Change(int index, const char* str1, const char* str2) { GStrBag::Change(index-1, str1); GStrBag::Change(index, str2); } + + inline const char* Index1(int i) { return Index((i*2)); } + inline const char* Index2(int i) { return Index((i*2)+1); } + + inline const char* Current1() { return Index1(currno); } + inline const char* Current2() { return Index2(currno); } +}; + + +// ------------------------------------------------------------------ + +class GStrSet3 { + +protected: + + char* set; + struct { + int size; + int pos2; + int pos3; + } cfg; + +public: + + GStrSet3() { set = NULL; cfg.size = 0; cfg.pos2 = 0; cfg.pos3 = 0; } + ~GStrSet3() { Reset(); } + + void Reset() { throw_xfree(set); } + + void Put(const char* s1, const char* s2, const char* s3); + + void Change(const char* s1, const char* s2, const char* s3); + + const char* Change1(const char* s) { Change(s, Get2(), Get3()); return s; } + const char* Change2(const char* s) { Change(Get1(), s, Get3()); return s; } + const char* Change3(const char* s) { Change(Get1(), Get2(), s); return s; } + + const char* Get1() const { return set ? set : ""; } + const char* Get2() const { return set ? set+cfg.pos2 : ""; } + const char* Get3() const { return set ? set+cfg.pos3 : ""; } +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrctyp.cpp b/goldlib/gall/gstrctyp.cpp new file mode 100644 index 0000000..2a4a0db --- /dev/null +++ b/goldlib/gall/gstrctyp.cpp @@ -0,0 +1,138 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// String upper/lower and NLS functions. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Converts a character to upper or lower case depending on the +// previous character in the string + +static char touplow(char* str, char* pos, char ch) { + + char i; + + if(pos == str) + return toupper(ch); + + switch(*(pos-1)) { // check previous character + case ' ': // see if it is a separator + case '-': + case '_': + case ',': + case '.': + case '/': + i = (char)toupper(ch); // if it is, convert to upper + break; + default: + i = (char)tolower(ch); // otherwise, convert to lower + break; + } + + return i; // return converted character +} + + +// ------------------------------------------------------------------ +// Converts a string to mixed upper & lower case + +char* struplow(char* str) { + + int i; + + for(i=0; *(str+i); i++) + *(str+i) = touplow(str, str+i, *(str+i)); + + return str; +} + + +// ------------------------------------------------------------------ + +char* strcvtc(char* str) { + + char c; + char* s = str; + char* d = s; + while(*s) { + if(*s == '\\') { + s++; + switch(*s) { + case 'n': *d++ = '\n'; goto skip_constant; + case 't': *d++ = '\t'; goto skip_constant; + case 'v': *d++ = '\v'; goto skip_constant; + case 'b': *d++ = '\b'; goto skip_constant; + case 'r': *d++ = '\r'; goto skip_constant; + case 'f': *d++ = '\f'; goto skip_constant; + case 'a': *d++ = '\a'; goto skip_constant; + case '\\': *d++ = '\\'; goto skip_constant; + case '\'': *d++ = '\''; goto skip_constant; + case '\"': *d++ = '\"'; goto skip_constant; + case '\?': *d++ = '\?'; goto skip_constant; + case 'x': + if(isxdigit(s[1])) { + s++; + c = 0; + while(isxdigit(*s)) { + c <<= 4; + c |= (char)xtoi(*s); + s++; + } + *d++ = c; + continue; + } + break; + default: + if(isoctal(*s)) { + c = 0; + while(isoctal(*s)) { + c <<= 3; + c |= (char)(*s - '0'); + s++; + } + *d++ = c; + } + else { + s++; + continue; + } + } + *d++ = *s++; + continue; + + skip_constant: + s++; + continue; + } + *d++ = *s++; + } + *d = NUL; + return str; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrmail.cpp b/goldlib/gall/gstrmail.cpp new file mode 100644 index 0000000..348d4e5 --- /dev/null +++ b/goldlib/gall/gstrmail.cpp @@ -0,0 +1,178 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// RFC822 related character/string classes and functions. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +mail_ctype mail_ctype_global; + + +// ------------------------------------------------------------------ + +mail_ctype::mail_ctype() { + + memset(table, mail_char|mail_ctl, 32*sizeof(uint)); + memset(table+32, mail_char, 96*sizeof(uint)); + memset(table+'A', mail_char|mail_alpha, ('Z'-'A'+1)*sizeof(uint)); + memset(table+'a', mail_char|mail_alpha, ('z'-'a'+1)*sizeof(uint)); + memset(table+128, 0, 128*sizeof(uint)); + table[127] |= mail_ctl; + table[0] |= mail_delimiters; + table[' '] |= mail_delimiters | mail_lwsp; + table[HT] |= mail_delimiters | mail_lwsp; + table['('] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table[')'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['<'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['>'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['@'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table[','] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table[';'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table[':'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['\\'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['\"'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['['] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table[']'] |= mail_delimiters | mail_special | mime_tspecial | mime_especial; + table['.'] |= mail_delimiters | mail_special | mime_especial; + table['/'] |= mime_tspecial | mime_especial; + table['?'] |= mime_tspecial | mime_especial; + table['='] |= mime_tspecial | mime_especial; +} + + +// ------------------------------------------------------------------ + +const char* strskip_lwsp(const char* p) { + + while(is_mail_lwsp(*p)) + p++; + return p; +} + + +// ------------------------------------------------------------------ + +const char* strskip_mail_quote(const char* p) { + + if(*p == '\"') + p++; + while(*p and (*p != '\"')) { + if(*p == '\\') + p++; + p++; + } + if(*p == '\"') + p++; + + return p; +} + + +// ------------------------------------------------------------------ + +const char* strskip_delimiters(const char* p) { + + while(is_mail_delimiters(*p)) + p++; + return p; +} + + +// ------------------------------------------------------------------ + +char* strtrim_lwsp(char* p) { + + char* p0 = p; + p += strlen(p) - 1; + while(is_mail_lwsp(*p)) { + if(p == p0) + break; + p--; + } + return p; +} + + +// ------------------------------------------------------------------ + +char* strmail_quote(char* ot, const char* it) { + + char* o = ot; + const char* i = it; + + if(*o == '\"') + o++; + while(*i) { + if(is_mail_special(*i)) + *o++ = '\\'; + *o++ = *i++; + } + if(*ot == '\"') + *o++ = '\"'; + *o = NUL; + + return ot; +} + + +// ------------------------------------------------------------------ + +char* strmail_unquote(char* ot, const char* it) { + + char* o = ot; + const char* i = it; + bool was_quoted = false; + + if(*i == '\"') { + was_quoted = true; + i++; + } + while(*i) { + if(*i == '\\') + i++; + *o++ = *i++; + } + if(was_quoted) + o--; + *o = NUL; + + return ot; +} + + +// ------------------------------------------------------------------ + +int is_mail_lwsp(const char* s) { + + while(is_mail_lwsp(*s)) + s++; + return *s == NUL; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrmail.h b/goldlib/gall/gstrmail.h new file mode 100644 index 0000000..a4e28f9 --- /dev/null +++ b/goldlib/gall/gstrmail.h @@ -0,0 +1,96 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gstrmail_h +#define __gstrmail_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class mail_ctype { + +public: + + enum { + mail_char = 0x01, + mail_alpha = 0x02, + mail_ctl = 0x04, + mail_lwsp = 0x08, + mail_special = 0x10, + mail_delimiters = 0x20, + mime_tspecial = 0x40, // RFC1521 parameter token specials + mime_especial = 0x80 // RFC1522 encoded-word token specials + }; + + uint table[256]; + mail_ctype(); +}; + +extern mail_ctype mail_ctype_global; + + +// ------------------------------------------------------------------ + +inline bool is_mail_char(uint c) { return mail_ctype_global.table[c] & mail_ctype::mail_char; } +inline bool is_mail_alpha(uint c) { return mail_ctype_global.table[c] & mail_ctype::mail_alpha; } +inline bool is_mail_ctl(uint c) { return mail_ctype_global.table[c] & mail_ctype::mail_ctl; } +inline bool is_mail_cr(uint c) { return c == CR; } +inline bool is_mail_lf(uint c) { return c == LF; } +inline bool is_mail_space(uint c) { return c == ' '; } +inline bool is_mail_htab(uint c) { return c == HT; } +inline bool is_mail_crlf(uint c) { return is_mail_cr(c) or is_mail_lf(c); } +inline bool is_mail_lwsp(uint c) { return mail_ctype_global.table[c] & mail_ctype::mail_lwsp; } +inline bool is_mail_special(uint c) { return mail_ctype_global.table[c] & mail_ctype::mail_special; } +inline bool is_mail_delimiters(uint c) { return mail_ctype_global.table[c] & mail_ctype::mail_delimiters; } +inline bool is_mime_tspecial(uint c) { return mail_ctype_global.table[c] & mail_ctype::mime_tspecial; } +inline bool is_mime_especial(uint c) { return mail_ctype_global.table[c] & mail_ctype::mime_especial; } +inline bool is_mail_atom_delimiters(uint c) { return is_mail_delimiters(c) or is_mail_ctl(c); } +inline bool is_mime_ct_token_valid(uint c) { return not (is_mail_lwsp(c) or is_mail_ctl(c) or is_mime_tspecial(c)); } + + +// ------------------------------------------------------------------ + +const char* strskip_lwsp(const char* p); +const char* strskip_mail_quote(const char* p); +const char* strskip_delimiters(const char* p); + +char* strtrim_lwsp(char* p); + +char* strmail_quote(char* ot, const char* it); +char* strmail_unquote(char* ot, const char* it); +char* strmail_unquote_qtext(char* ot, const char* it); + +int is_mail_lwsp(const char* s); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gstrname.cpp b/goldlib/gall/gstrname.cpp new file mode 100644 index 0000000..a5a4d56 --- /dev/null +++ b/goldlib/gall/gstrname.cpp @@ -0,0 +1,82 @@ + +// ------------------------------------------------------------------ +// The Goldware Library. Copyright (C) Odinn Sorensen. +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Name handling. +// ------------------------------------------------------------------ + + +#include + + +// ------------------------------------------------------------------ +// Reverse a name to "lastname, firstname(s)" form. + +char* strrevname(char* reversedname, const char* name) { + + char tmpname[256]; + char midname[256]; + + strtrim(strcpy(tmpname, name)); + char* c = midname; // Start of temp name buffer + char* p = tmpname; // Point to start of name + char* m = NULL; // Init pointer to space + + *c = *p++; + while(*c) { // Go entire length of name + if(*c == ' ') // Look for space + m = c; // Save location + c++; + *c = *p++; + } + + if(m != NULL) { + *m++ = NUL; + strxmerge(reversedname, 256, m, ", ", midname, NULL); + } + else + strcpy(reversedname, midname); + + return reversedname; +} + + +// ------------------------------------------------------------------ +// Unreverse a name from "lastname, firstname(s)" form. + +char* strunrevname(char* unreversedname, const char* name) { + + char tmpname[256]; + strcpy(tmpname, name); + char* comma = strchr(tmpname, ','); + if(comma) { + *comma = NUL; + char* firstname = strskip_wht(comma+1); + strxmerge(unreversedname, 256, firstname, " ", tmpname, NULL); + *comma = ','; + } + else { + strcpy(unreversedname, tmpname); + } + return unreversedname; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gstrutil.cpp b/goldlib/gall/gstrutil.cpp new file mode 100644 index 0000000..c75ad32 --- /dev/null +++ b/goldlib/gall/gstrutil.cpp @@ -0,0 +1,607 @@ + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on source from the CXL library by Mike Smedley. +// String manipulation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Determines if a string is blank + +bool strblank(const char* str) { + + const char* p; + + for(p = str; *p; p++) + if(not isspace(*p)) + return false; + + return true; +} + + +// ------------------------------------------------------------------ +// Changes all occurrences of one character to another + +int strchg(char* str, char oldch, char newch) { + + int count = 0; + + for(char* p=str; *p; p++) { + if(oldch == *p) { + *p = newch; + count++; + } + } + + return count; +} + + +// ------------------------------------------------------------------ +// Deletes a substring from within a string + +static char* strdel(const char* substr, char* str) { + + char* dest = strstr(str, substr); + if(!dest) + return NULL; + char* src = dest + strlen(substr); + strcpy(dest, src); + + return str; +} + + +// ------------------------------------------------------------------ +// Deletes a substring from within a string, ignores case + +static char* stridel(const char* substr, char* str) { + + char* dest = (char*)striinc(substr, str); + if(!dest) + return NULL; + char* src = dest + strlen(substr); + strcpy(dest, src); + + return str; +} + + +// ------------------------------------------------------------------ +// Deletes all occurrences of one string inside another + +char* stridela(const char* substr, char* str) { + + int count = 0; + char* p = str; + + while((p = (char*)striinc(substr, p)) != NULL) { + stridel(substr, p); + count++; + } + + if(count) + return str; + return NULL; +} + + +// ------------------------------------------------------------------ +// Compare two strings, allowing wildcards + +int strnicmpw(const char* str1, const char* str2, int len) { + + int cmp = 0; + + for(int n=0; n=st_pos; i--) + *(str+leninstr+i) = *(str+i); + + // insert instr text + for(i=0; i 0); + + while(ptr-- > tmp) + *str++ = *ptr; + *str = NUL; + + return out; +} + + +// ------------------------------------------------------------------ + +char* strp2c(char* str) { + + int len = *str; + + memmove(str, str+1, len); // Copy data part + str[len] = NUL; // Set length + return str; +} + + +// ------------------------------------------------------------------ + +char* strnp2c(char* str, int n) { + + int len = (n < *str) ? n : *str; + + memmove(str, str+1, len); // Copy data part + str[len] = NUL; // Set length + return str; +} + + +// ------------------------------------------------------------------ + +char* strnp2cc(char* dest, const char* str, int n) { + + int len = (n < *str) ? n : *str; + + memcpy(dest, str+1, len); // Copy data part + dest[len] = NUL; // Set length + return dest; +} + + +// ------------------------------------------------------------------ + +char* strc2p(char* str) { + + char len = (char)strlen(str); + + memmove(str+1, str, len); // Copy data part + *str = len; // Set length + return str; +} + + +// ------------------------------------------------------------------ +// Strip the quotes off a quoted string ("" or '') + +char* StripQuotes(char* str) { + + int len; + + switch(*str) { + case '\'': + case '\"': + len = strlen(str); + switch(*(str+len-1)) { + case '\'': + case '\"': + memmove(str, str+1, len); + str[len-2] = NUL; + } + } + return str; +} + + +// ------------------------------------------------------------------ +// Right justifies a string + +char* strrjust(char* str) { + + char* p; + char* q; + + for(p=str; *p; p++) + ; // find end of string + p--; + for(q=p; isspace(*q) and q>=str; q--) + ; // find last non-space character + if(p != q) { + while(q >= str) { + *p-- = *q; + *q-- = ' '; + } + } + return str; +} + + +// ------------------------------------------------------------------ +// Changes all occurrences of one string to another + +char* strschg(char* str, const char* find, const char* replace) { + + int count = 0; + char* p = str; + + int len = strlen(replace); + while((p = strstr(p, find)) != NULL) { + strsrep(p, find, replace); + p += len; + count++; + } + + if(count) + return str; + return NULL; +} + + +// ------------------------------------------------------------------ +// Adjusts the size of a string + +char* strsetsz(char* str, int newsize) { + + int i; + + int len = strlen(str); + if(newsize < len) + *(str+newsize) = NUL; + else { + for(i=len; i0; i--) + *(str+i) = *(str+i-1); + *(str) = ' '; + } + } + + return str; +} + + +// ------------------------------------------------------------------ +// String search and replace, case sensitive + +char* strsrep(char* str, const char* search, const char* replace) { + + char* p; + + if((p = strstr(str, search)) != NULL) { + strdel(search, str); + strins(replace, str, (int)(p-str)); + p = str; + } + + return p; +} + + +// ------------------------------------------------------------------ +// Trims trailing spaces off of a string + +char* strtrim(char* p) { + + int i; + for(i=strlen(p)-1; (i >= 0) and ('!' > p[i]); i--) {} + p[i+1] = NUL; + return p; +} + + +// ------------------------------------------------------------------ +// Trims leading spaces off of a string + +char* strltrim(char* str) { + + char* p; + char* q; + + p = q = str; + while(*p and isspace(*p)) + p++; + + if(p != q) { + while(*p) + *q++ = *p++; + *q = NUL; + } + + return str; +} + + +// ------------------------------------------------------------------ + +const char* strlword(const char* str) { + + char buf[256]; + static char left[40]; + + *left = NUL; + if(*str) { + strcpy(buf, str); + if(strtok(buf, " ") != NULL) { + strcpy(left, buf); + } + } + return left; +} + + +// ------------------------------------------------------------------ + +const char* strrword(const char* str) { + + char* ptr; + char* ptr2; + char buf[256]; + static char right[40]; + + *right = NUL; + if(*str) { + strcpy(buf, str); + ptr = strtok(buf, " "); + ptr2 = ptr; + while(ptr != NULL) { + ptr2 = ptr; + ptr = strtok(NULL, " "); + } + if(ptr2) { + strcpy(right, ptr2); + } + } + return right; +} + + +// ------------------------------------------------------------------ + +char* strxcpy(char* d, const char* s, int n) { + + if(n) { + strncpy(d, s, n-1); + d[n-1] = NUL; + } + else + *d = NUL; + return d; +} + + +// ------------------------------------------------------------------ + +char *strxcat(char *dest, const char *src, size_t max) +{ + while (*dest and (max > 0)) { + --max; + dest++; + } + while (*src and (max > 0)) { + --max; + *dest++ = *src++; + } + *dest = NUL; + return dest; +} + + +// ------------------------------------------------------------------ + +char *strxmerge(char *dest, size_t max, ...) +{ + va_list a; + va_start(a, max); + for(; max > 0;) { + const char *src = va_arg(a, const char *); + if (src == NULL) + break; + while (*src and (max > 0)) { + --max; + *dest++ = *src++; + } + } + va_end(a); + *dest = NUL; + return dest; +} + + +// ------------------------------------------------------------------ + +GTok::GTok(char* sep) { + + separator = sep ? sep : ", \t"; +} + + +// ------------------------------------------------------------------ + +#if defined(__GNUC__) and not defined(__EMX__) + +char* strupr(char* s) { + + char* p = s; + while(*p) { + *p = toupper(*p); + p++; + } + return s; +} + +char* strlwr(char* s) { + + char* p = s; + while(*p) { + *p = tolower(*p); + p++; + } + return s; +} + +#endif + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gtimall.h b/goldlib/gall/gtimall.h new file mode 100644 index 0000000..971b965 --- /dev/null +++ b/goldlib/gall/gtimall.h @@ -0,0 +1,161 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Time utility functions. +// ------------------------------------------------------------------ + +#ifndef __gtimall_h +#define __gtimall_h + + +// ------------------------------------------------------------------ + +#include +#include +#include +#ifdef __UNIX__ +#include +#endif +#ifdef __OS2__ +#define INCL_BASE +#include +#endif +#ifdef __WIN32__ +#include +#endif + + +// ------------------------------------------------------------------ + +typedef long Clock; + + +// ------------------------------------------------------------------ +// DOS "findfirst" timestamp + +struct gfiletime { + unsigned ft_tsec : 5; // Second / 2 + unsigned ft_min : 6; // Minutes + unsigned ft_hour : 5; // Hours + unsigned ft_day : 5; // Days + unsigned ft_month : 4; // Months + unsigned ft_year : 7; // Year - 80 + + const char* c_str(char* buf); + dword number() { return *(dword*)this; } +} __attribute__((packed)); + +typedef gfiletime FFTime; + + +// ------------------------------------------------------------------ +// Opus DOS-style file timestamp + +struct gopustime { + unsigned ft_day : 5; // Days + unsigned ft_month : 4; // Months + unsigned ft_year : 7; // Year - 80 + unsigned ft_tsec : 5; // Second / 2 + unsigned ft_min : 6; // Minutes + unsigned ft_hour : 5; // Hours + + const char* c_str(char* buf); + dword number() { return *(dword*)this; } +} __attribute__((packed)); + +typedef gopustime FTime; + + +// ------------------------------------------------------------------ +// Externs for strftimei() + +extern char* __gsweekday[]; +extern char* __glweekday[]; +extern char* __gsmonth[]; +extern char* __glmonth[]; +extern char* __gampm[]; + +extern char* gsweekday[]; +extern char* glweekday[]; +extern char* gsmonth[]; +extern char* glmonth[]; +extern char* gampm[]; + +extern const char* gmonths[]; + + +// ------------------------------------------------------------------ +// Prototypes + +#ifdef __WIN32__ +extern struct tm dummy_struct_tm; +inline struct tm* ggmtime(time_t* arg) { + struct tm* a = gmtime(arg); + return (a != NULL) ? a : &dummy_struct_tm; +} +inline struct tm* glocaltime(time_t* arg) { + struct tm* a = localtime(arg); + return (a != NULL) ? a : &dummy_struct_tm; +} +#define gmtime(arg) ggmtime(arg) +#define localtime(arg) glocaltime(arg) +#endif + +#if defined(__OS2__) +inline void usleep(long duration) { DosSleep(duration); } +#elif defined(__MINGW32__) +inline void usleep(long duration) { Sleep(duration); } +#endif + +#ifdef __UNIX__ +inline Clock gclock() { struct tms z; return Clock(times(&z)*10/CLK_TCK); } +#else +inline Clock gclock() { return Clock(clock()*10/CLK_TCK); } +#endif + +int str2mon(const char* ptr) __attribute__ ((const)); +int tzoffset(); + +char* strftimei(char* s, size_t maxsize, const char* fmt, const struct tm* t) __attribute__ ((format (strftime, 3, 0))); + +FTime TimeToFTime(time_t __time) __attribute__ ((const)); +time_t FTimeToTime(FTime* __ftime, struct tm* __tm=NULL); + +time_t FidoTimeToUnix(char* __fidotime); + +char* FTimeToStr(char* buf, FTime &t); +char* TimeToStr(char* buf, time_t t); + + +// ------------------------------------------------------------------ + +long YMD2JDN(unsigned yr, unsigned mo, unsigned day) __attribute__ ((const)); +void JDN2YMD(long scalar, unsigned *yr, unsigned *mo, unsigned *day); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gtimjuld.cpp b/goldlib/gall/gtimjuld.cpp new file mode 100644 index 0000000..b90bea8 --- /dev/null +++ b/goldlib/gall/gtimjuld.cpp @@ -0,0 +1,74 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Julian date conversion functions. +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +inline int isleap(unsigned yr) { return yr % 400 == 0 || (yr % 4 == 0 && yr % 100 != 0); } +inline unsigned months_to_days(unsigned month) { return (month * 3057 - 3007) / 100; } +inline long years_to_days(unsigned yr) { return yr * 365L + yr / 4 - yr / 100 + yr / 400; } + + +// ------------------------------------------------------------------ + +long YMD2JDN(unsigned yr, unsigned mo, unsigned day) { + + long scalar; + scalar = day + months_to_days(mo); + if(mo > 2) /* adjust if past February */ + scalar -= isleap(yr) ? 1 : 2; + yr--; + scalar += years_to_days(yr); + return scalar - 693595L; +} + + +// ------------------------------------------------------------------ + +void JDN2YMD(long scalar, unsigned *yr, unsigned *mo, unsigned *day) { + + scalar += 693595L; + + unsigned n; /* compute inverse of years_to_days() */ + + for(n = (unsigned)((scalar * 400L) / 146097L); years_to_days(n) < scalar;) + n++; /* 146097 == years_to_days(400) */ + *yr = n; + n = (unsigned)(scalar - years_to_days(n-1)); + if(n > 59) { /* adjust if past February */ + n += 2; + if(isleap(*yr)) + n -= n > 62 ? 1 : 2; + } + *mo = (n * 100 + 3007) / 3057; /* inverse of months_to_days() */ + *day = n - months_to_days(*mo); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gtimutil.cpp b/goldlib/gall/gtimutil.cpp new file mode 100644 index 0000000..9bf9dd9 --- /dev/null +++ b/goldlib/gall/gtimutil.cpp @@ -0,0 +1,504 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Time utility functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __OS2__ +#define INCL_BASE +#include +#endif + +#ifdef __WIN32__ +#include +#endif + + +// ------------------------------------------------------------------ + +#ifdef __WIN32__ +struct tm dummy_struct_tm = { 0, 0, 0, 1, 0, 70, 0, 0, -1 }; +#endif + + +// ------------------------------------------------------------------ + +const char* gmonths[] = { + "ERR", + "Jan", "Feb", "Mar", + "Apr", "May", "Jun", + "Jul", "Aug", "Sep", + "Oct", "Nov", "Dec", + "ERR" +}; + + +// ------------------------------------------------------------------ +// Returns current timezone offset based on TZ environment variable. + +int tzoffset() { + + time_t t = time(NULL); + struct tm *a = localtime(&t); + int tz = a->tm_hour * 100 + a->tm_min; + a = gmtime(&t); + tz -= a->tm_hour * 100 + a->tm_min; + if(tz < -12*100) + tz += 24*100; + else if(tz > 12*100) + tz -= 24*100; + return tz; +} + + +// ------------------------------------------------------------------ + +char* __gampm[2] = { + "AM", "PM" +}; + +char* __gsweekday[7] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; + +char* __glweekday[7] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" +}; + +char* __gsmonth[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +char* __glmonth[12] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; + +char* gampm[2] = { + "AM", "PM" +}; + +char* gsweekday[7] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +char* glweekday[7] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +char* gsmonth[12] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +char* glmonth[12] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + + +// ------------------------------------------------------------------ +// written 6 september 1989 by jim nutt +// released into the public domain by jim nutt +// modified 21-Oct-89 by Rob Duff + +static char buf[26]; +static char format[] = "%?"; + +static int pow[5] = { 1, 10, 100, 1000, 10000 }; + + +// ------------------------------------------------------------------ +// static void strfmt(char *str, char *fmt); +// simple sprintf for strftime +// each format descriptor is of the form %n +// where n goes from zero to four +// 0 -- string %s +// 1..4 -- int %?.?d + +static void strfmt(char *str, const char *fmt, ...) { + + int ival, ilen; + char *sval; + va_list vp; + + va_start(vp, fmt); + while(*fmt) { + if(*fmt++ == '%') { + ilen = *fmt++ - '0'; + if(ilen == 0) // zero means string arg + { + sval = va_arg(vp, char*); + while(*sval) + *str++ = *sval++; + } + else { // always leading zeros + if(ilen == ('-' - '0')) { + ilen = *fmt++ - '0'; + ival = va_arg(vp, int); + bool padding = true; + while(ilen) { + ival %= pow[ilen] / pow[ilen-1]; + if(ival) + padding = false; + if(--ilen and padding) + ival = ' ' - '0'; + *str++ = (char)('0' + ival); + } + } + else { + ival = va_arg(vp, int); + while(ilen) { + ival %= pow[ilen--]; + *str++ = (char)('0' + ival / pow[ilen]); + } + } + } + } + else *str++ = fmt[-1]; + } + *str = '\0'; + va_end(vp); +} + + +// ------------------------------------------------------------------ +// In differ to ANSI C strftime this function supports reloading of +// field names + +#define setvar(internal,external,field) \ + char **internal = external; \ + if(internal[field] == NULL) internal = __##external; + +char *strftimei(char *s, size_t maxs, const char *f, const struct tm *t) +{ + char *p, *q, *r; + + setvar(aday, gsweekday, t->tm_wday); + setvar(day, glweekday, t->tm_wday); + setvar(amonth, gsmonth, t->tm_mon); + setvar(month, glmonth, t->tm_mon); + + p = s; + q = s + maxs - 1; + while((*f != NUL)) { + if(*f++ == '%') { + r = buf; + switch(*f++) { + + case '%': + format[1] = NUL; + r = format; + break; + + case 'a': + r = aday[t->tm_wday]; + break; + + case 'A': + r = day[t->tm_wday]; + break; + + case 'b': + r = amonth[t->tm_mon]; + break; + + case 'B': + r = month[t->tm_mon]; + break; + + case 'C': + strfmt(r, "%0 %0 %-2 %2:%2:%2 %4", + aday[t->tm_wday], amonth[t->tm_mon], + t->tm_mday,t->tm_hour, t->tm_min, + t->tm_sec, t->tm_year+1900); + break; + + case 'e': + strfmt(r, "%-2", t->tm_mday); + break; + + case 'E': + sprintf(r, "%u", (uint)t->tm_mday); + break; + + case 'p': + r = gampm[(t->tm_hour>11)?1:0]; + break; + + default: + format[1] = f[-1]; + if(strftime(r, 26, format, t) == 0) { + buf[0] = '%'; // reconstruct the format + buf[1] = f[-1]; + buf[2] = '\0'; + if(buf[1] == 0) + f--; // back up if at end of string + } + break; + } + while(*r) { + if(p == q) { + *q = '\0'; + return 0; + } + *p++ = *r++; + } + } + else { + if(p == q) { + *q = '\0'; + return 0; + } + *p++ = f[-1]; + } + } + *p = '\0'; + return s; +} + + +// ------------------------------------------------------------------ +// Convert string-month to integer + +int str2mon(const char* ptr) { + + int mon; + + switch(toupper(*ptr)) { + case 'A': + if(toupper(ptr[1]) == 'P') + mon = 4; + else + mon = 8; + break; + case 'D': + mon = 12; + break; + case 'F': + mon = 2; + break; + case 'J': + if(toupper(ptr[1]) == 'A') + mon = 1; + else if(toupper(ptr[2]) == 'L') + mon = 7; + else + mon = 6; + break; + case 'M': + if(toupper(ptr[2]) == 'R') + mon = 3; + else + mon = 5; + break; + case 'N': + mon = 11; + break; + case 'O': + mon = 10; + break; + case 'S': + mon = 9; + break; + default: + mon = 0; + } + + return mon; +} + + +// ------------------------------------------------------------------ + +time_t FTimeToTime(FTime* __ftime, struct tm* __tm) { + + struct tm _tm; + ulong _time = 0; + + if(__tm == NULL) + __tm = &_tm; + + // Only try to convert a valid date + if(__ftime->ft_year >= 5) { // FidoNet standards didn't exist before 1985 + if((__ftime->ft_day >= 1) and (__ftime->ft_day <= 31)) { + if((__ftime->ft_month >= 1) and (__ftime->ft_month <= 12)) { + + __tm->tm_year = __ftime->ft_year + 80; + __tm->tm_mon = __ftime->ft_month - 1; + __tm->tm_mday = __ftime->ft_day; + __tm->tm_hour = __ftime->ft_hour; + __tm->tm_min = __ftime->ft_min; + __tm->tm_sec = __ftime->ft_tsec * 2; + __tm->tm_isdst = -1; + + time_t a = mktime(__tm); + time_t b = mktime(gmtime(&a)); + _time = a + a - b; + + if(_time == (ulong)0xFFFFFFFFL) + _time = 0; + } + } + } + + return _time; +} + + +// ------------------------------------------------------------------ + +FTime TimeToFTime(time_t __time) { + + FTime _ft; + memset(&_ft, 0, sizeof(FTime)); + + if(__time) { + + struct tm* _tmp = gmtime(&__time); + _ft.ft_year = (word)(_tmp->tm_year - 80); + _ft.ft_month = (word)(_tmp->tm_mon + 1); + _ft.ft_day = (word)(_tmp->tm_mday); + _ft.ft_hour = (word)(_tmp->tm_hour); + _ft.ft_min = (word)(_tmp->tm_min); + _ft.ft_tsec = (word)(_tmp->tm_sec / 2); + } + + return _ft; +} + + +// ------------------------------------------------------------------ + +time_t FidoTimeToUnix(char* ptr) { + + bool date_ok = false; + int year=0, month=0, day=0; + int hour=0, minute=0, second=0; + + ptr = strskip_wht(ptr); + if(not isdigit(*ptr)) { + // Skip past weekday string (SEA format) + ptr = strskip_wht(strskip_txt(ptr)); + } + if(*ptr) { + if(isdigit(*ptr)) { + day = atoi(ptr); + ptr = strskip_wht(strskip_txt(ptr)); + if(isalpha(*ptr)) { + month = str2mon(ptr); + if(month) { + ptr = strskip_wht(strskip_txt(ptr)); + if(isdigit(*ptr)) { + year = atoi(ptr); + ptr = strskip_wht(strskip_txt(ptr)); + if(isdigit(*ptr)) { + hour = atoi(ptr); + ptr = strskip_digits(ptr); + if(*ptr and isdigit(ptr[1])) { + minute = atoi(++ptr); + date_ok = true; + // The seconds part is only in the FTS-1 format + ptr = strskip_digits(ptr); + if(*ptr and isdigit(ptr[1])) { + second = atoi(++ptr); + } + } + } + } + } + } + } + } + + // Convert datetime to UNIX timestamp + if(date_ok) { + struct tm t; + t.tm_year = (year < 80) ? (year+100) : year; + t.tm_mon = month - 1; + t.tm_mday = day; + t.tm_hour = hour; + t.tm_min = minute; + t.tm_sec = second; + t.tm_isdst = -1; + time_t a = mktime(&t); + time_t b = mktime(gmtime(&a)); + return a + a - b; + } + return (ulong)-1; +} + + +// ------------------------------------------------------------------ + +char* TimeToStr(char* buf, time_t t) { + + return strftimei(buf, 20, "%Y-%m-%d %H:%M:%S", gmtime(&t)); +} + + +// ------------------------------------------------------------------ + +char* FTimeToStr(char* buf, FTime& t) { + + sprintf(buf, "%04u-%02u-%02u %02u:%02u:%02u", + t.ft_year+1980, t.ft_month, t.ft_day, + t.ft_hour, t.ft_min, t.ft_tsec*2 + ); + return buf; +} + + +// ------------------------------------------------------------------ + +const char* gfiletime::c_str(char* buf) { + + sprintf(buf, "%04u-%02u-%02u %02u:%02u:%02u", + ft_year+1980, ft_month, ft_day, + ft_hour, ft_min, ft_tsec*2 + ); + return buf; +} + + +// ------------------------------------------------------------------ + +const char* gopustime::c_str(char* buf) { + + sprintf(buf, "%04u-%02u-%02u %02u:%02u:%02u", + ft_year+1980, ft_month, ft_day, + ft_hour, ft_min, ft_tsec*2 + ); + return buf; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gtxtpara.cpp b/goldlib/gall/gtxtpara.cpp new file mode 100644 index 0000000..4afaf81 --- /dev/null +++ b/goldlib/gall/gtxtpara.cpp @@ -0,0 +1,197 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Text -> Paragraph conversion. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +int GParagraph::ConvertText(char* _tptr, uint _tlen) { + + // Text position counter + uint _tpos = 0; + + // Main conversion loop + while(_tpos < _tlen) { + + // Skip SOFTCR, NUL and LF characters at the start of a paragraph + while(_tpos < _tlen) { + switch(*_tptr) { + case SOFTCR: + if(softcr != LF) break; // Allow soft-cr to be a real char + case NUL: case LF: + _tptr++; _tpos++; continue; + } + break; + } + + // Break out of loop at end of text + if(_tpos >= _tlen) + break; + + // Paragraph start pointer and position + char* _pptr = _tptr; + uint _ppos = _tpos; + + // Find next CR or end of text + while((*_tptr != CR) and (_tpos < _tlen)) + _tptr++, _tpos++; + + // NUL-terminate paragraph (overwriting the CR if any) + *_tptr = NUL; + + // Add paragraph + AddParagraph(_pptr, _tpos-_ppos); + } + + return lines; +} + + +// ------------------------------------------------------------------ + +uint GParagraph::CheckCtrlLines() { + + // Non-ctrl text size including a terminating CR + uint _length = 0; + + if(paraidx) { + + // Flags + int _got_tearline = false; + int _got_origin = false; + + // Point to one item past the last item + GParaData* _pdptr = ¶idx[lines]; + int _line = lines; + + // Check paragraphs in bottom-up order + do { + + // Previous paragraph + _line--; + _pdptr--; + + // Shortcut alias + char* _ptr = _pdptr->text; + + // Switch the CHR4 value + switch(*(dword*)_ptr) { + + // AREA: echo identifier + case CHR4_AREA: + // Mark all occurrences. Check in a separate loop afterwards + if(strneql(_ptr, "AREA:", 5)) + _pdptr->control = CTRL_AREA; + break; + + // --- Tearline + case CHR4_TEARLINENUL: + case CHR4_TEARLINESPACE: + // Only the last tearline is valid + if(not _got_tearline) + if(strneql(_ptr, "---\0", 4) or strneql(_ptr, "--- ", 4)) + _pdptr->control = CTRL_TEARLINE, _got_tearline = true; + break; + + // * Origin: + case CHR4_ORIGIN: + // Only the last origin is valid and only if before any tearline + if(not _got_tearline and not _got_origin) + if(strneql(_ptr, " * Origin: ", 11)) + _pdptr->control = CTRL_ORIGIN, _got_origin = true; + break; + + // SEEN-BY: (non-kludge version) + case CHR4_SEENBY: + // Non-kludge version is only valid after tearline/origin + if(not _got_tearline and not _got_origin) + if(strneql(_ptr, "SEEN-BY: ", 9)) + _pdptr->control = CTRL_SEENBY; + break; + + // Standard known kludges + case CHR4_INTL: if(strneql(_ptr, "\001INTL ", 6)) _pdptr->control = CTRL_INTL; break; + case CHR4_FMPT: if(strneql(_ptr, "\001FMPT ", 6)) _pdptr->control = CTRL_FMPT; break; + case CHR4_TOPT: if(strneql(_ptr, "\001TOPT ", 6)) _pdptr->control = CTRL_TOPT; break; + case CHR4_MSGID: if(strneql(_ptr, "\001MSGID: ", 8)) _pdptr->control = CTRL_MSGID; break; + case CHR4_REPLY: if(strneql(_ptr, "\001REPLY: ", 8)) _pdptr->control = CTRL_REPLY; break; + case CHR4_PID: if(strneql(_ptr, "\001PID: ", 6)) _pdptr->control = CTRL_PID; break; + case CHR4_SEENBY1: if(strneql(_ptr, "\001SEEN-BY: ", 10)) _pdptr->control = CTRL_SEENBY1; break; + case CHR4_PATH: if(strneql(_ptr, "\001PATH: ", 7)) _pdptr->control = CTRL_PATH; break; + case CHR4_CHARSET: if(strneql(_ptr, "\001CHARSET: ", 10)) _pdptr->control = CTRL_CHARSET; break; + case CHR4_CHRS: if(strneql(_ptr, "\001CHRS: ", 7)) _pdptr->control = CTRL_CHRS; break; + case CHR4_TZUTC: if(strneql(_ptr, "\001TZUTC: ", 8)) _pdptr->control = CTRL_TZUTC; break; + case CHR4_VIA: if(strneql(_ptr, "\001VIA: ", 6)) _pdptr->control = CTRL_VIA; break; + case CHR4_FLAGS: if(strneql(_ptr, "\001FLAGS ", 7)) _pdptr->control = CTRL_FLAGS; break; + } + + // Mark unknown kludges + if(not _pdptr->control and (*_ptr == CTRL_A)) + _pdptr->control = CTRL_UNKNOWNKLUDGE; + + // Calculate non-ctrl text size + if(_pdptr->control < CTRL_KLUDGE) + _length += _pdptr->length + 1; + + } while(_line); + + // Flags + int _got_area = false; + int _got_nonctrl = false; + + // Loop to check AREA: occurrences + while(_line < lines) { + + // Is this a control line? + if(_pdptr->control) { + + // Eliminate AREA: duplicates and any occurrence after first non-ctrl line + if(_pdptr->control == CTRL_AREA) { + if(_got_area or _got_nonctrl) + _pdptr->control = 0; + _got_area = true; + } + } + else { + + // Flag first occurrence of a non-ctrl line + _got_nonctrl = true; + } + + // Next paragraph + _pdptr++; + _line++; + } + } + + // Return total non-ctrl text size + return _length; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gtxtpara.h b/goldlib/gall/gtxtpara.h new file mode 100644 index 0000000..a71156c --- /dev/null +++ b/goldlib/gall/gtxtpara.h @@ -0,0 +1,168 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Text -> Paragraph conversion. +// ------------------------------------------------------------------ + +#ifndef __gtxtpara_h +#define __gtxtpara_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Macro to build a CHR4 + +#define MK_CHR4(a,b,c,d) ((dword)(a)|((dword)(b)<<8)|((dword)(c)<<16)|((dword)(d)<<24)) + + +// ------------------------------------------------------------------ +// CHR4 values for standard non-kludge control lines + +const dword CHR4_AREA = MK_CHR4('A','R','E','A'); +const dword CHR4_TEARLINESPACE = MK_CHR4('-','-','-',' '); +const dword CHR4_TEARLINENUL = MK_CHR4('-','-','-','\0'); +const dword CHR4_ORIGIN = MK_CHR4(' ','*',' ','O'); +const dword CHR4_SEENBY = MK_CHR4('S','E','E','N'); + + +// ------------------------------------------------------------------ +// CHR4 values for standard known kludges + +const dword CHR4_INTL = MK_CHR4('\001','I','N','T'); +const dword CHR4_FMPT = MK_CHR4('\001','F','M','P'); +const dword CHR4_TOPT = MK_CHR4('\001','T','O','P'); +const dword CHR4_MSGID = MK_CHR4('\001','M','S','G'); +const dword CHR4_REPLY = MK_CHR4('\001','R','E','P'); +const dword CHR4_PID = MK_CHR4('\001','P','I','D'); +const dword CHR4_SEENBY1 = MK_CHR4('\001','S','E','E'); +const dword CHR4_PATH = MK_CHR4('\001','P','A','T'); +const dword CHR4_CHARSET = MK_CHR4('\001','C','H','A'); +const dword CHR4_CHRS = MK_CHR4('\001','C','H','R'); +const dword CHR4_TZUTC = MK_CHR4('\001','T','Z','U'); +const dword CHR4_VIA = MK_CHR4('\001','V','I','A'); +const dword CHR4_FLAGS = MK_CHR4('\001','F','L','A'); + + +// ------------------------------------------------------------------ +// Control line enumeration + +enum { + + // Non-ctrl line + NOT_CTRL = 0, + + // Standard non-kludge control lines + CTRL_AREA, + CTRL_TEARLINE, + CTRL_ORIGIN, + + // Standard known kludges + CTRL_KLUDGE, + CTRL_INTL, + CTRL_FMPT, + CTRL_TOPT, + CTRL_MSGID, + CTRL_REPLY, + CTRL_PID, + CTRL_SEENBY, + CTRL_SEENBY1, + CTRL_PATH, + CTRL_CHARSET, + CTRL_CHRS, + CTRL_TZUTC, + CTRL_VIA, + CTRL_FLAGS, + + // Unknown kludges + CTRL_UNKNOWNKLUDGE +}; + + +// ------------------------------------------------------------------ + +struct GParaData { + + char* text; + uint length; + uint control; +}; + + +// ------------------------------------------------------------------ + +class GParagraph { + +public: + + int lines; + char softcr; + GParaData* paraidx; + + GParagraph(); + ~GParagraph(); + + void AddParagraph(char* __text, uint __length); + int ConvertText(char* __text, uint __length); + uint CheckCtrlLines(); +}; + + +// ------------------------------------------------------------------ + +inline GParagraph::GParagraph() { + + lines = 0; + softcr = LF; + paraidx = NULL; +} + + +// ------------------------------------------------------------------ + +inline GParagraph::~GParagraph() { + + throw_free(paraidx); +} + + +// ------------------------------------------------------------------ + +inline void GParagraph::AddParagraph(char* __text, uint __length) { + + paraidx = (GParaData*)throw_realloc(paraidx, (lines+1)*sizeof(GParaData)); + GParaData* _para = paraidx + lines++; + _para->text = __text; + _para->length = __length; + _para->control = 0; +} + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrbase.cpp b/goldlib/gall/gusrbase.cpp new file mode 100644 index 0000000..0a42165 --- /dev/null +++ b/goldlib/gall/gusrbase.cpp @@ -0,0 +1,228 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Userfile base class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +GUser::GUser() { + + fh = -1; + found = false; + index = 0; + name = NULL; + recno = 0; + records = 0; + recptr = NULL; + recsize = 0; +} + + +// ------------------------------------------------------------------ + +GUser::~GUser() { + + // No action +} + + +// ------------------------------------------------------------------ + +void GUser::founduser() { + + index = recno; + found = true; +} + + +// ------------------------------------------------------------------ + +void GUser::inctimesposted(int) { + + // No action +} + + +// ------------------------------------------------------------------ + +ulong GUser::lastread() { + + // No action + return 0; +} + + +// ------------------------------------------------------------------ + +void GUser::lastread(ulong) { + + // No action +} + + +// ------------------------------------------------------------------ + +void GUser::recinit(const char* __name) { + + memset(recptr, 0, recsize); + strcpy(name, __name); +} + + +// ------------------------------------------------------------------ + +int GUser::moveto(uint __rec) { + + if(fh != -1) { + if(__rec <= records) { + lseek(fh, (long)__rec*(long)recsize, SEEK_SET); + recno = __rec; + return true; + } + } + recno = records; + return false; +} + + +// ------------------------------------------------------------------ + +int GUser::next() { + + return moveto(++recno); +} + + +// ------------------------------------------------------------------ + +int GUser::prev() { + + return moveto(--recno); +} + + +// ------------------------------------------------------------------ + +void GUser::seekread() { + + if(fh != -1) { + lseek(fh, (long)recno*(long)recsize, SEEK_SET); + ::read(fh, recptr, recsize); + } +} + + +// ------------------------------------------------------------------ + +void GUser::seekwrite() { + + if(fh != -1) { + lseek(fh, (long)recno*(long)recsize, SEEK_SET); + ::write(fh, recptr, recsize); + } +} + + +// ------------------------------------------------------------------ + +int GUser::find(const char* __name, char* __result, int __wildcards) { + + // Init variables + index = 0; + recno = 0; + found = false; + + // If userfile is open + if(fh != -1) { + + // Rewind file to start + lseek(fh, 0, SEEK_SET); + + // Get number of records in the userfile + records = (uint)(filelength(fh)/recsize); + + // Searching loop + for(recno=0; recno + + +// ------------------------------------------------------------------ +// Userfile base class + +class GUser { + +public: + + // ---------------------------------------------------------------- + // Variables + + int fh; // File handle + int found; // User found + uint index; // User index number + char* name; // Pointer to name in user record + uint recno; // Current user record number + uint records; // Total number of user records + char* recptr; // Pointer to user record + uint recsize; // Size of user records + + + // ---------------------------------------------------------------- + // Constructor and destructor + + GUser(); + virtual ~GUser() = 0; + + + // ---------------------------------------------------------------- + // Pure virtual functions + + virtual int isvalid() = 0; + virtual int read() = 0; + + + // ---------------------------------------------------------------- + // Virtual functions + + virtual void founduser(); + virtual void inctimesposted(int __times); + virtual ulong lastread(); + virtual void lastread(ulong __lastread); + virtual void recinit(const char* __name); + + + // ---------------------------------------------------------------- + // Normal functions + + int moveto(uint __rec); + int next(); + int prev(); + + void seekread(); + void seekwrite(); + + int find(const char* __name, char* __result=NULL, int __wildcards=false); + int findwild(const char* __name, char* __result=NULL); + + void add(const char* __name); + + + // ---------------------------------------------------------------- +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrezyc.cpp b/goldlib/gall/gusrezyc.cpp new file mode 100644 index 0000000..0f3b0aa --- /dev/null +++ b/goldlib/gall/gusrezyc.cpp @@ -0,0 +1,143 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +EzycomUser::EzycomUser() { + + ver = 102; + + extfh = -1; + + recsize = sizeof(EzycUsers); + + record = new EzycUsers; throw_new(record); + extrec = new EzycUsersExt; throw_new(extrec); + extrec110 = new EzycUsersExt110; throw_new(extrec110); + + recptr = (char*)record; + name = record->name; +} + + +// ------------------------------------------------------------------ + +EzycomUser::~EzycomUser() { + + throw_delete(extrec110); + throw_delete(extrec); + throw_delete(record); +} + + +// ------------------------------------------------------------------ + +void EzycomUser::inctimesposted(int __times) { + + if(extfh != -1) { + + if(ver >= 110) { + memset(extrec110, 0, sizeof(EzycUsersExt110)); + lseek(extfh, (long)recno*(long)sizeof(EzycUsersExt110), SEEK_SET); + ::read(extfh, extrec110, sizeof(EzycUsersExt110)); + extrec110->msgsposted += (word)__times; + lseek(extfh, (long)recno*(long)sizeof(EzycUsersExt110), SEEK_SET); + ::write(extfh, extrec110, sizeof(EzycUsersExt110)); + } + else { + memset(extrec, 0, sizeof(EzycUsersExt)); + lseek(extfh, (long)recno*(long)sizeof(EzycUsersExt), SEEK_SET); + ::read(extfh, extrec, sizeof(EzycUsersExt)); + extrec->msgsposted += (word)__times; + lseek(extfh, (long)recno*(long)sizeof(EzycUsersExt), SEEK_SET); + ::write(extfh, extrec, sizeof(EzycUsersExt)); + } + } +} + + +// ------------------------------------------------------------------ + +int EzycomUser::isvalid() { + + return not (record->attribute & EZYC_USERDELETED); +} + + +// ------------------------------------------------------------------ + +int EzycomUser::read() { + + if(fh != -1) { + + ::read(fh, record, sizeof(EzycUsers)); + STRNP2C(record->name); + + return isvalid(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +void EzycomUser::recinit(const char* __name) { + + GUser::recinit(__name); + strc2p(record->name); +} + + +// ------------------------------------------------------------------ + +void EzycomUser::add(const char* __name) { + + GUser::add(__name); + + if(extfh != -1) { + + if(ver >= 110) { + memset(extrec110, 0, sizeof(EzycUsersExt110)); + lseek(extfh, (long)recno*(long)sizeof(EzycUsersExt110), SEEK_SET); + ::write(extfh, extrec110, sizeof(EzycUsersExt110)); + } + else { + memset(extrec, 0, sizeof(EzycUsersExt)); + lseek(extfh, (long)recno*(long)sizeof(EzycUsersExt), SEEK_SET); + ::write(extfh, extrec, sizeof(EzycUsersExt)); + } + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrezyc.h b/goldlib/gall/gusrezyc.h new file mode 100644 index 0000000..1d802ff --- /dev/null +++ b/goldlib/gall/gusrezyc.h @@ -0,0 +1,222 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrezyc_h +#define __gusrezyc_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Ezycom USERS.BBS record structure + +struct EzycUsers { + + char name[36]; + char alias[36]; + char password[16]; + word security; + byte attribute; + byte attribute2; + byte attribute3; + byte attribute4; + byte flagsx[4]; + char dataphone[15]; + char voicephone[15]; +}; + + +// ------------------------------------------------------------------ +// Ezycom userfile attributes + +#define EZYC_USERDELETED 0x0001 + + +// ------------------------------------------------------------------ +// Ezycom USERSEXT.BBS record structure + +struct EzycUsersExt { + + char location[26]; + long lasttimedate; + word credit; + word pending; + word msgsposted; + word nocalls; + word uploads; + word todayk; + word timeused; + word downloads; + long uploadsk; + long downloadsk; + byte screenlength; + byte lastpwdchange; + word timebanked; + word ksbanked; + word filepoints; + byte qwkcompression; + byte qwkdaysold; + byte comment[41]; + byte colour1_2; + byte colour3_4; + byte colour5_6; + byte colour7_8; + byte bkcolour; + byte sessionfailures; + byte topmenu[9]; + word filepointsgiven; + struct { + word year; + byte month; + byte day; + } dateofbirth; + byte groups[4]; + word regodate; + word firstdate; + word lastfiledate; + char defprotocol; + word timeleft; + word filearea; + word messarea; + word qwkmaxmsgs; + word qwkmaxmsgsperarea; + short todaybankwk; + char forwardto[36]; + byte todaycalls; + short todaybankwt; + char extraspace[4]; +}; + + +// ------------------------------------------------------------------ +// Ezycom USERSEXT.BBS record structure, version 1.10 + +struct EzycUsersExt110 { + + char location[26]; + long lasttimedate; + word credit; + word pending; + word msgsposted; + word nocalls; + word uploads; + word todayk; + word timeused; + word downloads; + long uploadsk; + long downloadsk; + byte screenlength; + byte lastpwdchange; + word timebanked; + word ksbanked; + word filepoints; + byte qwkcompression; + byte qwkdaysold; + byte comment[41]; + byte colour1_2; + byte colour3_4; + byte colour5_6; + byte colour7_8; + byte bkcolour; + byte sessionfailures; + byte topmenu[9]; + word filepointsgiven; + struct { + word year; + byte month; + byte day; + } dateofbirth; + byte groups[4]; + word regodate; + word firstdate; + word lastfiledate; + char defprotocol; + word timeleft; + word filearea; + word messarea; + word qwkmaxmsgs; + word qwkmaxmsgsperarea; + short todaybankwk; + char forwardto[36]; + byte todaycalls; + short todaybankwt; + byte language; + word endregodate; + long tottimeused; + char extraspace[125]; +}; + + +// ------------------------------------------------------------------ +// Ezycom userfile class + +class EzycomUser : public GUser { + +public: + + int ver; + + int extfh; + + EzycUsers* record; + EzycUsersExt* extrec; + EzycUsersExt110* extrec110; + + EzycomUser(); + ~EzycomUser(); + + int isvalid(); + int read(); + + void inctimesposted(int __times); + void recinit(const char* __name); + + void add(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrgold.cpp b/goldlib/gall/gusrgold.cpp new file mode 100644 index 0000000..7743b3c --- /dev/null +++ b/goldlib/gall/gusrgold.cpp @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Goldbase userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +GoldbaseUser::GoldbaseUser() { + + recsize = sizeof(GoldUsers); + record = new GoldUsers; throw_new(record); + recptr = (char*)record; + name = record->name; +} + + +// ------------------------------------------------------------------ + +GoldbaseUser::~GoldbaseUser() { + + throw_delete(record); +} + + +// ------------------------------------------------------------------ + +void GoldbaseUser::inctimesposted(int __times) { + + seekread(); + record->timesposted += (word)__times; + seekwrite(); +} + + +// ------------------------------------------------------------------ + +int GoldbaseUser::isvalid() { + + return not (record->attrib & GOLD_USERDELETED); +} + + +// ------------------------------------------------------------------ + +int GoldbaseUser::read() { + + if(fh != -1) { + + ::read(fh, record, sizeof(GoldUsers)); + STRNP2C(record->name); + + return isvalid(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +ulong GoldbaseUser::lastread() { + + seekread(); + return record->highmsgread; +} + + +// ------------------------------------------------------------------ + +void GoldbaseUser::lastread(ulong __lastread) { + + seekread(); + record->highmsgread = (long)__lastread; + seekwrite(); +} + + +// ------------------------------------------------------------------ + +void GoldbaseUser::recinit(const char* __name) { + + GUser::recinit(__name); + strc2p(record->name); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrgold.h b/goldlib/gall/gusrgold.h new file mode 100644 index 0000000..29e310f --- /dev/null +++ b/goldlib/gall/gusrgold.h @@ -0,0 +1,121 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Goldbase derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrgold_h +#define __gusrgold_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Goldbase userfile (USERS.DAT) (QuickBBS 2.80 Gamma-3 structure) + +struct GoldUsers { + + char name[36]; + char city[26]; + byte reservedzero; + byte language; + long pwdcrc; + word pwdchangedate; + word expiredate; + long highmsgread; + byte extraspace[2]; + char dataphone[13]; + char homephone[13]; + char lasttime[6]; + char lastdate[9]; + byte attrib; + byte flagsx[4]; + word credit; + word pending; + word timesposted; + word obsoletefield; + word seclvl; + word times; + word ups; + word downs; + word upk; + word downk; + short todayk; + short elapsed; + short len; + word combinedptr; + word aliasptr; + long birthday; +}; + + +// ------------------------------------------------------------------ +// Goldbase userfile attributes + +#define GOLD_USERDELETED 0x0001 + + +// ------------------------------------------------------------------ +// Goldbase userfile class + +class GoldbaseUser : public GUser { + +public: + + GoldUsers* record; + + GoldbaseUser(); + ~GoldbaseUser(); + + int isvalid(); + int read(); + + void inctimesposted(int __times); + ulong lastread(); + void lastread(ulong __lastread); + void recinit(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrhuds.cpp b/goldlib/gall/gusrhuds.cpp new file mode 100644 index 0000000..dea3f03 --- /dev/null +++ b/goldlib/gall/gusrhuds.cpp @@ -0,0 +1,114 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +HudsonUser::HudsonUser() { + + recsize = sizeof(HudsUsers); + record = new HudsUsers; throw_new(record); + recptr = (char*)record; + name = record->name; +} + + +// ------------------------------------------------------------------ + +HudsonUser::~HudsonUser() { + + throw_delete(record); +} + + +// ------------------------------------------------------------------ + +void HudsonUser::inctimesposted(int __times) { + + seekread(); + record->timesposted += (word)__times; + seekwrite(); +} + + +// ------------------------------------------------------------------ + +int HudsonUser::isvalid() { + + return not (record->attrib & HUDS_USERDELETED); +} + + +// ------------------------------------------------------------------ + +int HudsonUser::read() { + + if(fh != -1) { + + ::read(fh, record, sizeof(HudsUsers)); + STRNP2C(record->name); + + return isvalid(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +ulong HudsonUser::lastread() { + + seekread(); + return record->highmsgread; +} + + +// ------------------------------------------------------------------ + +void HudsonUser::lastread(ulong __lastread) { + + seekread(); + record->highmsgread = (word)__lastread; + seekwrite(); +} + + +// ------------------------------------------------------------------ + +void HudsonUser::recinit(const char* __name) { + + GUser::recinit(__name); + strc2p(record->name); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrhuds.h b/goldlib/gall/gusrhuds.h new file mode 100644 index 0000000..a51ea58 --- /dev/null +++ b/goldlib/gall/gusrhuds.h @@ -0,0 +1,122 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrhuds_h +#define __gusrhuds_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Hudson userfile (USERS.BBS) (QuickBBS 2.80 Gamma-3 structure) +// sizeof = 158 + +struct HudsUsers { + + char name[36]; + char city[26]; + byte reservedzero; + byte language; + long pwdcrc; + word pwdchangedate; + word expiredate; + long unusedspace; + byte extraspace[2]; + char dataphone[13]; + char homephone[13]; + char lasttime[6]; + char lastdate[9]; + byte attrib; + byte flagsx[4]; + word credit; + word pending; + word timesposted; + word highmsgread; + word seclvl; + word times; + word ups; + word downs; + word upk; + word downk; + short todayk; + short elapsed; + short len; + word combinedptr; // record number in COMBINED.* + word aliasptr; // record number in ALIAS.* + long birthday; +}; + + +// ------------------------------------------------------------------ +// Hudson userfile attributes + +#define HUDS_USERDELETED 0x0001 + + +// ------------------------------------------------------------------ +// Hudson userfile class + +class HudsonUser : public GUser { + +public: + + HudsUsers* record; + + HudsonUser(); + ~HudsonUser(); + + int isvalid(); + int read(); + + void inctimesposted(int __times); + ulong lastread(); + void lastread(ulong __lastread); + void recinit(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrmax.cpp b/goldlib/gall/gusrmax.cpp new file mode 100644 index 0000000..68428da --- /dev/null +++ b/goldlib/gall/gusrmax.cpp @@ -0,0 +1,119 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Maximus userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +MaximusUser::MaximusUser() { + + recsize = sizeof(MaxUsers); + recptr = new char [recsize]; throw_new(recptr); + + record = (MaxUsers*)recptr; + memset(record, 0, recsize); + + name = record->name; + record->struct_len = (byte)(recsize / 20); + + firstread = true; +} + + +// ------------------------------------------------------------------ + +MaximusUser::~MaximusUser() { + + throw_deletearray(recptr); +} + + +// ------------------------------------------------------------------ + +int MaximusUser::isvalid() { + + return not (record->delflag & MAXIMUS_USERDELETED); +} + + +// ------------------------------------------------------------------ + +int MaximusUser::read() { + + if(fh != -1) { + if(firstread) { + firstread = false; + if(filelength(fh) >= 180) { + ::read(fh, record, recsize); + lseek(fh, -(long)recsize, SEEK_CUR); + uint _tmp = record->struct_len ? record->struct_len*20 : 180; + if(_tmp != recsize) { + recsize = _tmp; + throw_deletearray(recptr); + recptr = new char [recsize]; throw_new(recptr); + record = (MaxUsers*)recptr; + name = record->name; + } + } + } + ::read(fh, record, recsize); + if(isvalid()) { + index = record->lastread_ptr; + maxindex = maximum_of_two(index, maxindex); + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +void MaximusUser::founduser() { + + index = record->lastread_ptr; + found = true; +} + + +// ------------------------------------------------------------------ + +void MaximusUser::recinit(const char* __name) { + + GUser::recinit(__name); + record->lastread_ptr = (word)(++maxindex); + record->struct_len = (byte)(recsize / 20); + record->delflag = MAXIMUS_USERPERMANENT; + record->priv = MAXIMUS_PRIV_TWIT; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gusrmax.h b/goldlib/gall/gusrmax.h new file mode 100644 index 0000000..019e086 --- /dev/null +++ b/goldlib/gall/gusrmax.h @@ -0,0 +1,164 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Maximus derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrmax_h +#define __gusrmax_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Maximus structure for USER.BBS and LASTUSER.BBS + +struct MaxUsers { + + char name[36]; // Caller's name + char city[36]; // Caller's location + + char alias[21]; // MAX: user's alias (handle) + char phone[15]; // MAX: user's phone number + + word lastread_ptr; // MAX: a num which points to offset in LASTREAD + // file -- Offset of lastread pointer will be + // lastread_ptr*sizeof(int). + + word timeremaining; // MAX: time left for current call (xtern prog) + + char pwd[16]; // Password + word times; // Number of previous calls to this system + byte help; // Help level + byte rsvd1[2]; // Reserved by Maximus for future use + byte video; // user's video mode (see GRAPH_XXXX) + byte nulls; // Number of Nulls (delays) after + + byte bits; // Bit flags for user (number 1) + + word rsvd2; // Reserved by Maximus for future use + + word bits2; // Bit flags for user (number 2) + + word priv; // Access level + byte rsvd3[19]; // Reserved by Maximus for future use + byte struct_len; // len of struct, divided by 20. SEE ABOVE! + word time; // Time on-line so far today + + word delflag; // Used to hold baud rate for O)utside command + // In USER.BBS, usr.flag uses the constants + // UFLAG_xxx, defined earlier in this file. + + byte rsvd4[8]; // Reserved by Maximus for future use + + byte width; // Width of the caller's screen + byte len; // Height of the caller's screen + word credit; // Matrix credit, in cents + word debit; // Current matrix debit, in cents + + word xp_priv; // Priv to demote to, when time or minutes run + // out. + + FTime xp_date; // Bit-mapped date of when user expires. + // If zero, then no expiry date. + + dword xp_mins; // How many minutes the user has left before + // expiring. + + byte xp_flag; // Flags for expiry. See above XFLAG_XXX defs. + byte xp_rsvd; + + FTime ludate; // Bit-mapped date of user's last call + + dword xkeys; // User's keys (all 32 of 'em) + byte lang; // The user's current language # + byte def_proto; // Default file-transfer protocol + + dword up; // K-bytes uploaded, all calls + dword down; // K-bytes downloaded, all calls + dword downtoday; // K-bytes downloaded, today + + char msg[10]; // User's last msg area (string) + char files[10]; // User's last file area (string) + + byte compress; // Default compression program to use + + byte rsvd5; + dword extra; +}; + + +// ------------------------------------------------------------------ +// Maximus userfile constants + +#define MAXIMUS_USERDELETED 0x0001 +#define MAXIMUS_USERPERMANENT 0x0002 + +#define MAXIMUS_PRIV_TWIT 0xFFFE + + +// ------------------------------------------------------------------ +// Maximus userfile class + +class MaximusUser : public GUser { + +public: + + uint maxindex; + int firstread; + MaxUsers* record; + + MaximusUser(); + ~MaximusUser(); + + int isvalid(); + int read(); + + void founduser(); + void recinit(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrpcb.cpp b/goldlib/gall/gusrpcb.cpp new file mode 100644 index 0000000..3380a75 --- /dev/null +++ b/goldlib/gall/gusrpcb.cpp @@ -0,0 +1,119 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard 15.xx userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +PcbUser::PcbUser() { + + fhinf = -1; + recsize = sizeof(PcbUsers); + record = new PcbUsers; throw_new(record); + recptr = (char*)record; + name = record->name; +} + + +// ------------------------------------------------------------------ + +PcbUser::~PcbUser() { + + throw_delete(record); +} + + +// ------------------------------------------------------------------ + +int PcbUser::isvalid() { + + return record->deleteflag == 'N'; +} + + +// ------------------------------------------------------------------ + +int PcbUser::read() { + + if(fh != -1) { + ::read(fh, record, sizeof(PcbUsers)); + return isvalid(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +void PcbUser::recinit(const char* __name) { + + GUser::recinit(__name); +} + + +// ------------------------------------------------------------------ + +void PcbUser::add(const char*) { + +} + + +// ------------------------------------------------------------------ + +void PcbUser::update_mail_waiting(const char* __name, int __confno, int __status) { + + if(find(__name)) { + byte bitmask = 0x04; + if(__status) + record->bitflags |= bitmask; + else + record->bitflags &= (byte)~bitmask; + seekwrite(); + long _offset = (record->usersinfrec-1)*usershdr->totalrecsize; + _offset += usershdrsize; + _offset += usershdr->sizeofrec; + _offset += __confno / 8; + lseek(fhinf, _offset, SEEK_SET); + byte mailwaitingflags = 0; + ::read(fhinf, &mailwaitingflags, 1); + bitmask = (byte)(1 << (__confno % 8)); + if(__status) + mailwaitingflags |= bitmask; + else + mailwaitingflags &= (byte)~bitmask; + lseek(fhinf, _offset, SEEK_SET); + ::write(fhinf, &mailwaitingflags, 1); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrpcb.h b/goldlib/gall/gusrpcb.h new file mode 100644 index 0000000..d971d0b --- /dev/null +++ b/goldlib/gall/gusrpcb.h @@ -0,0 +1,151 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard 15.xx derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrpcb_h +#define __gusrpcb_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// PCBoard Users Record (USERS. file) + +struct PcbUsers { + + char name[25]; // Full Name + char city[24]; // City + char password[12]; // Password + char dataphone[13]; // Business / Data Phone Number + char voicephone[13]; // Home / Voice Phone Number + char lastdateon[6]; // Last Date On (format: YYMMDD) + char lasttimeon[5]; // Last Time On (format HH:MM) + char expertmode; // Expert Mode (Y or N) + char protocol; // Default Transfer Protocol (A-Z, 0-9) + byte bitflags; // Bit Flags (see below) + char dateoflastdirscan[6]; // Date of Last DIR Scan (most recent file found) + byte securitylevel; // Security Level (0-255) + short timesonline; // Number of Times On + byte pagelength; // Page Length (# lines displayed before prompt) + short filesuploaded; // Number of Files Uploaded + short filesdownloaded; // Number of Files Downloaded + dword bytesdownloadedtoday[2]; // Total Bytes Downloaded Today + char userscomment[30]; // Comment Field #1 (user comment) + char sysopcomment[30]; // Comment Field #2 (sysop comment - user can't see) + short elapsedtimeon; // Elapsed Time On (in minutes) + char regexpirationdate[6]; // Registration Expiration Date (YYMMDD) + byte expiredregseclevel; // Expired Registration - Security Level + byte lastconferenceinold; // Last Conference In (used for v14.x compatibility) + byte confregflags[5]; // Conference Registration Flags (conf 0-39) + byte expiredconfregflags[5]; // Expired Registration Conference Flags (conf 0-39) + byte usersconfflags[5]; // User Selected Conference Flags (conf 0-39) + dword totalbytesdownloaded[2]; // Total Bytes Downloaded + dword totalbytesuploaded[2]; // Total Bytes Uploaded + char deleteflag; // Delete Flag (Y or N) + dword lastmsgread[40]; // Last Message Read pointer (conference 0-39) + long usersinfrec; // Record Number of USERS.INF Record + byte bitflags2; // Bit Flags 2 (see below) + char reserved[8]; // Reserved (do not use) + short lastconferencein; // Last Conference In (used instead of offset 192) +}; + + +// ------------------------------------------------------------------ +// PCBoard Users Inf Header Record (in USERS.INF file) + +struct PcbUsersInfHdr { + + ushort version; // PCBoard Version Number + ushort numofconf; // Number of EXTENDED Conferences Allocated in File + ushort sizeofrec; // Size of the 'static' PCBoard User Record + long sizeofconf; // Total Size of PCBoard Conference Information + ushort numofapps; // Number of Third Party Apps adding onto the record + long totalrecsize; // Total Record Size (PCB and all TPA components) +}; + + +// ------------------------------------------------------------------ +// PCBoard Users Inf App Record (in USERS.INF file) + +struct PcbUsersInfApp { + + char name[15]; // Name of Application (NULL terminated) + ushort version; // Version Number + ushort sizeofrec; // Size of Application Record information (0-65535) + ushort sizeofconfrec; // Size of Conference Record information (0-65535) + char keyword[9]; // Keyword to execute Application (NULL terminated) + long offset; // Offset in User Record where TPA record begins +}; + + +// ------------------------------------------------------------------ +// PCBoard 15.xx userfile class + +class PcbUser : public GUser { + +public: + + int fhinf; + + PcbUsers* record; + PcbUsersInfHdr* usershdr; + long usershdrsize; + + PcbUser(); + ~PcbUser(); + + int isvalid(); + int read(); + + void recinit(const char* __name); + + void add(const char* __name); + + void update_mail_waiting(const char* __name, int __confno, int __status); +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrra2.cpp b/goldlib/gall/gusrra2.cpp new file mode 100644 index 0000000..53a62df --- /dev/null +++ b/goldlib/gall/gusrra2.cpp @@ -0,0 +1,152 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// RemoteAccess 2.x userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +RA2User::RA2User() { + + xifh = -1; + idxfh = -1; + + recsize = sizeof(RA2Users); + + record = new RA2Users; throw_new(record); + xirec = new RA2UsersXi; throw_new(xirec); + idxrec = new RA2UsersIdx; throw_new(idxrec); + + recptr = (char*)record; + name = record->name; +} + + +// ------------------------------------------------------------------ + +RA2User::~RA2User() { + + throw_delete(record); + throw_delete(idxrec); + throw_delete(xirec); +} + + +// ------------------------------------------------------------------ + +void RA2User::inctimesposted(int __times) { + + seekread(); + record->msgsposted += (word)__times; + seekwrite(); +} + + +// ------------------------------------------------------------------ + +int RA2User::isvalid() { + + return not (record->attribute & RA2_USERDELETED); +} + + +// ------------------------------------------------------------------ + +int RA2User::read() { + + if(fh != -1) { + + ::read(fh, record, sizeof(RA2Users)); + STRNP2C(record->name); + + return isvalid(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +ulong RA2User::lastread() { + + seekread(); + return record->lastread; +} + + +// ------------------------------------------------------------------ + +void RA2User::lastread(ulong __lastread) { + + seekread(); + record->lastread = (long)__lastread; + seekwrite(); +} + + +// ------------------------------------------------------------------ + +void RA2User::recinit(const char* __name) { + + GUser::recinit(__name); + strc2p(record->name); + strcpy(record->handle, __name); + strc2p(record->handle); +} + + +// ------------------------------------------------------------------ + +void RA2User::add(const char* __name) { + + GUser::add(__name); + + if(idxfh != -1) { + + char _namebuf[36]; + strupr(strcpy(_namebuf, __name)); + idxrec->namecrc32 = idxrec->handlecrc32 = strCrc32(_namebuf, NO, CRC32_MASK_CCITT); + + lseek(idxfh, (long)recno*(long)sizeof(RA2UsersIdx), SEEK_SET); + ::write(idxfh, idxrec, sizeof(RA2UsersIdx)); + } + + if(xifh != -1) { + + memset(xirec, 0, sizeof(RA2UsersXi)); + + lseek(xifh, (long)recno*(long)sizeof(RA2UsersXi), SEEK_SET); + ::write(xifh, xirec, sizeof(RA2UsersXi)); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrra2.h b/goldlib/gall/gusrra2.h new file mode 100644 index 0000000..710e718 --- /dev/null +++ b/goldlib/gall/gusrra2.h @@ -0,0 +1,165 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// RemoteAccess 2.x derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrra2_h +#define __gusrra2_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// RA2 USERS.BBS record structure +// sizeof = 1016 + +struct RA2Users { + + char name[36]; + char location[26]; + char organisation[51]; + char address1[51]; + char address2[51]; + char address3[51]; + char handle[36]; + char comment[81]; + long passwordcrc; + char dataphone[16]; + char voicephone[16]; + char lasttime[6]; + char lastdate[9]; + byte attribute; + byte attribute2; + byte flagsx[4]; + long credit; + long pending; + word msgsposted; + word security; + long lastread; + long nocalls; + long uploads; + long downloads; + long uploadsk; + long downloadsk; + long todayk; + short elapsed; + word screenlength; + byte lastpwdchange; + word group; + word combinedinfo[200]; + char firstdate[9]; + char birthdate[9]; + char subdate[9]; + byte screenwidth; + byte language; + byte dateformat; + char forwardto[36]; + word msgarea; + word filearea; + char defaultprotocol; + word filegroup; + byte lastdobcheck; + byte sex; + long xirecord; + word msggroup; + byte freespace[48]; +}; + + +// ------------------------------------------------------------------ +// RA2 userfile attributes + +#define RA2_USERDELETED 0x0001 + + +// ------------------------------------------------------------------ +// RA2 USERSIDX.BBS record structure + +struct RA2UsersIdx { + + dword namecrc32; + dword handlecrc32; +}; + + +// ------------------------------------------------------------------ +// RA2 USERSXI.BBS record structure + +struct RA2UsersXi { + + byte freespace[200]; +}; + + +// ------------------------------------------------------------------ +// RemoteAccess 2.x userfile class + +class RA2User : public GUser { + +public: + + int xifh; + int idxfh; + + RA2Users* record; + RA2UsersXi* xirec; + RA2UsersIdx* idxrec; + + RA2User(); + ~RA2User(); + + int isvalid(); + int read(); + + void inctimesposted(int __times); + ulong lastread(); + void lastread(ulong __lastread); + void recinit(const char* __name); + + void add(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrwcat.h b/goldlib/gall/gusrwcat.h new file mode 100644 index 0000000..a16a0e0 --- /dev/null +++ b/goldlib/gall/gusrwcat.h @@ -0,0 +1,124 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrwcat_h +#define __gusrwcat_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +struct WCatUserConfFileHdr { + word totalconfs; +}; + + +// ------------------------------------------------------------------ + +const byte ucrIndex = 0; +const byte ucrData = 1; + +struct WCatUserConfIndex { + word reclen; + byte rectype; + long offsets[32]; +}; + +struct WCatUserConfData { + byte flags; + word lastread; + word firstunread; +}; + +typedef WCatUserConfData WCatUserConfArray[1024]; + +struct WCatUserConfPageHeader { + word reclen; + byte rectype; + long userid; + short page; + long thisx; +}; + +struct WCatUserConfPage { + word reclen; + byte rectype; + long userid; + short page; + long thisx; + WCatUserConfArray userconfdata; +}; + +#define MaxChunk 1024 +#define MaxPages(MaxConfAreas) ((MaxConfAreas+MaxChunk-1)/MaxChunk) + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ +// WildCat! userfile class + +class WCatUser : public GUser { + +public: + + uint maxindex; + int firstread; + WCatUserConfIndex header; + + WCatUser(); + ~WCatUser(); + + int isvalid(); + int read(); + + void founduser(); + void recinit(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrxbbs.cpp b/goldlib/gall/gusrxbbs.cpp new file mode 100644 index 0000000..e9bc623 --- /dev/null +++ b/goldlib/gall/gusrxbbs.cpp @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS userfile class implementation. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +XbbsUser::XbbsUser() { + + recsize = sizeof(XbbsUsers); + record = new XbbsUsers; throw_new(record); + recptr = (char*)record; + name = record->name; +} + + +// ------------------------------------------------------------------ + +XbbsUser::~XbbsUser() { + + throw_delete(record); +} + + +// ------------------------------------------------------------------ + +int XbbsUser::isvalid() { + + return not (record->attribs & U_DELETED); +} + + +// ------------------------------------------------------------------ + +int XbbsUser::read() { + + if(fh != -1) { + ::read(fh, record, sizeof(XbbsUsers)); + return isvalid(); + } + + return false; +} + + +// ------------------------------------------------------------------ + +void XbbsUser::recinit(const char* __name) { + + GUser::recinit(__name); +} + + +// ------------------------------------------------------------------ + +void XbbsUser::add(const char*) { + +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gusrxbbs.h b/goldlib/gall/gusrxbbs.h new file mode 100644 index 0000000..25f152f --- /dev/null +++ b/goldlib/gall/gusrxbbs.h @@ -0,0 +1,210 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS derived userfile class. +// ------------------------------------------------------------------ + +#ifndef __gusrxbbs_h +#define __gusrxbbs_h + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// AdeptXBBS structure for "Users" file + +// The following flags are used for the 'user.attribs' bits. +#define U_ANSI 0x00000001 // Ansi Movement +#define U_COLOR 0x00000002 // Ansi Color +#define U_HIGHASCII 0x00000004 // High Ascii +#define U_NOMORE 0x00000008 // No? More? Prompts +#define U_NOCLEAR 0x00000010 // Don't Clear Screens +#define U_COLD 0x00000020 // No Hot Keys +#define U_NOSHOWADDRESS 0x00000040 // Don't show address in user list +#define U_NOSHOWPHONE 0x00000080 // Don't show phone numbers in user list +#define U_NOSHOWREAL 0x00000100 // Don't show real names in user list +#define U_NOKILL 0x00000200 // User cannot be killed/deleted +#define U_DELETED 0x00000400 // User marked as deleted +#define U_EXPERT 0x00000800 // User set for expert mode +#define U_TWIT 0x00001000 // User is a twit! +#define U_NEWFILES 0x00002000 // New files search at logon +#define U_NEWMSGS 0x00004000 // New message search at logon +#define U_DLNEWMSGS 0x00008000 // Auto download mail packets at logon +#define U_DLNEWFILELIST 0x00010000 // Auto download new file list at logon +#define U_SEENEWS 0x00020000 // Sees new news +#define U_ASKDL 0x00040000 // Ask logoff before download +#define U_NOVICE 0x00080000 // User set to novice +#define U_NOROLL 0x00100000 // no rolling prompts (obsolete) +#define U_POINTONLY 0x00200000 // Fidonet point mail only +#define U_LOCKEDOUT 0x00400000 // User locked out +#define U_AVAILABLE 0x00800000 // Available for multi-node chat +#define U_LISTPROTECTED 0x01000000 // Not shown in user list +#define U_MISCNEWSOK 0x02000000 // Sees misc. news +#define U_LIMITFLIST 0x04000000 // Limit file list to current area +#define U_EBCDIC 0x08000000 // EBCDIC <-> ASCII Conversion +#define U_VERIFIED 0x10000000 // user call back verified, turn this off, they get verified again.. (if BBS verifies) +#define U_ANSITE2 0x20000000 // User supports Ansi-TE2 Special Chars +#define U_RIPSCRIPT 0x40000000 // User has RIP Support +#define U_AVATAR 0x80000000 // User has Avatar Support + +// The following flags are used for 'user.attribs2' bits. +#define U2_FSE 0x00000001 // User Full Screen Message Editor +#define U2_OFF_AFTER_MAIL 0x00000002 // Log off after mail download +#define U2_MONITOR_MAIL 0x00000004 // Monitor mail export/packing +#define U2_INT_NEW_FILES 0x00000008 // include new files in mail packet +#define U2_INC_BULLETS 0x00000010 // include bulletins in mail packet +#define U2_INC_WELCOME 0x00000020 // include welcome screen in mail packet +#define U2_DEFAULT_QWK 0x00000040 // Default use to QWK mail +#define U2_DEFAULT_FIDO 0x00000080 // Default use to Fidonet Point Mail +#define U2_DEFAULT_TEXT 0x00000100 // Default to text export +#define U2_DEFAULT_BLUE 0x00000200 // Default to Bluewave Mail +#define U2_AVTANS 0x00000400 // Can handle both ANSI and Avatar +#define U2_8DOT3 0x00000800 // Convert long names to 8.3 names + +struct XbbsUsers { + char name[36]; // Users Name + char handle[36]; // Users Handle + char address[60]; // Address line 1 + char address1[60]; // Address line 2 + char address2[60]; // Address line 3 + char city[20]; // Users City/County + char state[5]; // Users State + char zipcode[10]; // Users ZipCode + char home_phone[21]; // Users home phone number + char data_phone[21]; // Users data phone number + char fax_phone[21]; // Users fax phone number + char bus_phone[21]; // Users business/office number + char interests[78]; // Interest Line + char SysOpComment[78]; // Room for Sysops comment + ushort banktime; // Time in the bank + ushort computer_type; // Computer type + long userid; // User ID + short pointid; // Point Mail ID + time_t initial_logon; // Time/Date of initial logon + time_t expires; // Time/Date user expires + time_t last_logon; // Time/Date of last logon + time_t logon_today; // Last time the user logged on today + short birthyear; // Birth Year + char birthmonth; // Birth Month + char birthday; // Birth day + char gender; // Gender + long credit; // User credit + long minlimit; // Minimum limit + long group; // Group number the user belongs to + long currlastread; // Last read pointer for current area + long time_today; // Number of minutes user used today + long time_per_day; // Time limit per day + long time_per_call; // Time limit per call + long numcalls; // Number of total calls user made to BBS + long ulnum; // Total number of uploads + long dlnum; // Total number of downloads + long ulk; // Total uploads in K-bytes + long dlk; // Total downloads in K-bytes + long uktoday; // Uploads in K-bytes made today + long dktoday; // Download in k-bytes made today + long ukperday; // Max k-bytes user can upload a day + long dkperday; // Max k-byes a user can download a day + long numposts; // Number of messages ever written + long security1; // Security level #1 + long security2; // Security level #2 + long flags1; // Sysop definable 32 flags + long flags2; // Sysop definable 32 flags + long attribs; // User attributes + long attribs2; // User attributes + short length; // Screen length + short width; // Screen width + short lastmsgarea; // Last message area user was in + short lastfilearea; // Last file area user was in + char lastprotocol; // Last protocol user chose + char lastarchiver; // Last archiver user chose + long forsysop; // unused + char interface_; // obsolete + char exp; // unused + short leech_percent; // File leech ratio + short maxbanktime; // Maximum time user can have in bank + short timecredit; // Current time user has credit for + short callstoday; // Number of calls user made to BBS today + long totalminsever; // Total minutes users has used ever + long netmaildebits; // Total spent on NetMail + time_t lastpwchange; // Time/Date of last password change + time_t lastlistednewfile; // Time/Date user last listed new files + ulong filekcredit; // Amount of file k-byte credit user has + char unixid[8]; // Users Unix Specific ID + byte _unused[94]; // reserved for future use + byte mailtags[128]; // Message areas tagged for off-line mail + byte usermsg[128]; // Message areas user can access + byte userfile[128]; // File areas user can access + ulong passwordcrc; // User password CRC + ulong passwordcrc2; // User password CRC2 + ushort max_mail_pkt; // Max msgs to pack for off-line mail + char reasked; // Has user answered the ReAsk questionairre + char reserved[75]; // reserved for future user +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ +// AdeptXBBS userfile class + +class XbbsUser : public GUser { + +public: + + uint maxindex; + int firstread; + XbbsUsers* record; + + XbbsUser(); + ~XbbsUser(); + + int isvalid(); + int read(); + + void recinit(const char* __name); + void add(const char* __name); +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlclip.cpp b/goldlib/gall/gutlclip.cpp new file mode 100644 index 0000000..921eafb --- /dev/null +++ b/goldlib/gall/gutlclip.cpp @@ -0,0 +1,160 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Misc. clipboards support. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +int clipboard_available = -1; +char *fake_clipboard = NULL; + + +// ------------------------------------------------------------------ + +void fake_clipboard_destroy() { + + if(fake_clipboard) + throw_free(fake_clipboard); +} + + +// ------------------------------------------------------------------ + +gclipbrd::gclipbrd() { + + len = -1; + clipdata = NULL; + cliphdl = NULL; + #if defined(GUTLOS_FUNCS) + if(clipboard_available == -1) + clipboard_available = g_is_clip_available() ? 1 : 0; + #else + clipboard_available = 0; + #endif + if(not clipboard_available and not fake_clipboard) { + fake_clipboard = throw_strdup(""); + atexit(fake_clipboard_destroy); + } +} + + +// ------------------------------------------------------------------ + +bool gclipbrd::openread() { + + if(not clipboard_available) { + + cliphdl = clipdata = fake_clipboard; + if(fake_clipboard != NULL) { + len = strlen(cliphdl); + return true; + } + else + return false; + } + + #if defined(GUTLOS_FUNCS) + cliphdl = clipdata = g_get_clip_text(); + if (clipdata != NULL) { + len = strlen(clipdata); + return true; + } + #endif + + return false; +} + + +// ------------------------------------------------------------------ + +bool gclipbrd::writeclipbrd(char* buf) { + + if(not clipboard_available) { + if(fake_clipboard) + throw_free(fake_clipboard); + fake_clipboard = throw_strdup(buf); + return (fake_clipboard != NULL) ? true : false; + } + + #if defined(GUTLOS_FUNCS) + return (g_put_clip_text(buf) == 0) ? true : false; + #else + return false; + #endif +} + + +// ------------------------------------------------------------------ + +char* gclipbrd::read(char* buffer, int maxlen) { + + if(len>0) { + int i = MinV(len, maxlen); + char* p = strpbrk(clipdata, "\r\n"); + if(p and (p-clipdata < i)) { + i = p - clipdata; + if(len > i and strchr("\r\n", *(p+1)) and (*p != *(p+1))) + ++i; + } + strxcpy(buffer, clipdata, ++i); + char* p2 = strpbrk(buffer, "\r\n"); + if(p2) *p2 = 0; + if(p) strcat(buffer, "\n"); + len -= MinV(len, i); + clipdata += i; + return buffer; + } + + return NULL; +} + + +// ------------------------------------------------------------------ + +void gclipbrd::close() { + + if(not clipboard_available) + return; + + #if defined(GUTLOS_FUNCS) + if(len>=0) { + if (cliphdl != NULL) + throw_free(cliphdl); + len = -1; + cliphdl = clipdata = NULL; + } + #endif +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gutlclip.h b/goldlib/gall/gutlclip.h new file mode 100644 index 0000000..e45ab26 --- /dev/null +++ b/goldlib/gall/gutlclip.h @@ -0,0 +1,72 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Goldware misc. clipboards support. +// ------------------------------------------------------------------ + +#ifndef __gutlclip_h +#define __gutlclip_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(__OS2__) +#define CLIP_NAME "OS/2 Clipboard" +#elif defined(__WIN32__) or defined(__MSDOS__) +#define CLIP_NAME "Windows Clipboard" +#else +#define CLIP_NAME "Fake Clipboard" +#endif + + +// ------------------------------------------------------------------ + +class gclipbrd { + + char *clipdata, *cliphdl; + int len; + +public: + + bool openread(); + char* read(char* buffer, int maxlen); + void close(); + + bool writeclipbrd(char* buf); + + gclipbrd(); + +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlcode.cpp b/goldlib/gall/gutlcode.cpp new file mode 100644 index 0000000..6a4bca7 --- /dev/null +++ b/goldlib/gall/gutlcode.cpp @@ -0,0 +1,291 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Decoder/encoders. +// ------------------------------------------------------------------ + +#ifdef __GNUG__ +#pragma implementation "gutlcode.h" +#endif + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +uucode_engine::uucode_engine() { + + initialized = false; +} + + +// ------------------------------------------------------------------ + +void uucode_engine::initialize() { + + // Set up the default translation table. + int i, j; + for(i=0; i<' '; i++) + table.ch[i] = -1; + for(i=' ',j=0; i<' '+64; i++,j++) + table.ch[i] = j; + for(i=' '+64; i<256; i++) + table.ch[i] = -1; + table.ch['`'] = table.ch[' ']; // A common mutation + table.ch['~'] = table.ch['^']; // Another common mutation + table.blank = ' '; + + // Set up the line length table, to avoid computing lotsa * and / ... + table.len[0] = 1; + for(i=1,j=5; i<=60; i+=3, j+=4) + table.len[i] = (table.len[i+1] = (table.len[i+2] = j)); + + initialized = true; + complete = false; +} + + +// ------------------------------------------------------------------ + +char* uucode_engine::decode(char* outputbuffer, const char* inputbuffer) { + + char buf[80]; + char* o = outputbuffer; + int len = strlen(strcpy(buf, inputbuffer)); + + if(not initialized) + initialize(); + + if(strnieql(buf, "begin ", 6)) { + return o; + } + else if(strieql(buf, "end")) { + initialized = false; + complete = true; + return o; + } + else if(strieql(buf, "table")) { + defining_table = true; + for(int c=0; c<256; c++) + table.ch[c] = -1; + table_index = 0; + return o; + } + + if(defining_table) { + char* p = buf + len - 1; + *p = ' '; + while(*p == ' ') + *p-- = 0; + p = buf; + char c; + while((c = *p) != 0) { + if(table_index == 0) + table.blank = c; + table.ch[c] = table_index++; + if(table_index >= 64) { + defining_table = false; + break; + } + p++; + } + return o; + } + + // Get the binary line length. + int n = table.ch[*buf]; + if(n > 0) { + + // Pad with blanks. + int c = len; + char* i = buf + c; + int rlen = table.len[n]; + while(c < rlen) { + *i++ = table.blank; + c++; + } + + // Output a group of 3 bytes (4 input characters). + i = buf + 1; + while(n > 0) { + *(o++) = (char)((table.ch[*i] << 2) | (table.ch[i[1]] >> 4)); + n--; + if(n) { + *(o++) = (char)((table.ch[i[1]] << 4) | (table.ch[i[2]] >> 2)); + n--; + } + if(n) { + *(o++) = (char)((table.ch[i[2]] << 6) | table.ch[i[3]]); + n--; + } + i += 4; + } + } + + *o = NUL; + + return o; +} + + +// ------------------------------------------------------------------ + +char* quoted_printable_engine::decode(char* outputbuffer, const char* inputbuffer) { + + char c; + char* o = outputbuffer; + const char* i = inputbuffer; + + while((c = *i) != NUL) { + if(c == '=') { + char c1 = i[1]; + char c2 = i[2]; + if(isxdigit(c1) and isxdigit(c2)) { + // Decode the character + c = (char)((xtoi(c1) << 4) | xtoi(c2)); + i += 2; + } + } + //else if(c == '_') { + // c = ' '; + //} + *o++ = c; + i++; + } + + *o = NUL; + + return o; +} + + +// ------------------------------------------------------------------ + +char* base64_engine::decode(char* outputbuffer, const char* inputbuffer) { + + char* o = outputbuffer; + const char* i = inputbuffer; + + int shift = 0; + ulong accum = 0; + while(*i) { + char c = *i; + uint value = (uint)-1; + if((c >= 'A') and (c <= 'Z')) value = c - 'A'; + else if((c >= 'a') and (c <= 'z')) value = 26 + c - 'a'; + else if((c >= '0') and (c <= '9')) value = 52 + c - '0'; + else if(c == '+') value = 62; + else if(c == '/') value = 63; + else if(c == '=') value = (uint)-2; + if(value >= 64) + break; + else { + accum <<= 6; + shift += 6; + accum |= value; + if(shift >= 8) { + shift -= 8; + value = (uint)(accum >> shift); + c = (byte)(value & 0xFF); + *o++ = c; + } + } + i++; + } + + *o = NUL; + + return o; +} + + +// ------------------------------------------------------------------ + +char base64_engine::table[64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' +}; + + +// ------------------------------------------------------------------ + +char* base64_engine::encode(char* outputbuffer, const char* inputbuffer, uint length, bool padding) { + + uint l = length; + char* o = outputbuffer; + const char* i = inputbuffer; + + while(l > 0) { + + char c1 = i[0]; + char c2 = l > 1 ? i[1] : '\0'; + char c3 = l > 2 ? i[2] : '\0'; + int pads = l > 2 ? 0 : (3 - l); + + o[0] = table[c1 >> 2]; + o[1] = table[((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4)]; + if(pads == 2) { + if(padding) { + o[2] = '='; + o[3] = '='; + } + else { + o[2] = NUL; + o[3] = NUL; + } + } + else if(pads == 1) { + o[2] = table[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]; + if(padding) { + o[3] = '='; + } + else { + o[3] = NUL; + } + } + else { + o[2] = table[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]; + o[3] = table[c3 & 0x3F]; + } + o += 4; + if(l < 3) + break; + l -= 3; + i += 3; + } + + *o = NUL; + + return o; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlcode.h b/goldlib/gall/gutlcode.h new file mode 100644 index 0000000..9f0e513 --- /dev/null +++ b/goldlib/gall/gutlcode.h @@ -0,0 +1,113 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Decoder/encoders. +// ------------------------------------------------------------------ + +#ifndef __gutlcode_h +#define __gutlcode_h + + +// ------------------------------------------------------------------ + +#ifdef __GNUG__ +#pragma interface "gutlcode.h" +#endif + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class code_engines { + +public: + + virtual char* decode(char* outputbuffer, const char* inputbuffer) = 0; +}; + + +// ------------------------------------------------------------------ + +class uucode_engine : public code_engines { + +protected: + + struct { + char blank; + int len[63]; + int ch[256]; + } table; + + int initialized; + int defining_table; + int table_index; + + void initialize(); + +public: + + int complete; + + uucode_engine(); + + char* decode(char* outputbuffer, const char* inputbuffer); +}; + + +// ------------------------------------------------------------------ + +class quoted_printable_engine : public code_engines { + +protected: + +public: + + char* decode(char* outputbuffer, const char* inputbuffer); +}; + + +// ------------------------------------------------------------------ + +class base64_engine : public code_engines { + +protected: + + static char table[64]; + +public: + + char* decode(char* outputbuffer, const char* inputbuffer); + char* encode(char* outputbuffer, const char* inputbuffer, uint length, bool padding=true); +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutldos.cpp b/goldlib/gall/gutldos.cpp new file mode 100644 index 0000000..b3deb2a --- /dev/null +++ b/goldlib/gall/gutldos.cpp @@ -0,0 +1,402 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Various WinOldAp functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#ifdef __DJGPP__ +#include +#include +#include +#include +#include +#endif + + +// ------------------------------------------------------------------ + +enum OSAPI { + NOAPI, + WIN3x, + WIN9x, + ANSIPLUS +}; + +OSAPI winapi; +char ge_win_oldtitle[GMAXTITLE] = ""; +char ge_win_title[GMAXTITLE] = ""; +int ge_win_ext_title; + + +// ------------------------------------------------------------------ + +int g_init_os(int flags) { + + NW(flags); + + i86 cpu; + + // Identify WinOldAp version + cpu.ax(0x1700); + cpu.genint(0x2f); + winapi = NOAPI; + if(cpu.ax() != 0x1700) { + winapi = WIN3x; + // Identify Windows version and type + cpu.ax(0x160a); + cpu.genint(0x2f); + if((cpu.ax() == 0x0000) and (cpu.bh() > 3)) + winapi = WIN9x; + } + else { + // Check for ANSIPLUS.SYS v4.00+ + cpu.ax(0x1a00); + cpu.bx(0x414e); + cpu.cx(0x5349); + cpu.dx(0x2b2b); + cpu.genint(0x2f); + if((cpu.al() == 0xff) and (cpu.ch() > 3)) + winapi = ANSIPLUS; + } + #ifdef __DJGPP__ + // reload internal djgpp structures for toupper/tolower + int segment, selector; + + if((segment = __dpmi_allocate_dos_memory(1, &selector)) != -1) { + cpu.ah(0x65); + cpu.al(0x02); + cpu.bx(0xffff); + cpu.dx(0xffff); + cpu.cx(5); + cpu.es(segment); + cpu.di(0); + cpu.genint(0x21); + if(not (cpu.flags() & 1) and (cpu.cx() == 5)) { + unsigned int table = _farpeekw(selector, 3) * 16 + _farpeekw(selector, 1); + int i, size = _farpeekw(_dos_ds, table); + movedata(_dos_ds, table + 2, _my_ds(), (unsigned int)&(toupper(128)), size); + // let's build lowercase table from uppercase... + for(i = 0; i < size; i++) { + int c = toupper(i + 128); + if((c != i + 128) and (c > 127)) + tolower(c) = i + 128; + } + for(i=128; i<256; i++) { + if((toupper(tolower(i)) != i) && (tolower(toupper(i)) != i)) + tolower(i) = toupper(i) = i; + if(toupper(tolower(i)) != toupper(i)) + toupper(i) = i; + if(tolower(toupper(i)) != tolower(i)) + tolower(i) = i; + } + } + __dpmi_free_dos_memory(selector); + } + #endif + g_get_ostitle_name(ge_win_oldtitle); + return 0; +} + + +// ------------------------------------------------------------------ + +void g_deinit_os(void) { + + if(*ge_win_oldtitle) + g_set_ostitle_name(ge_win_oldtitle, 1); +} + + +// ------------------------------------------------------------------ + +void g_init_title(char *tasktitle, int titlestatus) { + + strxcpy(ge_win_title, tasktitle, GMAXTITLE); + ge_win_ext_title = titlestatus; +} + + +// ------------------------------------------------------------------ + +void g_increase_priority(void) { + + // Do nothing +} + + +// ------------------------------------------------------------------ + +void g_set_ostitle(char* title, word dx) { + + if(winapi == WIN9x) { + + if(dx and not *title) + return; + + i86 cpu; + int segment, selector; + size_t len = strlen(title) + 1; + + segment = __dpmi_allocate_dos_memory((len >> 4) + 1, &selector); + if(segment == -1) + return; + movedata(_my_ds(), (unsigned)title, selector, 0, len); + // Set application title + cpu.ax(0x168e); + cpu.dx(dx); + cpu.es(segment); + cpu.di(0x0000); + cpu.genint(0x2f); + __dpmi_yield(); + __dpmi_free_dos_memory(selector); + } +} + + +// ------------------------------------------------------------------ + +void g_set_osicon(void) { + + // do nothing +} + + +// ------------------------------------------------------------------ + +bool g_is_clip_available(void) { + + return (winapi == NOAPI) ? false : true; +} + + +// ------------------------------------------------------------------ + +char* g_get_clip_text(void) { + + if(winapi == NOAPI) + return NULL; + + i86 cpu; + int seg, selector; + char* text = NULL; + size_t len; + + if((winapi == WIN3x) or (winapi == WIN9x)) { + + // Open clipboard + cpu.ax(0x1701); + cpu.genint(0x2f); + if(cpu.ax() == 0x0000) + return NULL; + + // Get clipboard data size + cpu.ax(0x1704); + cpu.dx(0x07); + cpu.genint(0x2f); + len = cpu.ax() + (cpu.dx() << 16); + if(len != 0) + if((seg = __dpmi_allocate_dos_memory(len >> 4, &selector)) != -1) { + // Get clipboard data + cpu.ax(0x1705); + cpu.dx(0x07); // OEM text + cpu.es(seg); + cpu.bx(0x0000); + cpu.genint(0x2f); + if(cpu.ax() != 0x0000) { + text = (char *) throw_malloc(len); + if(text) + movedata(selector, 0, _my_ds(), (unsigned) text, len); + } + __dpmi_free_dos_memory(selector); + } + + // Close clipboard + cpu.ax(0x1708); + cpu.genint(0x2f); + } + else { + // Get clipboard information + cpu.ax(0x1aa5); + cpu.dh(0x00); + cpu.genint(0x2f); + if(cpu.al() == 0x00) { + len = cpu.cx(); + if(len) + if((seg = __dpmi_allocate_dos_memory((len >> 4) + 1, &selector)) != -1) { + // Get clipboard text + cpu.ax(0x1aa5); + cpu.dh(0x01); + cpu.es(seg); + cpu.bx(0x0000); + cpu.genint(0x2f); + if(cpu.al() == 0x00) { + text = (char *) throw_malloc(len); + if(text) + movedata(selector, 0, _my_ds(), (unsigned) text, len); + } + __dpmi_free_dos_memory(selector); + } + } + } + + return text; +} + + +// ------------------------------------------------------------------ + +int g_put_clip_text(char* buf) { + + if(winapi == NOAPI) + return -1; + + i86 cpu; + int seg, selector; + int result = -1; + size_t len = strlen(buf); + + if((winapi == WIN3x) or (winapi == WIN9x)) { + // Open clipboard + cpu.ax(0x1701); + cpu.genint(0x2f); + if(cpu.ax() == 0x0000) + return -1; + + // Empty clipboard + cpu.ax(0x1702); + cpu.genint(0x2f); + + if(len>0) { + if((seg = __dpmi_allocate_dos_memory((len >> 4) + 1, &selector)) != -1) { + movedata(_my_ds(), (unsigned) buf, selector, 0, len); + // Set clipboard data + cpu.ax(0x1703); + cpu.dx(0x07); + cpu.si(len >> 16); + cpu.cx(len & 0xffff); + cpu.es(seg); + cpu.bx(0); + cpu.genint(0x2f); + __dpmi_free_dos_memory(selector); + if(cpu.ax() != 0x0000) + result = 0; + } + } + + // Close clipboard + cpu.ax(0x1708); + cpu.genint(0x2f); + } + else { + // Clear clipboard + cpu.ax(0x1aa5); + cpu.dh(0x04); + cpu.genint(0x2f); + if(len > 0) + if((seg = __dpmi_allocate_dos_memory((len >> 4) + 1, &selector)) != -1) { + movedata(_my_ds(), (unsigned) buf, selector, 0, len); + // Set clipboard text + cpu.ax(0x1aa5); + cpu.dh(0x01); + cpu.es(seg); + cpu.bx(0x0000); + cpu.cx(len & 0xffff); + cpu.genint(0x2f); + __dpmi_free_dos_memory(selector); + if(cpu.al() == 0x00) + result = 0; + } + } + return result; +} + + +// ------------------------------------------------------------------ + +void g_get_ostitle_name(char* title) { + + *title = NUL; + if(winapi == WIN9x) { + i86 cpu; + int segment, selector; + + segment = __dpmi_allocate_dos_memory((GMAXTITLE >> 4) + 1, &selector); + if(segment == -1) + return; + // Get vdm title + cpu.ax(0x168e); + cpu.dx(3); + cpu.es(segment); + cpu.di(0); + cpu.cx(GMAXTITLE); + cpu.genint(0x2f); + movedata(selector, 0, _my_ds(), (unsigned)title, GMAXTITLE); + strcat(title, " - "); + int len = strlen(title); + // Get application title + cpu.ax(0x168e); + cpu.dx(2); + cpu.es(segment); + cpu.di(0); + cpu.cx(GMAXTITLE - len); + cpu.genint(0x2f); + movedata(selector, 0, _my_ds(), (unsigned)title + len, GMAXTITLE - len); + __dpmi_free_dos_memory(selector); + len = strlen(title); + if(streql(title + len - 3, " - ")) + title[len-3] = NUL; + } +} + + +// ------------------------------------------------------------------ + +void g_set_ostitle_name(char* title, int mode) { + + if(mode == 0) { + if(ge_win_ext_title) + g_set_ostitle(title, 0); + } + else { + char* p; + char* s = throw_xstrdup(title); + if((p = strstr(s, " - ")) != NULL) { + *p = NUL; + p += 3; + } + else + p = s + strlen(s); + g_set_ostitle(p, 0); + g_set_ostitle(s, 1); + throw_xfree(s); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlgrp.cpp b/goldlib/gall/gutlgrp.cpp new file mode 100644 index 0000000..dfc4522 --- /dev/null +++ b/goldlib/gall/gutlgrp.cpp @@ -0,0 +1,263 @@ +// hey, emacs, treat this like -*- C++ -*- file + +// ------------------------------------------------------------------ +// The Goldware Library. +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Group/Random System. +// ------------------------------------------------------------------ + +#ifdef __GNUG__ +#pragma implementation "gutlgrp.h" +#endif + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Constructor + +Grp::Grp() { + + currgrp = container.end(); + currgrpno = -1; +} + + +// ------------------------------------------------------------------ +// Destructors + +Grp::~Grp() { + + multimap::iterator i; + for(currgrp = container.begin(); currgrp != container.end(); currgrp++) + for(i = currgrp->second.find(GRP_MEMBER); i != currgrp->second.end(); i++) { + if(i->second.type == TYPE_OBJECT) + throw_free(i->second.data.object_item); + else if(i->second.type == TYPE_STRING) + throw_delete(i->second.data.string_item); + } +} + + +// ------------------------------------------------------------------ +// Add a new group + +void Grp::AddGrp(const char* id) { + + string sid(id); + multimap m; + m.insert(pair(GRP_MEMBER, sid)); + container.push_back(pair >(sid, m)); + currgrp = container.end()-1; + currgrpno = container.size()-1; +} + + +// ------------------------------------------------------------------ +// Add a new group member + +void Grp::AddMbr(const char* id) { + + currgrp->second.insert(pair(GRP_MEMBER, string(id))); +} + + +// ------------------------------------------------------------------ + +const char* Grp::SetGrp(const char* id) { + + multimap::iterator i; + for(currgrp = container.begin(), currgrpno = 0; currgrp != container.end(); currgrp++, currgrpno++) + for(i = currgrp->second.find(GRP_MEMBER); (i != currgrp->second.end()) and (i->first == GRP_MEMBER); i++) + if(strwild(id, i->second.data.string_item->c_str())) + return i->second.data.string_item->c_str(); + currgrpno = -1; + return NULL; +} + + +// ------------------------------------------------------------------ + +void Grp::AddItm(int __type, bool __data) { + + currgrp->second.insert(pair(__type, __data)); +} + + +// ------------------------------------------------------------------ + +void Grp::AddItm(int __type, char __data) { + + currgrp->second.insert(pair(__type, __data)); +} + + +// ------------------------------------------------------------------ + +void Grp::AddItm(int __type, int __data) { + + currgrp->second.insert(pair(__type, __data)); +} + + +// ------------------------------------------------------------------ + +void Grp::AddItm(int __type, const string& __data) { + + currgrp->second.insert(pair(__type, __data)); +} + + +// ------------------------------------------------------------------ + +void Grp::AddItm(int __type, void* __data, int __size) { + + void *data = throw_malloc(__size); + memcpy(data, __data, __size); + currgrp->second.insert(pair(__type, data)); +} + + +// ------------------------------------------------------------------ + +int Grp::GetItm(int __type, bool& __data, int __no) { + + // Return error if a current group is not set + if(currgrpno == -1) + return -1; + + // Pointer to item type index for this group and type + int rv = currgrp->second.count(__type); + + if(rv) { + if((__no >= rv) or (__no == -1)) + __no = rand() % rv; + multimap::iterator i = currgrp->second.find(__type); + while(__no--) i++; + __data = i->second.data.bool_item; + } + + // Return number of items of this type in the group + return rv; +} + + +// ------------------------------------------------------------------ + +int Grp::GetItm(int __type, char& __data, int __no) { + + // Return error if a current group is not set + if(currgrpno == -1) + return -1; + + // Pointer to item type index for this group and type + int rv = currgrp->second.count(__type); + + if(rv) { + if((__no >= rv) or (__no == -1)) + __no = rand() % rv; + multimap::iterator i = currgrp->second.find(__type); + while(__no--) i++; + __data = i->second.data.char_item; + } + + // Return number of items of this type in the group + return rv; +} + + +// ------------------------------------------------------------------ + +int Grp::GetItm(int __type, int& __data, int __no) { + + // Return error if a current group is not set + if(currgrpno == -1) + return -1; + + // Pointer to item type index for this group and type + int rv = currgrp->second.count(__type); + + if(rv) { + if((__no >= rv) or (__no == -1)) + __no = rand() % rv; + multimap::iterator i = currgrp->second.find(__type); + while(__no--) i++; + __data = i->second.data.int_item; + } + + // Return number of items of this type in the group + return rv; +} + + +// ------------------------------------------------------------------ + +int Grp::GetItm(int __type, string& __data, int __no) { + + // Return error if a current group is not set + if(currgrpno == -1) + return -1; + + // Pointer to item type index for this group and type + int rv = currgrp->second.count(__type); + + if(rv) { + if((__no >= rv) or (__no == -1)) + __no = rand() % rv; + multimap::iterator i = currgrp->second.find(__type); + while(__no--) i++; + __data = *(i->second.data.string_item); + } + + // Return number of items of this type in the group + return rv; +} + + +// ------------------------------------------------------------------ + +int Grp::GetItm(int __type, void* __data, int __size, int __no) { + + // Return error if a current group is not set + if(currgrpno == -1) + return -1; + + // Pointer to item type index for this group and type + int rv = currgrp->second.count(__type); + + if(rv) { + if((__no >= rv) or (__no == -1)) + __no = rand() % rv; + multimap::iterator i = currgrp->second.find(__type); + while(__no--) i++; + memcpy(__data, i->second.data.object_item, __size); + } + + // Return number of items of this type in the group + return rv; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlgrp.h b/goldlib/gall/gutlgrp.h new file mode 100644 index 0000000..229a808 --- /dev/null +++ b/goldlib/gall/gutlgrp.h @@ -0,0 +1,175 @@ +// hey, emacs, treat this like -*- C++ -*- file + +// ------------------------------------------------------------------ +// The Goldware Library. +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Group/Random System. +// ------------------------------------------------------------------ + +#ifndef __gutlgrp_h +#define __gutlgrp_h + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +#ifdef __GNUG__ +#pragma interface "gutlgrp.h" +#endif + +// ------------------------------------------------------------------ + +enum { + GRP_AKA, + GRP_AKAMATCHING, + GRP_AREACOPYADDID, + GRP_AREACOPYDIRECT, + GRP_AREACOPYTO, + GRP_AREAFORWARDDIRECT, + GRP_AREAFREQDIRECT, + GRP_AREAFREQTO, + GRP_AREAREPLYDIRECT, + GRP_AREAREPLYTO, + GRP_AREAYOUWROTETO, + GRP_ATTRIBUTES, + GRP_CTRLINFO, + GRP_EDITHARDTERM, + GRP_EDITMIXCASE, + GRP_EDITREPLYRE, + GRP_FORCETEMPLATE, + GRP_INPUTFILE, + GRP_INTERNETADDRESS, + GRP_INTERNETGATE, + GRP_INTERNETMSGID, + GRP_INTERNETRFCBODY, + GRP_LOADLANGUAGE, + GRP_MEMBER, + GRP_MSGLISTDATE, + GRP_MSGLISTFAST, + GRP_MSGLISTFIRST, + GRP_MSGLISTHEADER, + GRP_MSGLISTWIDESUBJ, + GRP_NICKNAME, + GRP_ORGANIZATION, + GRP_ORIGIN, + GRP_OUTPUTFILE, + GRP_PLAY, + GRP_QUOTEBUFFILE, + GRP_QUOTECHARS, + GRP_QUOTECTRL, + GRP_QUOTESTRING, + GRP_QUOTEWRAPHARD, + GRP_SEARCHFOR, + GRP_TAGLINE, + GRP_TAGLINECHAR, + GRP_TAGLINESUPPORT, + GRP_TEARLINE, + GRP_TEMPLATE, + GRP_TEMPLATEMATCH, + GRP_TWITMODE, + GRP_USEFWD, + GRP_USERNAME, + GRP_USETZUTC, + GRP_VIEWHIDDEN, + GRP_VIEWKLUDGE, + GRP_VIEWQUOTE, + GRP_WHOTO, + GRP_XLATEXPORT, + GRP_XLATIMPORT, + + GRP_MAX +}; + + +// ------------------------------------------------------------------ +// Group class + +class Grp { + +private: + + enum { + TYPE_BOOL, + TYPE_CHAR, + TYPE_INT, + TYPE_STRING, + TYPE_OBJECT + }; + + class grp_stock { + + public: + + int type; + union { + bool bool_item; + char char_item; + int int_item; + string *string_item; + void *object_item; + } data; + + grp_stock(bool item) { type = TYPE_BOOL; data.bool_item = item; } + grp_stock(char item) { type = TYPE_CHAR; data.char_item = item; } + grp_stock(int item) { type = TYPE_INT; data.int_item = item; } + grp_stock(const string& item) { type = TYPE_STRING; data.string_item = new string(item); throw_new(data.string_item); } + grp_stock(void *item) { type = TYPE_OBJECT; data.object_item = item; } + }; + + vector< pair > > container; + vector< pair > >::iterator currgrp; + +public: + + int currgrpno; + + Grp(); + ~Grp(); + + void AddGrp(const char* id); + void AddMbr(const char* id); + const char* SetGrp(const char* id); + + void AddItm(int __type, bool __data); + void AddItm(int __type, char __data); + void AddItm(int __type, int __data); + void AddItm(int __type, const string& __data); + void AddItm(int __type, void* __data, int __size); + + int GetItm(int __type, bool& __data, int __no=-1); + int GetItm(int __type, char& __data, int __no=-1); + int GetItm(int __type, int& __data, int __no=-1); + int GetItm(int __type, string& __data, int __no=-1); + int GetItm(int __type, void* __data, int __size, int __no=-1); +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlmisc.cpp b/goldlib/gall/gutlmisc.cpp new file mode 100644 index 0000000..555d74a --- /dev/null +++ b/goldlib/gall/gutlmisc.cpp @@ -0,0 +1,195 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Utility functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Get yes/no value + +int GetYesno(const char* value) { + + if(isdigit(*value)) + return atoi(value); + + switch(toupper(*value)) { + + case NUL: // Blank + case 'T': // True + case 'Y': // Yes + return YES; + + case 'F': // False + case 'N': // No + return NO; + + case 'O': // On or Off + if(toupper(value[1]) == 'N') + return YES; + else + return NO; + + case 'A': // Always, Ask or Auto + if(toupper(value[1]) == 'L') + return ALWAYS; + else if(toupper(value[1]) == 'S') + return ASK; + else + return GAUTO; + + case 'M': // Maybe + return MAYBE; + } + + return NO; +} + + +// ------------------------------------------------------------------ +// Calculates a percentage + +int Pct(ulong x, ulong y) { + + if(x) { + + ulong p = (((x-y)*100)/x); + ulong r = (((x-y)*100)%x); + + if(((r*10)/x)>4) + p++; + + return (int)p; + } + + return 100; +} + + +// ------------------------------------------------------------------ +// Calculates next tab stop from given column + +int tabstop(int column, int tabwidth) { + + int sum = column + tabwidth; + return sum - (sum % tabwidth); +} + + +// ------------------------------------------------------------------ +// Convert hex string to integer + +ulong atoulx(const char* s) { + + ulong retval = 0; + + s = strskip_wht(s); + + while(isxdigit(*s)) { + retval <<= 4; + retval |= xtoi(*s); + s++; + } + + return retval; +} + + +// ------------------------------------------------------------------ + +char* ltob(char* dst, ulong value, int fill) { + + char* p = dst; + + for(int b=1,g=0; b<33; b++) { + if(value & 0x80000000L) { + g = 1; + *p++ = '1'; + } + else { + if(g or (b >= fill)) + *p++ = '0'; + } + value <<= 1; + } + *p = NUL; + + return dst; +} + + +// ------------------------------------------------------------------ + +dword B2L(dword b) { + + byte* bp = (byte*)&b; + return ((*bp + ((dword)bp[1] << 8) + ((dword)bp[2] << 16)) | 0x800000L) >> (24 - (bp[3] - 0x80)); +} + + +// ------------------------------------------------------------------ + +dword L2B(dword l) { + + // Special case for zero + if(l == 0) + return 0; + + // Look for the largest power of 2 + int s = 31; + dword p = 0x80000000UL; + while(s > 0) { + if(p & l) + break; + p >>= 1; + s--; + } + + // Fillup the mantisse with useful information + dword b = 0; + int n = 0; + int e = s--; + l -= 1UL << e; + while(l > 0) { + dword t = (1UL << s); + if(l >= t) { + b += 1UL << (22 - n); + if(l < t) + break; + l -= t; + } + n++; + s--; + } + + return b | ((0x81UL+e) << 24); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlmisc.h b/goldlib/gall/gutlmisc.h new file mode 100644 index 0000000..aac4072 --- /dev/null +++ b/goldlib/gall/gutlmisc.h @@ -0,0 +1,67 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Utility functions. +// ------------------------------------------------------------------ + +#ifndef __gutlmisc_h +#define __gutlmisc_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Prototypes + +ulong atoulx(const char* s); + +inline word atow(const char* p) { return (word)atoi(p); } +inline int xtoi(char c) { return isdigit(c) ? (c - '0') : (toupper(c) - ('A' - 10)); } +inline int atox(const char* s) { return (int)atoulx(s); } + +char* ltob(char* dst, ulong value, int fill=32); + +int GetYesno(const char* value); +int Pct(dword x, dword y); +int tabstop(int col, int tabwidth); + +char* ggetosstring(); + +// Convert between Microsoft MKS format and long int +dword B2L(dword b); +dword L2B(dword l); + +inline void SwapWord32(long* dw) { *dw = (long)(((dword)(*dw) << 16) | ((dword)(*dw) >> 16)); } + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gutlmtsk.cpp b/goldlib/gall/gutlmtsk.cpp new file mode 100644 index 0000000..cab32fb --- /dev/null +++ b/goldlib/gall/gutlmtsk.cpp @@ -0,0 +1,220 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Multitasking. +// ------------------------------------------------------------------ + +#include +#include +#include + +#ifdef __OS2__ +#define INCL_BASE +#include +#endif + +#ifdef __WIN32__ +#include +#endif + +#ifdef __GNUC__ +#include +#endif + + +// ------------------------------------------------------------------ +// Global multitasker data + +GMTsk gmtsk; + + +// ------------------------------------------------------------------ + +GMTsk::GMTsk() { + + detected = GMTSK_NONE; + name = ""; + #if defined(__DJGPP__) + _get_dos_version(true); + name = "DPMI32"; + #elif defined(__UNIX__) + detected = GMTSK_LINUX; + name = "UNIX"; + #else + if(desqview()) + return; + if(win32()) + return; + if(os2()) + return; + if(windows()) + return; + dosint28(); + #endif +} + + +// ------------------------------------------------------------------ + +int GMTsk::os2() { + + #if defined(__OS2__) + detected = GMTSK_OS2; + name = "OS/2"; + #elif not defined(__GNUC__) + if(_osmajor >= 10) { + detected = GMTSK_OS2; + name = "OS/2"; + } + #endif + return detected; +} + + +// ------------------------------------------------------------------ + +int GMTsk::win32() { + + #if defined(__WIN32__) + #if defined(__BORLANDC__) + if(GetProcAddress(GetModuleHandle("kernel32.dll"), "Borland32")) { + name = "DOS (32RTM.EXE)"; + detected = GMTSK_DOS; + return detected; + } + #endif + detected = GMTSK_W32; + name = "Win32"; + #endif + return detected; +} + + +// ------------------------------------------------------------------ + +int GMTsk::windows() { + + #if defined(__MSDOS__) and not defined(__DJGPP__) + i86 cpu; + cpu.ax(0x352F); + cpu.genint(0x21); + if(cpu.es() != 0) { + cpu.ax(0x1600); + cpu.genint(0x2F); + if(cpu.ax() & 0x007F) { + detected = GMTSK_WINDOWS; + name = "Windows"; + } + } + #endif + return detected; +} + + +// ------------------------------------------------------------------ + +int GMTsk::desqview() { + + #if defined(__MSDOS__) and not defined(__DJGPP__) + i86 cpu; + cpu.cx(0x4445); + cpu.dx(0x5351); + cpu.ax(0x2B01); + cpu.genint(0x21); + if(cpu.al() != 0xFF) { + if(cpu.bx()) { + detected = GMTSK_DESQVIEW; + name = "DESQview"; + } + } + #endif + return detected; +} + + +// ------------------------------------------------------------------ + +int GMTsk::dosint28() { + + #if defined(__MSDOS__) and not defined(__DJGPP__) + detected = GMTSK_DOS; + name = "DOS"; + #endif + + return detected; +} + + +// ------------------------------------------------------------------ + +void GMTsk::timeslice() { + + #if defined(__DJGPP__) + __dpmi_yield(); + #else + #if defined(__MSDOS__) + i86 cpu; + #endif + + switch(detected) { + #if defined(__UNIX__) + case GMTSK_LINUX: + usleep(5000); + break; + #endif + #if defined(__WIN32__) + case GMTSK_W32: + Sleep(5); + break; + case GMTSK_DOS: + Sleep(5); + break; + #endif + #if defined(__MSDOS__) or defined(__OS2__) + case GMTSK_OS2: + #if defined(__OS2__) + DosSleep(5); + break; + #endif + // Drop through if this is a DOS version + #if defined(__MSDOS__) + case GMTSK_WINDOWS: + cpu.ax(0x1680); + cpu.genint(0x2F); + break; + case GMTSK_DESQVIEW: + cpu.ax(0x1000); + cpu.genint(0x15); + break; + case GMTSK_DOS: + cpu.genint(0x28); + break; + #endif + #endif + } + #endif +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlmtsk.h b/goldlib/gall/gutlmtsk.h new file mode 100644 index 0000000..f044785 --- /dev/null +++ b/goldlib/gall/gutlmtsk.h @@ -0,0 +1,80 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Multitasking. +// ------------------------------------------------------------------ + +#ifndef __gutlmtsk_h +#define __gutlmtsk_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Supported multitaskers + +const int GMTSK_NONE = 0; +const int GMTSK_OS2 = 1; +const int GMTSK_WINDOWS = 2; +const int GMTSK_DESQVIEW = 3; +const int GMTSK_DOS = 4; +const int GMTSK_W32 = 5; +const int GMTSK_LINUX = 6; + + +// ------------------------------------------------------------------ +// Multitasker base class + +class GMTsk { + +public: + + int detected; + const char* name; + + int os2(); + int win32(); + int windows(); + int desqview(); + int dosint28(); + + void timeslice(); + + GMTsk(); +}; + + +// ------------------------------------------------------------------ +// Globals + +extern GMTsk gmtsk; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlos.h b/goldlib/gall/gutlos.h new file mode 100644 index 0000000..fa201d5 --- /dev/null +++ b/goldlib/gall/gutlos.h @@ -0,0 +1,87 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// XXX +// ------------------------------------------------------------------ + +#ifndef __gutlos_h +#define __gutlos_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(__WIN32__) or defined(__OS2__) or defined(__DJGPP__) + + +// ------------------------------------------------------------------ + +#define GUTLOS_FUNCS 1 + +const int GMAXTITLE = 60; +const int BUFFERSIZE = 128; + +// ------------------------------------------------------------------ + +#ifdef __cplusplus +extern "C" { +#endif + +int g_init_os(int flags); +void g_deinit_os(void); + +void g_increase_priority(void); + +int g_send_mci_string(char*, char*); + +void g_init_title(char *, int); +void g_set_ostitle(char *); +void g_set_osicon(void); + +bool g_is_clip_available(void); +char* g_get_clip_text(void); +int g_put_clip_text(char *cd); + +void g_get_ostitle_name(char *); +void g_set_ostitle_name(char *, int); + +char g_tolower(char); +char g_toupper(char); + +#ifdef __cplusplus +} +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlos2.cpp b/goldlib/gall/gutlos2.cpp new file mode 100644 index 0000000..2022c58 --- /dev/null +++ b/goldlib/gall/gutlos2.cpp @@ -0,0 +1,349 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999 Alexander Batalov +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Some os2 pm func. +// ------------------------------------------------------------------ + +#include +#include +#include + +#define INCL_DOSMODULEMGR +#define INCL_WINWINDOWMGR +#define INCL_DOSPROCESS +#define INCL_WIN +#define INCL_OS2MM +#define INCL_WINFRAMEMGR +#include +#include + +// ------------------------------------------------------------------ + +HAB APIENTRY (*pfnWinInitialize)(ULONG); +BOOL APIENTRY (*pfnWinTerminate)(HAB); +HMQ APIENTRY (*pfnWinCreateMsgQueue)(HAB, LONG); +BOOL APIENTRY (*pfnWinDestroyMsgQueue)(HMQ); +BOOL APIENTRY (*pfnWinEmptyClipbrd)(HAB); +BOOL APIENTRY (*pfnWinOpenClipbrd)(HAB); +BOOL APIENTRY (*pfnWinCloseClipbrd)(HAB); +BOOL APIENTRY (*pfnWinSetClipbrdData)(HAB, ULONG, ULONG, ULONG); +ULONG APIENTRY (*pfnWinQueryClipbrdData)(HAB, ULONG); +ULONG APIENTRY (*pfnWinChangeSwitchEntry)(HSWITCH, SWCNTRL *); +BOOL APIENTRY (*pfnWinSetWindowText)(HWND, PSZ); +BOOL APIENTRY (*pfnWinQueryClipbrdFmtInfo)(HAB, ULONG, PULONG); +ULONG APIENTRY (*pfnWinQuerySwitchEntry)(HSWITCH, PSWCNTRL); +HSWITCH APIENTRY (*pfnWinQuerySwitchHandle)(HWND, PID); +LONG APIENTRY (*pfnWinQueryWindowText)(HWND, LONG, char *); +MRESULT APIENTRY (*pfnWinSendMsg)(HWND, ULONG, MPARAM, MPARAM); +HPOINTER APIENTRY (*pfnWinLoadPointer)(HWND, HMODULE, ULONG); +BOOL APIENTRY (*pfnWinInvalidateRect)(HWND, PRECTL, BOOL); +DWORD APIENTRY (*pfnmciSendString)(LPSTR, LPSTR, WORD, HWND, WORD); +DWORD APIENTRY (*pfnmciGetErrorString)(DWORD, LPSTR, WORD); + +static BOOL access_pm_clipboard(void); +static void leave_pm_clipboard(int mode); + + +// ------------------------------------------------------------------ + +HAB ge_os2_hab = 0; +HMQ ge_os2_hmq = 0; +HSWITCH ge_os2_hsw = 0; +HWND ge_os2_hwndframe = 0; +HMODULE ge_os2_hmte = 0; +HMODULE ge_os2_hmte2 = 0; +HMODULE ge_os2_mdmHandle = 0; +SWCNTRL ge_os2_swolddata; +SWCNTRL ge_os2_swdata; +SZ ge_os2_loaderr[256]; +char ge_os2_coldtitle[GMAXTITLE] = ""; +HPOINTER ge_os2_coldicon; +char ge_os2_title[GMAXTITLE] = ""; +int ge_os2_ext_title; +ULONG ge_os2_oldicon; + + +// ------------------------------------------------------------------ + +static struct { + PPIB ppib; + HAB hab; + HMQ hmq; + ULONG savedtype; + BOOL opened; +} pminfo; + + +// ------------------------------------------------------------------ +// Init os/2 pm functions + +int g_init_os(int flags) { + + int rc; + PTIB ptib; + + rc = DosQueryModuleHandle((PSZ)"PMWIN", &ge_os2_hmte); + memset(&pminfo, 0, sizeof (pminfo)); + + DosGetInfoBlocks(&ptib, &pminfo.ppib); + pminfo.savedtype = pminfo.ppib->pib_ultype; + + // Morph application into PM + if(not rc) { + pminfo.ppib->pib_ultype = 3; + rc = DosLoadModule((PSZ)ge_os2_loaderr, sizeof(ge_os2_loaderr), (PSZ)"PMWIN", &ge_os2_hmte); + if(rc) + return 1; + + // Load the functions dinamically + rc = DosQueryProcAddr(ge_os2_hmte, 707, 0, (PFN*)&pfnWinCloseClipbrd); + rc = DosQueryProcAddr(ge_os2_hmte, 716, 0, (PFN*)&pfnWinCreateMsgQueue); + rc = DosQueryProcAddr(ge_os2_hmte, 726, 0, (PFN*)&pfnWinDestroyMsgQueue); + rc = DosQueryProcAddr(ge_os2_hmte, 733, 0, (PFN*)&pfnWinEmptyClipbrd); + rc = DosQueryProcAddr(ge_os2_hmte, 763, 0, (PFN*)&pfnWinInitialize); + rc = DosQueryProcAddr(ge_os2_hmte, 793, 0, (PFN*)&pfnWinOpenClipbrd); + rc = DosQueryProcAddr(ge_os2_hmte, 806, 0, (PFN*)&pfnWinQueryClipbrdData); + rc = DosQueryProcAddr(ge_os2_hmte, 807, 0, (PFN*)&pfnWinQueryClipbrdFmtInfo); + rc = DosQueryProcAddr(ge_os2_hmte, 854, 0, (PFN*)&pfnWinSetClipbrdData); + rc = DosQueryProcAddr(ge_os2_hmte, 888, 0, (PFN*)&pfnWinTerminate); + rc = DosQueryProcAddr(ge_os2_hmte, 841, 0, (PFN*)&pfnWinQueryWindowText); + rc = DosQueryProcAddr(ge_os2_hmte, 877, 0, (PFN*)&pfnWinSetWindowText); + rc = DosQueryProcAddr(ge_os2_hmte, 920, 0, (PFN*)&pfnWinSendMsg); + rc = DosQueryProcAddr(ge_os2_hmte, 780, 0, (PFN*)&pfnWinLoadPointer); + rc = DosQueryProcAddr(ge_os2_hmte, 765, 0, (PFN*)&pfnWinInvalidateRect); + + rc = DosQueryModuleHandle((PSZ)"PMSHAPI", &ge_os2_hmte2); + if(rc) + return 1; + rc = DosLoadModule((PSZ)ge_os2_loaderr, sizeof(ge_os2_loaderr), (PSZ)"PMSHAPI", &ge_os2_hmte2); + if(rc) + return 1; + DosQueryProcAddr(ge_os2_hmte2, 123, 0, (PFN*)&pfnWinChangeSwitchEntry); + DosQueryProcAddr(ge_os2_hmte2, 124, 0, (PFN*)&pfnWinQuerySwitchEntry); + DosQueryProcAddr(ge_os2_hmte2, 125, 0, (PFN*)&pfnWinQuerySwitchHandle); + + if(flags & 1) { + rc = DosQueryModuleHandle((PSZ)"MDM", &ge_os2_hmte); + if(not rc) { + rc = DosLoadModule((PSZ)ge_os2_loaderr, sizeof(ge_os2_loaderr), (PSZ)"MDM", &ge_os2_mdmHandle); + if(not rc) { + DosQueryProcAddr(ge_os2_mdmHandle, 0, (PSZ)"mciSendString", (PFN*)&pfnmciSendString); + DosQueryProcAddr(ge_os2_mdmHandle, 0, (PSZ)"mciGetErrorString", (PFN*)&pfnmciGetErrorString); + } + } + } + + // Make queue + ge_os2_hab = pfnWinInitialize(0); + ge_os2_hmq = pfnWinCreateMsgQueue(ge_os2_hab, 0); + + // Find our hSw + ge_os2_hsw = pfnWinQuerySwitchHandle(0, pminfo.ppib->pib_ulpid); + if(ge_os2_hsw) { + pfnWinQuerySwitchEntry(ge_os2_hsw, &ge_os2_swolddata); + ge_os2_swdata = ge_os2_swolddata; + ge_os2_hwndframe = ge_os2_swdata.hwnd; + pfnWinQueryWindowText(ge_os2_hwndframe, sizeof(ge_os2_coldtitle), ge_os2_coldtitle); + } + } + DosSetPriority(PRTYS_PROCESS, PRTYC_REGULAR, PRTYD_MINIMUM, 0); + return 0; +} + + +// ------------------------------------------------------------------ +// deInit os/2 pm functions + +void g_deinit_os(void) { + + if(ge_os2_hwndframe) { + pfnWinChangeSwitchEntry(ge_os2_hsw, &ge_os2_swolddata); + g_set_ostitle(ge_os2_coldtitle); + pfnWinSendMsg(ge_os2_hwndframe, WM_SETICON, (MPARAM) ge_os2_swolddata.hwndIcon, (MPARAM) 0); + } + if(ge_os2_hmq) + pfnWinDestroyMsgQueue(ge_os2_hmq); + if(ge_os2_hab) + pfnWinTerminate(ge_os2_hab); + if(ge_os2_hmte) + DosFreeModule(ge_os2_hmte); + if(ge_os2_hmte2) + DosFreeModule(ge_os2_hmte2); + if(ge_os2_mdmHandle) + DosFreeModule(ge_os2_mdmHandle); +} + + +// ------------------------------------------------------------------ + +void g_init_title(char *tasktitle, int titlestatus) { + + strxcpy(ge_os2_title, tasktitle, GMAXTITLE); + ge_os2_ext_title = titlestatus; +} + + +// ------------------------------------------------------------------ + +void g_increase_priority(void) { + + DosSetPriority(PRTYS_PROCESS, PRTYC_REGULAR, PRTYD_MAXIMUM, 0); +} + + +// ------------------------------------------------------------------ +// Change title + +void g_set_ostitle(char *title) { + + if(ge_os2_hsw && ge_os2_hwndframe) { + strxcpy(ge_os2_swdata.szSwtitle, title, MAXNAMEL); + pfnWinChangeSwitchEntry(ge_os2_hsw, &ge_os2_swdata); + pfnWinSetWindowText(ge_os2_hwndframe, (PSZ)title); + } +} + + +// ------------------------------------------------------------------ +// Change icon + +void g_set_osicon(void) { + + if(ge_os2_hwndframe && ge_os2_hsw) { + ULONG ulPicture = (ULONG) pfnWinLoadPointer(HWND_DESKTOP, 0, 1); + if(ulPicture) { + pfnWinSendMsg(ge_os2_hwndframe, WM_SETICON, (MPARAM) ulPicture, (MPARAM) 0); + pfnWinInvalidateRect(ge_os2_hwndframe, 0, 1); + pfnWinChangeSwitchEntry(ge_os2_hsw, &ge_os2_swdata); + } + } +} + + +// ------------------------------------------------------------------ + +bool g_is_clip_available(void) { + + return (ge_os2_hab) ? true : false; +} + + +// ------------------------------------------------------------------ + +char *g_get_clip_text(void) { + + char *text = NULL; + char *cd = NULL; + BOOL clip_open = false; + if(ge_os2_hab) { + if((clip_open = access_pm_clipboard()) != true) + return NULL; + if((text = (char *) pfnWinQueryClipbrdData(ge_os2_hab, CF_TEXT)) != NULL) + cd = throw_strdup(text); + leave_pm_clipboard(clip_open); + } + return cd; +} + + +// ------------------------------------------------------------------ + +void g_get_ostitle_name(char *currtitle) { + + if(ge_os2_hwndframe) + pfnWinQueryWindowText(ge_os2_hwndframe, GMAXTITLE, currtitle); +} + + +// ------------------------------------------------------------------ + +void g_set_ostitle_name(char *title, int mode) { + + if(mode == 0) { + char fulltitle[80]; + strcpy(fulltitle, ge_os2_title); + if(ge_os2_ext_title) { + int len = strlen(fulltitle); + if(len < GMAXTITLE-4) { + if(len) + strcat(fulltitle, " - "); + strxcpy(fulltitle+len+3, title, GMAXTITLE-len-3); + } + } + g_set_ostitle(fulltitle); + } + else + g_set_ostitle(title); +} + + +// ------------------------------------------------------------------ + +static BOOL access_pm_clipboard(void) { + + BOOL clip_opened = false; + if(pfnWinOpenClipbrd(ge_os2_hab) == true) + clip_opened = true; + else + leave_pm_clipboard(clip_opened); + return clip_opened; +} + + +// ------------------------------------------------------------------ + +static void leave_pm_clipboard(int mode) { + + if(mode == true) + pfnWinCloseClipbrd(ge_os2_hab); +} + + +// ------------------------------------------------------------------ + +int g_put_clip_text(char *cd) { + + ULONG len; + void *text; + int rc = -1; + BOOL clip_open = false; + if(ge_os2_hab) { + if((clip_open = access_pm_clipboard()) != true) + return rc; + pfnWinEmptyClipbrd(ge_os2_hab); + len = strlen(cd); + + if(len) { + DosAllocSharedMem((void **) &text, 0, len + 1, PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE); + strxcpy((char *) text, cd, len + 1); + if(pfnWinSetClipbrdData(ge_os2_hab, (ULONG) text, CF_TEXT, CFI_POINTER)) + rc = 0; + } + leave_pm_clipboard(clip_open); + } + return rc; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlos2m.cpp b/goldlib/gall/gutlos2m.cpp new file mode 100644 index 0000000..cebb6ca --- /dev/null +++ b/goldlib/gall/gutlos2m.cpp @@ -0,0 +1,73 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999 Alexander Batalov +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Some os2 pm func. +// ------------------------------------------------------------------ + +#include +#include +#include + +#define INCL_DOSMODULEMGR +#define INCL_WINWINDOWMGR +#define INCL_DOSPROCESS +#define INCL_WIN +#define INCL_OS2MM +#define INCL_WINFRAMEMGR +#include +#include + + +// ------------------------------------------------------------------ + +extern DWORD APIENTRY (*pfnmciSendString)(LPSTR, LPSTR, WORD, HWND, WORD); +extern DWORD APIENTRY (*pfnmciGetErrorString)(DWORD, LPSTR, WORD); +extern HMODULE ge_os2_mdmHandle = 0; + + +// ------------------------------------------------------------------ +// Send MCI string + +int g_send_mci_string(char* string, char* his_buffer) { + + char our_buffer[BUFFERSIZE], *return_buffer; + + return_buffer = his_buffer ? his_buffer : our_buffer; + memset(return_buffer, 0, BUFFERSIZE); + + if(not ge_os2_mdmHandle) + return 1; + + DWORD rc = pfnmciSendString((LPSTR)string, (LPSTR)return_buffer, BUFFERSIZE, 0, 0); + + if(rc == MCIERR_SUCCESS) + return 1; + else { + pfnmciGetErrorString(rc, (LPSTR)return_buffer, BUFFERSIZE); + return 0; + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutltag.cpp b/goldlib/gall/gutltag.cpp new file mode 100644 index 0000000..8b85ab6 --- /dev/null +++ b/goldlib/gall/gutltag.cpp @@ -0,0 +1,323 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Tag number types and set class. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Constructor. + +GTag::GTag() { + + granularity = 10; + + tag = NULL; + allocated = tags = count = 0; +} + + +// ------------------------------------------------------------------ +// Destructor. + +GTag::~GTag() { + + Reset(); +} + + +// ------------------------------------------------------------------ +// Deallocate and reset internal data. + +void GTag::Reset() { + + throw_xrelease(tag); + allocated = tags = 0; + // NOTE: Does and must NOT reset the count! +} + + +// ------------------------------------------------------------------ +// Resize tag array. +// Returns NULL if realloc failed. + +ulong* GTag::Resize(uint __tags) { + + register uint newsize = 0; + + if(__tags >= allocated) + newsize = __tags + granularity; + else if(__tags < allocated) { + if((allocated-__tags) > granularity) + newsize = __tags + granularity; + } + + if(newsize) { + tag = (ulong*)throw_realloc(tag, newsize*sizeof(ulong)); + allocated = newsize; + } + + count = tags = __tags; + return tag; +} + + +// ------------------------------------------------------------------ +// Appends a new tag number to the end of the tag array. +// NOTE - Does not check for duplicates or correct sequence! + +ulong* GTag::Append(ulong __tagn) { + + Resize(tags+1); + tag[tags-1] = __tagn; + return tag; +} + + +// ------------------------------------------------------------------ +// Add a new tag number at the correct position of the tag array. +// +// Algorithm dry test situations: +// +// [] 0123456 +// tag 345789x tags = 7 (after resize) +// _reln 1234567 +// +// Case 1 - New tag is smaller than first tag in array: +// __tagn = 2 +// _reln = 1 (changed to 0) +// tags-_reln-1 = 7-0-1 = 6 +// +// Case 2 - Normal insert in middle: +// __tagn = 6 +// _reln = 3 +// tags-_reln-1 = 7-3-1 = 3 +// +// Case 3 - New tag is larger than last tag in array: +// __tagn = 10 +// _reln = 6 +// tags-_reln-1 = 7-6-1 = 0 +// +// Dry test result: Works! + +ulong* GTag::Add(ulong __tagn) { + + // Find closest tag number + uint _reln = ToReln(__tagn, TAGN_CLOSEST); + + // Do we have it already? + if((_reln == RELN_INVALID) OR (tag[_reln-1] != __tagn)) { + + // Resize tag array to make room for the new number + Resize(tags+1); + + // General rule: + // - tag[_reln-1] is smaller than __tagn + // + // The exceptions to the rule: + // - no tags in array (if _reln == RELN_INVALID) + // - tag[_reln-1] is larger than __tagn + + if(_reln AND (tag[_reln-1] > __tagn)) + _reln--; + + // Move data to make room for the new tag number + memmove(tag+_reln+1, tag+_reln, (tags-_reln-1)*sizeof(ulong)); + + // Copy the new tag number to the insert position + tag[_reln] = __tagn; + } + + return tag; +} + + +// ------------------------------------------------------------------ +// Delete a tag number from the tag array. +// Returns the relative tag number or RELN_INVALID if missing. +// NOTE - Does not resize the array. + +uint GTag::Del(ulong __tagn) { + + return DelReln(ToReln(__tagn)); +} + + +// ------------------------------------------------------------------ + +uint GTag::DelReln(uint __reln) { + + if(__reln) { + memmove(tag+__reln-1, tag+__reln, (tags-__reln)*sizeof(ulong)); + count--; + tags--; + } + return __reln; +} + + +// ------------------------------------------------------------------ + +uint GTag::DelResize(ulong __tagn) { + + uint _reln = Del(__tagn); + Resize(tags); + return _reln; +} + + +// ------------------------------------------------------------------ + +static int TagnCmp(const ulong* __a, const ulong* __b) { + + return CmpV(*__a, *__b); +} + + +// ------------------------------------------------------------------ + +void GTag::Sort() { + + qsort(tag, tags, sizeof(ulong), (StdCmpCP)TagnCmp); +} + +// ------------------------------------------------------------------ + +void GTag::ElimDups() { + + if(tags > 1) { + uint _before = tags; + ulong _last = tag[0]; + for(uint n=1; n tag[tags-1]) + return __closest ? tags : RELN_INVALID; + + if(tags and __tagn) { + + register long _mid; + register long _left = 0; + register long _right = tags; + + do { + _mid = (_left+_right)/2; + if(__tagn < tag[(uint)_mid]) + _right = _mid - 1; + else if(__tagn > tag[(uint)_mid]) + _left = _mid + 1; + else + return (uint)(_mid + 1); + } while(_left < _right); + + _lastreln = (uint)(_left + 1); + if(__tagn == tag[(uint)_left]) + return _lastreln; + } + } + + // Not found + return __closest ? _lastreln : RELN_INVALID; +} + + +// ------------------------------------------------------------------ + +uint GTag::ToReln(ulong __tagn) { + + return ToReln(__tagn, TAGN_EXACT); +} + + +// ------------------------------------------------------------------ + +void GTag::Load(gfile& fp) { + + dword val; + + fp.fread(&val, sizeof(dword)); + count = (uint) val; + if(count) { + Resize(count); + fp.fread(tag, sizeof(ulong), count); + } +} + + +// ------------------------------------------------------------------ + +void GTag::Save(gfile& fp) { + + dword val; + + val = (dword) count; + fp.fwrite(&val, sizeof(dword)); + + if(tag and count) + fp.fwrite(tag, sizeof(ulong), count); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutltag.h b/goldlib/gall/gutltag.h new file mode 100644 index 0000000..42d4966 --- /dev/null +++ b/goldlib/gall/gutltag.h @@ -0,0 +1,115 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Tag number types and set class. +// ------------------------------------------------------------------ + +#ifndef __gutltag_h +#define __gutltag_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Constants + +const ulong TAGN_INVALID = 0; +const uint RELN_INVALID = 0; + +const ulong TAGN_MAX = ((ulong)-1); +const uint RELN_MAX = ((uint)-1); + +const int TAGN_CLOSEST = true; +const int TAGN_EXACT = false; + + +// ------------------------------------------------------------------ +// Tag class + +class GTag { + +public: + + // ---------------------------------------------------------------- + // Internal data + + ulong* tag; // tag array + uint tags; // tags in array + uint count; // fake tags count + uint allocated; // actual allocated tags + uint granularity; // memory allocation optimization + + // ---------------------------------------------------------------- + // Constructor and destructor + + GTag(); + ~GTag(); + + // ---------------------------------------------------------------- + // User functions + + void Reset(); + void ResetAll() { Reset(); count = 0; } + + ulong* Resize(uint __tags); + + ulong* Append(ulong __tagn); + ulong* Add(ulong __tagn); + uint Del(ulong __tagn); + uint DelReln(uint __reln); + uint DelResize(ulong __tagn); + void Sort(); + void ElimDups(); + + ulong CvtReln(uint __reln); + uint ToReln(ulong __tagn); + uint ToReln(ulong __tagn, int __closest); + + uint Find(ulong __tagn) { return ToReln(__tagn); } + + uint Tags() const { return tags; } + uint Count() const { return count; } + uint SetCount(uint n) { tags = count = n; return count; } + + void Set(uint n, ulong t) { tag[n] = t; } + ulong Get(uint n) { return (tags AND (n +#include +#include + +#if defined(__WIN32__) +#include +#elif defined(__GNUC__) +#include +#endif + + +// ------------------------------------------------------------------ + +char* ggetosstring(void) { + + static char osstring[256] = ""; + + if(*osstring == NUL) { + + #if defined(__UNIX__) or defined(__DJGPP__) or defined(__EMX__) + + struct utsname info; + + if(uname(&info) != -1) + #if defined(__EMX__) + sprintf(osstring, "%s %s.%s %s", info.sysname, info.version, info.release, info.machine); + #elif defined(__DJGPP__) + sprintf(osstring, "%s %s.%s %s", info.sysname, info.release, info.version, info.machine); + #else + sprintf(osstring, "%s %s %s", info.sysname, info.release, info.machine); + #endif + else + strcpy(osstring, "unknown"); + + #elif defined (__WIN32__) + + OSVERSIONINFO info; + SYSTEM_INFO si; + char ostype[16]; + char processor[16]; + + GetSystemInfo(&si); + info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if(GetVersionEx(&info)) { + switch(info.dwPlatformId) { + case VER_PLATFORM_WIN32_NT: + strcpy(ostype, "WinNT"); + break; + case VER_PLATFORM_WIN32_WINDOWS: + strcpy(ostype, "Win9x"); + break; + default: + strcpy(ostype, "Win32s"); + break; + } + switch(*((WORD*)&si)) { + case PROCESSOR_ARCHITECTURE_INTEL: + { + int cpu; + + if(info.dwPlatformId == VER_PLATFORM_WIN32_NT) + cpu = si.wProcessorLevel; + else { + switch(si.dwProcessorType) { + case PROCESSOR_INTEL_386: + cpu = 3; + break; + case PROCESSOR_INTEL_486: + cpu = 4; + break; + default: + cpu = 5; + break; + } + } + sprintf(processor, "i%d86", cpu); + } + break; + case PROCESSOR_ARCHITECTURE_MIPS: + sprintf(processor, "mips%d000", si.wProcessorLevel); + break; + case PROCESSOR_ARCHITECTURE_ALPHA: + sprintf(processor, "alpha%d", si.wProcessorLevel); + break; + case PROCESSOR_ARCHITECTURE_PPC: + switch(si.wProcessorLevel) { + case 1: + strcpy(processor, "ppc601"); + break; + case 3: + strcpy(processor, "ppc603"); + break; + case 4: + strcpy(processor, "ppc604"); + break; + case 6: + strcpy(processor, "ppc603+"); + break; + case 9: + strcpy(processor, "ppc604+"); + break; + case 20: + strcpy(processor, "ppc620"); + break; + default: + strcpy(processor, "ppcXXX"); + break; + } + break; + default: + strcpy(processor, "unknown"); + break; + } + if(info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) + info.dwBuildNumber = info.dwBuildNumber & 0x0000ffffl; + if(info.dwPlatformId == VER_PLATFORM_WIN32_NT and *info.szCSDVersion != NUL) { + char _tmp[128]; + strcpy(_tmp, info.szCSDVersion); + strchg(_tmp, ' ', '_'); + sprintf(osstring, "%s %ld.%ld.%ld-%s %s", ostype, info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber, _tmp, processor); + } + else + sprintf(osstring, "%s %ld.%ld.%ld %s", ostype,info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber, processor); + } + else + strcpy(osstring, "unknown"); + + #else + + #if defined(__MSDOS__) + const char* osname = "DOS"; + #elif defined(__OS2__) + const char* osname = "OS/2"; + #endif + + sprintf(osstring, "%s %d.%02d ix86", osname, _osmajor, _osminor); + + #endif + } + + return osstring; +} + + +// ------------------------------------------------------------------- diff --git a/goldlib/gall/gutlwin.cpp b/goldlib/gall/gutlwin.cpp new file mode 100644 index 0000000..4877f7c --- /dev/null +++ b/goldlib/gall/gutlwin.cpp @@ -0,0 +1,331 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Various Windows functions. +// ------------------------------------------------------------------ +// Clipboard handling donated by Eugene Roshal +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#ifndef __NO_MMSYSTEM +#include +#endif + + +// ------------------------------------------------------------------ + +OSVERSIONINFO WinVer; +char ge_win_coldtitle[GMAXTITLE] = ""; +char ge_win_title[GMAXTITLE] = ""; +int ge_win_ext_title; + +char tu[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +char tl[256] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + + +// ------------------------------------------------------------------ + +int g_init_os(int flags) { + + NW(flags); + + int i; + memset(&WinVer, 0, sizeof(OSVERSIONINFO)); + WinVer.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + GetVersionEx(&WinVer); + GetConsoleTitle(ge_win_coldtitle, sizeof(ge_win_coldtitle)); + if(WinVer.dwPlatformId == VER_PLATFORM_WIN32_NT) { + for(i = 0; i < 256; i++) { + tu[i] = (toupper)(i); + tl[i] = (tolower)(i); + } + return 0; + } + // Due to Win9x doesn't have proper locale support we should rebuild + // tolower/toupper tables + char src[2], dst[2]; + for(i = 0; i < 128; i++) { + tu[i] = (toupper)(i); + tl[i] = (tolower)(i); + } + for(i = 128; i < 256; i++) { + *dst = i; dst[1] = 0; + OemToChar(dst, src); + LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_UPPERCASE, src, 1, dst, 2); + CharToOem(dst, src); + tu[i] = (*src & 0xff); + *dst = i; dst[1] = 0; + OemToChar(dst, src); + LCMapString(LOCALE_SYSTEM_DEFAULT, LCMAP_LOWERCASE, src, 1, dst, 2); + CharToOem(dst, src); + tl[i] = (*src & 0xff); + } + for(i = 128; i < 256; i++) { + if((tu[tl[i]] != i) && (tl[tu[i]] != i)) + tu[i] = tl[i] = i; + if(tu[tl[i]] != tu[i]) + tu[i] = i; + if(tl[tu[i]] != tl[i]) + tl[i] = i; + } + return 0; +} + + +// ------------------------------------------------------------------ + +void g_deinit_os(void) { + + SetConsoleTitle(ge_win_coldtitle); +} + + +// ------------------------------------------------------------------ + +void g_init_title(char* tasktitle, int titlestatus) { + + strncpy(ge_win_title, tasktitle, GMAXTITLE); + ge_win_title[GMAXTITLE-1] = '\0'; + ge_win_ext_title = titlestatus; +} + + +// ------------------------------------------------------------------ + +void g_increase_priority(void) { + + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); +} + + +// ------------------------------------------------------------------ + +void g_set_ostitle(char *title) { + + SetConsoleTitle(title); +} + + +// ------------------------------------------------------------------ + +void g_set_osicon(void) { + + // do nothing +} + + +// ------------------------------------------------------------------ + +bool g_is_clip_available(void) { + + return true; +} + + +// ------------------------------------------------------------------ + +char* g_get_clip_text(void) { + + HANDLE hClipData; + if(not OpenClipboard(NULL)) + return NULL; + int Unicode = false; + int Format = 0; + int ReadType = CF_OEMTEXT; + while((Format = EnumClipboardFormats(Format)) != 0) { + if(Format == CF_UNICODETEXT && WinVer.dwPlatformId == VER_PLATFORM_WIN32_NT) { + Unicode = true; + break; + } + if(Format == CF_TEXT) { + ReadType = CF_TEXT; + break; + } + if(Format == CF_OEMTEXT) + break; + } + char *ClipText = NULL; + if((hClipData = GetClipboardData(Unicode ? CF_UNICODETEXT : ReadType)) != NULL) { + int BufferSize; + char *ClipAddr = (char *)GlobalLock(hClipData); + if(Unicode) + BufferSize = lstrlenW((LPCWSTR)ClipAddr) + 1; + else + BufferSize = strlen(ClipAddr) + 1; + ClipText = (char *) throw_malloc(BufferSize); + if(ClipText != NULL) + if(Unicode) + WideCharToMultiByte(CP_OEMCP, 0, (LPCWSTR)ClipAddr, -1, ClipText, BufferSize, NULL, NULL); + else + if(ReadType == CF_TEXT) + CharToOem(ClipAddr, ClipText); + else + strcpy(ClipText, ClipAddr); + GlobalUnlock(hClipData); + } + CloseClipboard(); + return ClipText; +} + + +// ------------------------------------------------------------------ + +int g_put_clip_text(char *Data) { + + long DataSize; + if((Data != NULL) and ((DataSize = strlen(Data)) != 0)) { + HGLOBAL hData; + void *GData; + if(not OpenClipboard(NULL)) + return -1; + EmptyClipboard(); + int BufferSize = DataSize + 1; + if((hData=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, BufferSize)) != NULL) + if((GData = GlobalLock(hData)) != NULL) { + memcpy(GData, Data, DataSize + 1); + GlobalUnlock(hData); + SetClipboardData(CF_OEMTEXT, (HANDLE)hData); + } + if((hData=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, BufferSize)) != NULL) + if((GData=GlobalLock(hData)) != NULL) { + memcpy(GData, Data, DataSize + 1); + OemToChar((LPCSTR)GData, (LPTSTR)GData); + GlobalUnlock(hData); + SetClipboardData(CF_TEXT, (HANDLE)hData); + } + if(WinVer.dwPlatformId == VER_PLATFORM_WIN32_NT) + if((hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, BufferSize * 2)) != NULL) + if((GData = GlobalLock(hData)) != NULL) { + MultiByteToWideChar(CP_OEMCP, 0, Data, -1, (LPWSTR)GData, BufferSize); + GlobalUnlock(hData); + SetClipboardData(CF_UNICODETEXT, (HANDLE)hData); + } + CloseClipboard(); + } + return 0; +} + + +// ------------------------------------------------------------------ + +void g_get_ostitle_name(char *title) { + + GetConsoleTitle(title, GMAXTITLE); +} + + +// ------------------------------------------------------------------ + +void g_set_ostitle_name(char *title, int mode) { + + if(mode == 0) { + char fulltitle[GMAXTITLE]; + strcpy(fulltitle, ge_win_title); + if(ge_win_ext_title) { + int len = strlen(fulltitle); + if(len < GMAXTITLE-4) { + if(len) + strcat(fulltitle, " - "); + strncpy(fulltitle+len+3, title, GMAXTITLE-len-3); + fulltitle[GMAXTITLE-1] = '\0'; + } + } + g_set_ostitle(fulltitle); + } + else + g_set_ostitle(title); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gutlwinm.cpp b/goldlib/gall/gutlwinm.cpp new file mode 100644 index 0000000..22db34b --- /dev/null +++ b/goldlib/gall/gutlwinm.cpp @@ -0,0 +1,54 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Various Windows functions. +// ------------------------------------------------------------------ +// Clipboard handling donated by Eugene Roshal +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +// ------------------------------------------------------------------ + +int g_send_mci_string(char* string, char* his_buffer) { + + char our_buffer[BUFFERSIZE], *return_buffer; + + return_buffer = his_buffer ? his_buffer : our_buffer; + memset(return_buffer, 0, BUFFERSIZE); + + MCIERROR rc = mciSendString(string, return_buffer, BUFFERSIZE, NULL); + + if(rc == 0) + return 1; + else { + mciGetErrorString(rc, return_buffer, BUFFERSIZE); + return 0; + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gvidall.h b/goldlib/gall/gvidall.h new file mode 100644 index 0000000..86dd5b2 --- /dev/null +++ b/goldlib/gall/gvidall.h @@ -0,0 +1,420 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// Screen/video functions. +// ------------------------------------------------------------------ + +#ifndef __gvidall_h +#define __gvidall_h + + +// ------------------------------------------------------------------ + +#include +#if defined(__USE_NCURSES__) +#include +#else +#define ACS_BOARD '°' +#define ACS_BLOCK 'Û' +#endif + + +// ------------------------------------------------------------------ +// Display adapter types returned from vidtype() +// If bit 0 is set, the adapter was detected in monochrome mode + +#define GV_NONE 0x0000 +#define V_MONO 0x0001 +#define V_MDA 0x0011 +#define V_HGC 0x0021 +#define V_HGCPLUS 0x0041 +#define V_INCOLOR 0x0080 +#define V_CGA 0x0100 +#define V_EGA 0x0200 +#define V_EGAMONO 0x0201 +#define V_MCGA 0x0400 +#define V_MCGAMONO 0x0401 +#define V_VGA 0x0800 +#define V_VGAMONO 0x0801 + + +// ------------------------------------------------------------------ +// Video parameter settings + +#define VP_DMA 0 // direct screen writes +#define VP_CGA 1 // direct screen writes, eliminate CGA snow +#define VP_BIOS 2 // BIOS screen writes +#define VP_MONO 3 // monochrome attribute translation on +#define VP_COLOR 4 // monochrome attribute translation off +#define VP_OS2VIO 6 // OS/2 vio screen writes +#define VP_W32CON 7 // WIN32 console screen writes +#define VP_CURSES 8 // Curses screen writes + + +// ------------------------------------------------------------------ +// Video devices + +#define GVID_DMA 0 +#define GVID_CGA 1 +#define GVID_BIO 2 +#define GVID_OS2 4 +#define GVID_W32 5 +#define GVID_CUR 6 + + +// ------------------------------------------------------------------ +// Useful defines for video (0x10) interrupt function numbers + +#if defined(__MSDOS__) +#define V_SET_MODE 0x00 +#define V_SET_CURSOR_POS 0x02 +#define V_GET_CURSOR_POS 0x03 +#define V_SCROLL_UP 0x06 +#define V_SCROLL_DOWN 0x07 +#define V_RD_CHAR_ATTR 0x08 +#define V_WR_CHAR_ATTR 0x09 +#define V_WR_CHAR 0x0A +#define V_WR_TTY 0x0E +#define V_GET_MODE 0x0F +#define V_GET_FONT_INFO 0x1130 +#endif + + +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) +struct __int10_ah1b_statebuf { + // Offset Size Description + dword statfunctable; // 00h DWORD address of static funtionality table (see below) + byte videomode; // 04h BYTE video mode in effect + word columns; // 05h WORD number of columns + word regenbuflen; // 07h WORD length of regen buffer in bytes + word regenbufstart; // 09h WORD starting address of regen buffer + word cursorpos0; // 0Bh WORD cursor position for page 0 + word cursorpos1; // 0Dh WORD cursor position for page 1 + word cursorpos2; // 0Fh WORD cursor position for page 2 + word cursorpos3; // 11h WORD cursor position for page 3 + word cursorpos4; // 13h WORD cursor position for page 4 + word cursorpos5; // 15h WORD cursor position for page 5 + word cursorpos6; // 17h WORD cursor position for page 6 + word cursorpos7; // 19h WORD cursor position for page 7 + word cursortype; // 1Bh WORD cursor type + byte activepage; // 1Dh BYTE active display page + word crctportaddr; // 1Eh WORD CRTC port address + byte curr_reg_3x8; // 20h BYTE current setting of register (3?8) + byte curr_reg_3x9; // 21h BYTE current setting of register (3?9) + byte rows; // 22h BYTE number of rows + word bytesperchar; // 23h WORD bytes/character + byte dispcombcode; // 25h BYTE display combination code of active display + byte dcc; // 26h BYTE DCC of alternate display + word numcolors; // 27h WORD number of colors supported in current mode + byte numpages; // 29h BYTE number of pages supported in current mode + byte numscanlines; // 2Ah BYTE number of scan lines active (0,1,2,3) = (200,350,400,480) Tseng ET3000: (4,5,6 = 512,600,768) + byte primcharblock; // 2Bh BYTE primary character block + byte seccharblock; // 2Ch BYTE secondary character block + byte miscflags; // 2Dh BYTE miscellaneous flags (see below) + byte reserved1[3]; // 2Eh 3 BYTEs reserved (00h) + byte videomem; // 31h BYTE video memory available 00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K + byte stateflags; // 32h BYTE save pointer state flags (see below) + byte reserved2[13]; // 33h 13 BYTEs reserved (00h) +}; +#endif + + +// ------------------------------------------------------------------ +// Attribute codes for functions that use them + +#define BLACK 0 +#define BLUE 1 +#define GREEN 2 +#define CYAN 3 +#define RED 4 +#define MAGENTA 5 +#define BROWN 6 +#define LGREY 7 +#define DGREY 8 +#define LBLUE 9 +#define LGREEN 10 +#define LCYAN 11 +#define LRED 12 +#define LMAGENTA 13 +#define YELLOW 14 +#define WHITE 15 + +#define _BLACK (BLACK << 4) +#define _BLUE (BLUE << 4) +#define _GREEN (GREEN << 4) +#define _CYAN (CYAN << 4) +#define _RED (RED << 4) +#define _MAGENTA (MAGENTA << 4) +#define _BROWN (BROWN << 4) +#define _LGREY (LGREY << 4) +#define _DGREY (DGREY << 4) +#define _LBLUE (LBLUE << 4) +#define _LGREEN (LGREEN << 4) +#define _LCYAN (LCYAN << 4) +#define _LRED (LRED << 4) +#define _LMAGENTA (LMAGENTA << 4) +#define _YELLOW (YELLOW << 4) +#define _WHITE (WHITE << 4) + +#undef BLINK +#define BLINK 128 + +#if defined(__UNIX__) and not defined(__USE_NCURSES__) +#define ACSET BLINK +#else +#define ACSET 0 +#endif + + +// ------------------------------------------------------------------ +// Additional monochrome color values + +#define UNDERLINE 1 +#define NORMAL 7 +#define HIGHLIGHT 15 +#define REVERSE 112 + + +// ------------------------------------------------------------------ +// Border types + +#define BT_SINGLE 0 +#define BT_DOUBLE 1 +#define BT_SINGLETOP 2 +#define BT_DOUBLETOP 3 +#define BT_BLANKS 4 +#define BT_NONE 5 +#define BT_BLOCKS 6 +#define BT_ASCII 7 + + +// ------------------------------------------------------------------ +// Video information structure + +struct GVidInfo { + + // Screen info + struct { + int mode; // Video mode + int rows; // Number of rows + int columns; // Number of columns + int cheight; // Character height + int cwidth; // Character width + } screen; + + // Cursor info + struct { + int column; // Cursor column + int row; // Cursor row + int start; // Cursor start line + int end; // Cursor end line + word attr; // Cursor attribute. Hidden if attr == 0xFFFF + } cursor; + + // Colors + struct { + int textattr; // Text attribute + int overscan; // Overscan color + int intensity; // Background color state (intense or blinking) + int palette[16]; // Palette state + } color; +}; + + +// ------------------------------------------------------------------ + +#ifdef __DJGPP__ +typedef unsigned long gdma; // Video DMA linear address +#else +typedef word* gdma; // Video DMA pointer +#endif + +// ------------------------------------------------------------------ + +#if defined(__USE_NCURSES__) +typedef chtype vchar; // Type of characters on-screen +typedef chtype vatch; // Type of character-attribute groups +#else +typedef char vchar; // Type of characters on-screen +typedef word vatch; // Type of character-attribute groups +#endif + +// ------------------------------------------------------------------ +// Video information record + +class GVid { + +public: + + int adapter; // Video adapter type + + GVidInfo orig; // Original video info + GVidInfo curr; // Current video info + + int device; // Video device type + + gdma dmadir; // Video DMA pointer (direct) + gdma dmaptr; // Video DMA pointer (direct or buffered) + + vchar* bufchr; // Video line char buffer (char only) + vatch* bufwrd; // Video line word buffer (char+attr) + vchar* bufansi; // Video line ANSI buffer (11*numcols) + + int currow; // Current cursor row + int curcol; // Current cursor column + + int numrows; // number of displayed rows + int numcols; // number of displayed columns + + word videoseg; // video buffer segment address + +public: + + GVid(); + ~GVid(); + +public: + + void init(); + + int detectadapter (); + void detectinfo (GVidInfo* _info); + + void resetcurr (); + + void setdevice (int _device); + + void setmode (int _mode); + void setrows (int _rows); + + void setoverscan (int _overscan); + void setintensity (int _intensity); + + void getpalette (int* _palette); + void setpalette (int* _palette); + + bool isdma() { return device == GVID_DMA; } + bool iscga() { return device == GVID_CGA; } + bool isbios() { return device == GVID_BIO; } + + void restore_cursor(); + + void resize_screen(int columns, int rows); + +}; + +extern GVid *gvid; + +#if defined(__UNIX__) and not defined(__USE_NCURSES__) +extern bool gvid_xterm; +#endif + + +// ------------------------------------------------------------------ +// Box characters table + +#if not defined(__USE_NCURSES__) + +extern char* __box_table[]; +#define _box_table(i,j) (__box_table[i][j]) + +#else + +chtype _box_table(int type, int c); + +#endif + + +// ------------------------------------------------------------------ +// Prototypes + +int setvparam (int setting); + +int mapattr (int attr); +int revsattr (int attr); + +inline int attrib(int f, int b, int i, int bl) { return (int)((b<<4)|(f)|(i<<3)|(bl<<7)); } + +void vputw (int row, int col, vatch chat); +void vputws (int row, int col, vatch* buf, uint len); +void vputc (int row, int col, int atr, vchar chr); +void vputvs (int row, int col, int atr, const vchar* str); +void vputs (int row, int col, int atr, const char* str); +void vputns (int row, int col, int atr, const char* str, uint len); +void vputx (int row, int col, int atr, vchar chr, uint len); +void vputy (int row, int col, int atr, vchar chr, uint len); + +vatch vgetw (int row, int col); +void vgetc (int row, int col, int* atr, vchar* chr); + +void vscroll (int srow, int scol, int erow, int ecol, int atr, int lines); + +void vposget (int* row, int* col); +void vposset (int row, int col); + +void vclrscr (); +void vclrscr (int atr); // Overloaded + +vatch* vsave (int srow=-1, int scol=-1, int erow=-1, int ecol=-1); +void vredraw (vatch* buf, int srow=-1, int scol=-1, int erow=-1, int ecol=-1); +void vrestore (vatch* buf, int srow=-1, int scol=-1, int erow=-1, int ecol=-1); + +void vcurget (int* sline, int* eline); +void vcurset (int sline, int eline); + +void vcurhide (); +void vcurshow (); +bool vcurhidden (); + +void vcurlarge (); +void vcursmall (); + +void vbox (int srow, int scol, int erow, int ecol, int box, int hiattr, int loattr=-1); +void vfill (int srow, int scol, int erow, int ecol, vchar chr, int atr); + +#if not defined(__USE_NCURSES__) +inline vchar vgetc (int row, int col) { return (vchar)(0xFF & vgetw(row, col)); } +#else +inline vchar vgetc (int row, int col) { return (vchar)((A_CHARTEXT|A_ALTCHARSET) & vgetw(row, col)); } +#endif + +vchar vgchar (vatch chat); +int vgattr (vatch chat); +vatch vschar (vatch chat, vchar chr); +vatch vsattr (vatch chat, int atr); +vatch vcatch (vchar chr, int atr); + +typedef void (*VidPutStrCP)(int,int,int,const char*); + +void gvid_boxcvt(char* s); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gvidbase.cpp b/goldlib/gall/gvidbase.cpp new file mode 100644 index 0000000..61d3b95 --- /dev/null +++ b/goldlib/gall/gvidbase.cpp @@ -0,0 +1,2351 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// Copyright (C) 2000 Jacobo Tarrio +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Device-independent video functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__OS2__) +#define INCL_BASE +#include +#ifndef __EMX__ +#define PCCH CHAR* +#endif +#endif + +#ifdef __WIN32__ +#include +#endif + +#ifdef __GNUC__ +#include +#endif + +#if defined(__DJGPP__) +#include +#endif + + +// ------------------------------------------------------------------ +// Check if Borland C++ for OS/2 1.0 header has been fixed + +#if defined(__OS2__) and defined(__BORLANDC__) + #if __BORLANDC__ <= 0x400 + #ifndef BCOS2_BSESUB_FIXED + #error There is a bug in the BSESUB.H header. Please fix it. + // + // Add/change the following in BSESUB.H: + // + // #define BCOS2_BSESUB_FIXED + // APIRET16 APIENTRY16 VioGetState (PVOID16 pState, HVIO hvio); + // APIRET16 APIENTRY16 VioSetState (PVOID16 pState, HVIO hvio); + // + // Borland forgot this (was only PVOID) ^^ + // + #endif + #endif +#endif + + +// ------------------------------------------------------------------ + +static bool __vcurhidden = false; + +#if not defined(__USE_NCURSES__) + +// ------------------------------------------------------------------ + +#ifdef __WIN32__ +extern HANDLE gvid_hout; +#endif + + +// ------------------------------------------------------------------ + +#if defined(__MSDOS__) or defined(__UNIX__) + +#ifndef __DJGPP__ +const unsigned short _dos_ds = 0; + +inline unsigned short _my_ds(void) { + + return 0; +} + +inline void _farpokew(unsigned short s, gdma ptr, word chat) { + + NW(s); + *ptr = chat; +} + +inline void _farnspokew(gdma ptr, word chat) { + + *ptr = chat; +} + +inline word _farpeekw(unsigned short s, gdma ptr) { + + NW(s); + return *ptr; +} + +inline void _farnspokeb(byte *ptr, byte chr) { + + *ptr = chr; +} + +inline void _farsetsel(unsigned short s) { + + NW(s); +} +#endif + +#ifdef __DJGPP__ +const int ATTRSIZE = sizeof(word); +#else +const int ATTRSIZE = 1; +#endif + +inline void gdmacpy(unsigned short seg_d, gdma sel_d, unsigned short seg_s, gdma sel_s, int len) { + + #ifdef __DJGPP__ + movedata(seg_s, sel_s, seg_d, sel_d, len); + #else + NW(seg_d); + NW(seg_s); + memcpy(sel_d, sel_s, len); + #endif +} + +inline gdma gdmaptr(int col, int row) { + + return gvid->dmaptr+ATTRSIZE*((row*gvid->numcols)+col); +} +#endif + + +// ------------------------------------------------------------------ + +#if defined(__UNIX__) + + +// ------------------------------------------------------------------ + +extern int gvid_stdout; +extern bool gvid_xterm; +extern const char* gvid_acs_enable; +extern const char* gvid_acs_disable; +int gvid_last_attr = 0; + + +// ------------------------------------------------------------------ + +void gvid_printf(const char* fmt, ...) { + + char buf[1024]; + va_list argptr; + va_start(argptr, fmt); + int n = vsprintf(buf, fmt, argptr); + va_end(argptr); + + write(gvid_stdout, buf, n); +} + + +// ------------------------------------------------------------------ +// Control chars 01234567890123456789012345678901 + +const char* gvid_x0 = "x@xxxxxxxxxxxxxx>>4) & 7]; +} + + +// ------------------------------------------------------------------ + +void vputansi(int row, int col, word* buf, int len) { + + char ch; + int in, fg, bg, acs; + int atr = gvid_last_attr; + int in0 = vatr2ansin(atr); + int fg0 = vatr2ansfg(atr); + int bg0 = vatr2ansbg(atr); + int acs0 = atr & ACSET; + + // Get pointer to ANSI line buffer + char* ptr = gvid->bufansi; + + // Get pointer to video memory image + byte* p = (byte*)buf; + + for(int n=0; nbufansi); +} + + +// ------------------------------------------------------------------ + +#endif + +#endif // not defined(__USE_NCURSES__) + + +// ------------------------------------------------------------------ + +extern int __gdvdetected; + + +// ------------------------------------------------------------------ +// Converts an attribute to monochrome equivalent + +int mapattr(int attr) { + + switch(attr&112) { // test for a light background + + case _LGREY: + case _GREEN: + case _CYAN: + case _BROWN: + attr &= 240; // foreground = black + attr |= 112; // background = light grey + break; + + default: + if((attr&15)==8) // if foreground = dark grey + attr &= 247; // clear intensity bit + attr |= 7; // foreground = light grey + attr &= 143; // background = black + } + + return attr; // return converted attribute +} + + +// ------------------------------------------------------------------ +// Reverses the attribute given + +int revsattr(int attr) { + + return (int)(((attr>>4)&0x07)|((attr<<4)&0x70)|(attr&0x80)|(attr&0x08)); +} + +#if not defined(__USE_NCURSES__) + + +// ------------------------------------------------------------------ + +#if defined(__UNIX__) +char* gvid_newattr(int& attr) { + + // 12345678901234567890 + // E[1;33;44mE[11m + static char newattr[20]; + *newattr = NUL; + if(attr != gvid_last_attr) { + if((attr & ~ACSET) != (gvid_last_attr & ~ACSET)) { + sprintf(newattr, "\033[%c;3%u;4%um", + vatr2ansin(attr) ? '1' : '0', + vatr2ansfg(attr), + vatr2ansbg(attr) + ); + } + if((attr & ACSET) != (gvid_last_attr & ACSET)) + strcat(newattr, (attr & ACSET) ? gvid_acs_enable : gvid_acs_disable); + gvid_last_attr = attr; + } + + return newattr; +} +#endif + + +// ------------------------------------------------------------------ +// OS/2 Vio* wrappers for prevent 16-bit segment overrun + +#if defined(__OS2__) + +#ifndef _THUNK_PTR_SIZE_OK +#define _THUNK_PTR_SIZE_OK(ptr,size) (((ULONG)(ptr) & ~0xffff) == (((ULONG)(ptr) + (size) - 1) & ~0xffff)) +#endif + +static USHORT VioReadCellStr_(PCH str, PUSHORT pcb, USHORT row, USHORT col, HVIO hvio) { + USHORT rc, cb = *pcb; + + if(_THUNK_PTR_SIZE_OK(str, cb)) + return VioReadCellStr(str, pcb, row, col, hvio); + PCH newstr = (PCH)throw_xmalloc(cb * 2); + if(_THUNK_PTR_SIZE_OK(newstr, cb)) { + rc = VioReadCellStr(newstr, pcb, row, col, hvio); + if(rc == 0) + memcpy(str, newstr, *pcb); + } + else { + rc = VioReadCellStr(newstr + cb, pcb, row, col, hvio); + if(rc == 0) + memcpy(str, newstr + cb, *pcb); + } + throw_xfree(newstr); + return rc; +} + + +static USHORT VioWrtCellStr_(PCCH str, USHORT cb, USHORT row, USHORT col, HVIO hvio) { + USHORT rc; + + if(_THUNK_PTR_SIZE_OK(str, cb )) + return VioWrtCellStr(str, cb, row, col, hvio); + PCH newstr = (PCH)throw_xmalloc(cb * 2); + if(_THUNK_PTR_SIZE_OK(newstr, cb)) { + memcpy(newstr, str, cb); + rc = VioWrtCellStr(newstr, cb, row, col, hvio); + } + else { + memcpy(newstr + cb, str, cb); + rc = VioWrtCellStr(newstr + cb, cb, row, col, hvio); + } + throw_xfree(newstr); + return rc; +} + + +static USHORT VioWrtCharStrAtt_(PCCH str, USHORT cb, USHORT row, USHORT col, PBYTE attr, HVIO hvio) { + USHORT rc; + + if(_THUNK_PTR_SIZE_OK(str, cb)) + return VioWrtCharStrAtt(str, cb, row, col, attr, hvio); + PCH newstr = (PCH)throw_xmalloc(cb * 2); + if(_THUNK_PTR_SIZE_OK(newstr, cb)) { + memcpy(newstr, str, cb); + rc = VioWrtCharStrAtt(newstr, cb, row, col, attr, hvio); + } + else { + memcpy(newstr + cb, str, cb); + rc = VioWrtCharStrAtt(newstr + cb, cb, row, col, attr, hvio); + } + throw_xfree(newstr); + return rc; +} + +#define VioReadCellStr VioReadCellStr_ +#define VioWrtCellStr VioWrtCellStr_ +#define VioWrtCharStrAtt VioWrtCharStrAtt_ + +#endif + +// ------------------------------------------------------------------ +// ncurses support functions + +#else // defined(__USE_NCURSES__) + +// ------------------------------------------------------------------ +// Compute our attributes from DOS attributes + +int gvid_attrcalc (int dosattr) { + + // DOS attrs: XRGBxrgb + // color pair definition: 00RGBrgb, with last 3 bits negated + int attr; + attr = COLOR_PAIR(((dosattr & 0x70) >> 1) | ((~dosattr) & 0x07)); + if(dosattr & 0x08) + attr |= A_BOLD; +// if(dosattr & 0x80) +// attr |= A_BLINK; + + return attr; +} + +// ------------------------------------------------------------------ +// Compute DOS attributes from our attributes + +int gvid_dosattrcalc (int ourattr) { + + int attr = 0; + attr = PAIR_NUMBER(ourattr); + attr = ((attr & 0x38) << 1) | ((~attr) & 0x07); + if(ourattr & A_BLINK) + attr |= 0x80; + if(ourattr & A_BOLD) + attr |= 0x08; + + return attr; +} + +// ------------------------------------------------------------------ +// Transform character < 32 into printable equivalent + + +chtype gvid_tcpr (vchar chr) { + +chtype gvid_cpr[] = { + (chtype)' ', (chtype)'@', (chtype)'@', (chtype)'x', + (chtype) ACS_DIAMOND, (chtype)'x', (chtype)'x', ACS_BULLET, + ACS_BULLET, ACS_BULLET, ACS_BULLET, (chtype)'x', + (chtype)'x', (chtype)'x', (chtype)'x', ACS_LANTERN, + ACS_LARROW, (chtype) ACS_RARROW, (chtype)'x', (chtype)'!', + (chtype)'x', (chtype)'x', ACS_S1, (chtype)'x', + ACS_UARROW, ACS_DARROW, ACS_LARROW, (chtype)ACS_RARROW, + (chtype)'x', (chtype)'x', ACS_UARROW, ACS_DARROW +}; + + chtype ch = chr & A_CHARTEXT; + chtype at = chr & (~A_CHARTEXT); + + if(ch<' ') + return gvid_cpr[ch] | at; + else + return ch | at; +} + + +// ------------------------------------------------------------------ + +#endif // defined(__USE_NCURSES__) + + +// ------------------------------------------------------------------ +// Print character and attribute at specfied location + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +inline void _vputw(int row, int col, word chat) { + + _farpokew(_dos_ds, gdmaptr(col, row), chat); +} +#endif + + +void vputw(int row, int col, vatch chat) { + + #if defined(__USE_NCURSES__) + + mvaddch(row, col, chat); + refresh(); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + _vputw(row, col, chat); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)col); + cpu.genint(0x10); + cpu.ah(9); + cpu.al((byte)(chat&0xFF)); + cpu.bh(0); + cpu.bl((byte)(chat>>8)); + cpu.cx(1); + cpu.genint(0x10); + } + + #elif defined(__OS2__) + + BYTE tmp[2]; + tmp[0] = (BYTE)(chat & 0xFF); + tmp[1] = (BYTE)(chat >> 8); + VioWrtNCell(tmp, 1, (USHORT)row, (USHORT)col, 0); + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + word atr = (word) (chat >> 8); + + coord.X = (SHORT) col; + coord.Y = (SHORT) row; + WriteConsoleOutputAttribute(gvid_hout, &atr, 1, coord, &x); + WriteConsoleOutputCharacter(gvid_hout, (char* ) &chat, 1, coord, &x); + + #elif defined(__UNIX__) + + char chr = (char)(chat & 0xFF); + int atr = chat >> 8; + char* color = gvid_newattr(atr); + chat = (word)(chr | (atr << 8)); + + gvid_cvtstr(&chat, 1); + _vputw(row, col, chat); + + gvid_printf("\033[%u;%uH%s%c", row+1, col+1, color, chr); + + #endif +} + + +// ------------------------------------------------------------------ +// Print attrib/char buffer at specfied location + +void vputws(int row, int col, vatch* buf, uint len) { + + #if defined(__USE_NCURSES__) + + move(row, col); + for(int counter = 0; counter < len; counter++) + addch(buf[counter]); + refresh(); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + gdmacpy(_dos_ds, (gdma)gdmaptr(col, row), _my_ds(), (gdma)buf, len*sizeof(word)); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + byte* p = (byte*)buf; + for(uint n=0; nbufwrd; + char* c = gvid->bufchr; + + for(int i = 0; i < len; i++) { + *c++ = *p++; + *q++ = *p++; + } + + WriteConsoleOutputAttribute(gvid_hout, gvid->bufwrd, len, coord, &x); + WriteConsoleOutputCharacter(gvid_hout, gvid->bufchr, len, coord, &x); + + #elif defined(__UNIX__) + + gvid_cvtstr(buf, len); + gdmacpy(_dos_ds, (gdma)gdmaptr(col, row), _my_ds(), (gdma)buf, len*sizeof(word)); + vputansi(row, col, buf, len); + + #endif +} + + +// ------------------------------------------------------------------ +// Print character and attribute at specfied location + +void vputc(int row, int col, int atr, vchar chr) { + + #if defined(__USE_NCURSES__) + + mvaddch(row, col, gvid_tcpr(chr) | gvid_attrcalc(atr)); + refresh(); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + _vputw(row, col, (word)((atr << 8) | chr)); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)col); + cpu.genint(0x10); + cpu.ah(9); + cpu.al(chr); + cpu.bh(0); + cpu.bl((byte)atr); + cpu.cx(1); + cpu.genint(0x10); + } + + #elif defined(__OS2__) + + BYTE tmp[2]; + tmp[0] = chr; + tmp[1] = (BYTE)atr; + VioWrtNCell(tmp, 1, (USHORT)row, (USHORT)col, 0); + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + + coord.X = (SHORT) col; + coord.Y = (SHORT) row; + WriteConsoleOutputAttribute(gvid_hout, (word *) &atr, 1, coord, &x); + WriteConsoleOutputCharacter(gvid_hout, (char *) &chr, 1, coord, &x); + + #elif defined(__UNIX__) + + char* color = gvid_newattr(atr); + gvid_cvtstr(&chr, 1); + _vputw(row, col, (word)((atr << 8) | chr)); + + gvid_printf("\033[%u;%uH%s%c", row+1, col+1, color, chr); + + #endif +} + + +// ------------------------------------------------------------------ +// Print string with attribute at specfied location + +void vputvs(int row, int col, int atr, const vchar* str) { + + #if defined(__USE_NCURSES__) + + uint counter; + int attr = gvid_attrcalc(atr); + move(row, col); + for(counter = 0; str[counter] != 0; counter++) + addch(gvid_tcpr(str[counter]) | attr); + refresh(); + +#else + + vputs(row, col, atr, str); + +#endif +} + + +// ------------------------------------------------------------------ +// Print string with attribute at specfied location + +void vputs(int row, int col, int atr, const char* str) { + + #if defined(__USE_NCURSES__) + + uint counter; + int len = strlen(str); + int attr = gvid_attrcalc(atr); + move(row, col); + for(counter = 0; counter < len; counter++) + addch(gvid_tcpr(str[counter]) | attr); + refresh(); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + gdma p = gdmaptr(col, row); + _farsetsel(_dos_ds); + while(*str) { + _farnspokew(p, (atr << 8) | *str++); + p += ATTRSIZE; + } + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + for(const char* q=str; *q; q++) { + // Write as fast as possible on XT bios... + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)(col++)); + cpu.genint(0x10); + cpu.ah(9); + cpu.al(*q); + cpu.bh(0); + cpu.bl((byte)atr); + cpu.cx(1); + cpu.genint(0x10); + } + } + + #elif defined(__OS2__) + + VioWrtCharStrAtt((PCCH)str, (USHORT)strlen(str), (USHORT)row, (USHORT)col, (PBYTE)&atr, 0); + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + int len = strlen(str); + + coord.X = (SHORT) col; + coord.Y = (SHORT) row; + + FillConsoleOutputAttribute(gvid_hout, (word) atr, len, coord, &x); + WriteConsoleOutputCharacter(gvid_hout, str, len, coord, &x); + + #elif defined(__UNIX__) + + char buf[1024]; + strcpy(buf, str); + char* color = gvid_newattr(atr); + gvid_cvtstr(buf, strlen(buf)); + gdma p = gdmaptr(col, row); + _farsetsel(_dos_ds); + while(*str) { + _farnspokew(p, (atr << 8) | *str++); + p += ATTRSIZE; + } + + gvid_printf("\033[%u;%uH%s%s", row+1, col+1, color, buf); + + #endif +} + + +// ------------------------------------------------------------------ +// Print string with attribute at specfied location + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +static void _vputns(int row, int col, int atr, const char* str, uint width) { + + char fillchar = ' '; + + gdma p = gdmaptr(col, row); + _farsetsel(_dos_ds); + while(width--) { + _farnspokew(p, (atr << 8) | (*str ? *str++ : fillchar)); + p += ATTRSIZE; + } +} +#endif + + +// ------------------------------------------------------------------ +// Print string with attribute at specfied location + +void vputns(int row, int col, int atr, const char* str, uint width) { + + char fillchar = ' '; + + #if defined(__USE_NCURSES__) + + uint counter; + int len = strlen(str); + int attr = gvid_attrcalc(atr); + move(row, col); + for(counter = 0; counter < width; counter++) { + if(counterisdma()) { + _vputns(row, col, atr, str, width); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + while(width--) { + // Write as fast as possible on XT bios... + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)(col++)); + cpu.genint(0x10); + cpu.ah(9); + cpu.al(*str ? *str++ : fillchar); + cpu.bh(0); + cpu.bl((byte)atr); + cpu.cx(1); + cpu.genint(0x10); + } + } + + #elif defined(__OS2__) + + uint len = strlen(str); + + VioWrtCharStrAtt((PCCH)str, (USHORT)minimum_of_two(len,width), (USHORT)row, (USHORT)col, (PBYTE)&atr, 0); + + if(width > len) { + BYTE tmp[2]; + tmp[0] = fillchar; + tmp[1] = (BYTE)atr; + VioWrtNCell(tmp, (USHORT)(width-len), (USHORT)row, (USHORT)(col+len), 0); + } + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + int len = minimum_of_two(strlen(str), width); + + coord.X = (SHORT) col; + coord.Y = (SHORT) row; + FillConsoleOutputAttribute(gvid_hout, (word) atr, width, coord, &x); + WriteConsoleOutputCharacter(gvid_hout, str, len, coord, &x); + + if(width > len) { + coord.X += (SHORT) len; + len = width - len; + + FillConsoleOutputCharacter(gvid_hout, fillchar, len, coord, &x); + } + + #elif defined(__UNIX__) + + char* color = gvid_newattr(atr); + + uint len = strlen(str); + uint min_len = minimum_of_two(len, width); + char buf[1024]; + strcpy(buf, str); + gvid_cvtstr(buf, len); + + _vputns(row, col, atr, buf, width); + + char fillbuf[256]; + if(width > len) { + memset(fillbuf, fillchar, width-len); + fillbuf[width-len] = NUL; + } + else { + *fillbuf = NUL; + } + + gvid_printf("\033[%u;%uH%s%*.*s%s", row+1, col+1, color, + min_len, min_len, buf, fillbuf + ); + + #endif +} + + +// ------------------------------------------------------------------ +// Print horizontal line of character and attribute + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +void _vputx(int row, int col, int atr, char chr, uint len) { + + gdma p = gdmaptr(col, row); + word tmp = (word)((atr << 8) | chr); + _farsetsel(_dos_ds); + for(uint n=0; nisdma()) { + _vputx(row, col, atr, chr, len); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)col); + cpu.genint(0x10); + cpu.ah(9); + cpu.al(chr); + cpu.bh(0); + cpu.bl((byte)atr); + cpu.cx((word)len); + cpu.genint(0x10); + } + + #elif defined(__OS2__) + + BYTE tmp[2]; + tmp[0] = chr; + tmp[1] = (BYTE)atr; + VioWrtNCell(tmp, (USHORT)len, (USHORT)row, (USHORT)col, 0); + + #elif defined(__WIN32__) + + COORD c; + c.X = (SHORT)col; + c.Y = (SHORT)row; + DWORD wr; + FillConsoleOutputCharacter(gvid_hout, chr, len, c, &wr); + FillConsoleOutputAttribute(gvid_hout, (WORD)atr, len, c, &wr); + + #elif defined(__UNIX__) + + char buf[256]; + char* color = gvid_newattr(atr); + gvid_cvtchr(chr); + _vputx(row, col, atr, chr, len); + memset(buf, chr, len); + buf[len] = NUL; + gvid_printf("\033[%u;%uH%s%s", row+1, col+1, color, buf); + + #endif +} + + +// ------------------------------------------------------------------ +// Print vertical line of character and attribute + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +inline void _vputy(int row, int col, int atr, char chr, uint len) { + + gdma p = gdmaptr(col, row); + word tmp = (word)((atr<<8) | chr); + _farsetsel(_dos_ds); + for(uint n=0; nnumcols; + } +} +#endif + + +// ------------------------------------------------------------------ +// Print vertical line of character and attribute + +void vputy(int row, int col, int atr, vchar chr, uint len) { + + #if defined(__USE_NCURSES__) + + int attr = gvid_attrcalc(atr); + mvvline(row, col, gvid_tcpr(chr) | attr, len); + refresh(); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + _vputy(row, col, atr, chr, len); + } + else if(gvid->isbios() or gvid->iscga()) { + for(uint n=0; nnumcols-1) { + sprintf(p, "\033[%u;%uH", row+n+2, col+1); + p += strlen(p); + } + else { + strcpy(p, "\033[D\033[B"); + p += 6; + } + } + *p++ = chr; + *p = NUL; + gvid_printf("%s", buf); + + #endif +} + + +// ------------------------------------------------------------------ +// Get character and attribute at cursor position + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +inline word _vgetw(int row, int col) { + + return _farpeekw(_dos_ds, gdmaptr(col, row)); +} +#endif + + +// ------------------------------------------------------------------ +// Get character and attribute at cursor position + +vatch vgetw(int row, int col) { + + #if defined(__USE_NCURSES__) + + return mvinch(row, col); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + return _vgetw(row, col); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)col); + cpu.genint(0x10); + cpu.ah(8); + cpu.bh(0); + cpu.genint(0x10); + return cpu.ax(); + } + return 0; + + #elif defined(__OS2__) + + word chat; + USHORT _row=(USHORT)row, _col=(USHORT)col, len=sizeof(chat); + + #if defined(__EMX__) + VioReadCellStr((PCH)&chat, &len, _row, _col, 0); + #else + VioReadCellStr((CHAR*)&chat, &len, _row, _col, 0); + #endif + + return chat; + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + word atr; + char chr; + + coord.X = (SHORT) col; + coord.Y = (SHORT) row; + + ReadConsoleOutputAttribute(gvid_hout, &atr, 1, coord, &x); + ReadConsoleOutputCharacter(gvid_hout, &chr, 1, coord, &x); + + return (word)((atr << 8) | chr); + + #elif defined(__UNIX__) + + return _vgetw(row, col); + + #endif +} + + +// ------------------------------------------------------------------ +// Get character and attribute at cursor position + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +inline void _vgetc(int row, int col, int* atr, char* chr) { + + word w = _vgetw(row, col); + *chr = (char)(w & 0xFF); + *atr = (int)(w >> 8); +} +#endif + + +// ------------------------------------------------------------------ +// Get character and attribute at cursor position + +void vgetc(int row, int col, int* atr, vchar* chr) { + + #if defined(__USE_NCURSES__) + + chtype charead = mvinch(row, col); + *chr = (charead & A_CHARTEXT); + *atr = gvid_dosattrcalc(charead & (A_ATTRIBUTES | A_COLOR)); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + _vgetc(row, col, atr, chr); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)col); + cpu.genint(0x10); + cpu.ah(8); + cpu.bh(0); + cpu.genint(0x10); + *chr = cpu.al(); + *atr = cpu.ah(); + } + + #elif defined(__OS2__) + + CHAR tmp[2]; + USHORT _row=(USHORT)row, _col=(USHORT)col, len=sizeof(tmp); + + #if defined(__EMX__) + VioReadCellStr((PCH)tmp, &len, _row, _col, 0); + #else + VioReadCellStr(tmp, &len, _row, _col, 0); + #endif + + *chr = tmp[0]; + *atr = tmp[1]; + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + + coord.X = (SHORT) col; + coord.Y = (SHORT) row; + + ReadConsoleOutputAttribute(gvid_hout, (word* ) atr, 1, coord, &x); + ReadConsoleOutputCharacter(gvid_hout, (char* ) chr, 1, coord, &x); + + #elif defined(__UNIX__) + + _vgetc(row, col, atr, chr); + + #endif +} + + +// ------------------------------------------------------------------ +// Scroll screen area + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +static void _vscroll(int srow, int scol, int erow, int ecol, int atr, int lines) { + + word empty = (atr << 8) | ' '; + if(lines > 0) { + while(lines--) { + int nrow = srow; + int l = ((ecol - scol) + 1); + gdma scrptr = gdmaptr(scol, srow); + while(nrow++ < erow) { + gdmacpy(_dos_ds, (gdma)scrptr, _dos_ds, (gdma)(scrptr+ATTRSIZE*gvid->numcols), l*sizeof(word)); + scrptr += ATTRSIZE*gvid->numcols; + } + _farsetsel(_dos_ds); + for(l *= ATTRSIZE; l>0;) { + l -= ATTRSIZE; + _farnspokew(scrptr+l, empty); + } + } + } + else { + while(lines++) { + int nrow = erow; + int l = ((ecol - scol) + 1); + gdma scrptr = gdmaptr(scol, erow); + while(nrow-- >= (srow + 1)) { + gdmacpy(_dos_ds, (gdma)scrptr, _dos_ds, (gdma)(scrptr-ATTRSIZE*gvid->numcols), l*sizeof(word)); + scrptr -= ATTRSIZE*gvid->numcols; + } + _farsetsel(_dos_ds); + for(l *= ATTRSIZE; l>0;) { + l -= ATTRSIZE; + _farnspokew(scrptr+l, empty); + } + } + } +} +#endif + + +// ------------------------------------------------------------------ +// Scroll screen area + +void vscroll(int srow, int scol, int erow, int ecol, int atr, int lines) { + + #if defined(__USE_NCURSES__) + + // Currently implemented with vsave/vrestore + // Does anyone know a better solution? + + if(lines >= 0) { + if (lines <= 1 + erow - srow) { + vatch *buf = vsave (srow + lines, scol, erow, ecol); + vrestore (buf, srow, scol, erow - lines, ecol); + } + else + lines = 1 + erow - srow; + + for(int counter = 0; counter < lines; counter++) + mvhline(1 + erow + counter - lines, scol, ' ' | gvid_attrcalc(atr), 1 + ecol - scol); + refresh(); + } + else { + lines*=-1; + if (lines <= 1 + erow - srow) { + vatch *buf = vsave (srow, scol, erow - lines, ecol); + vrestore (buf, srow + lines, scol, erow, ecol); + } + else + lines = 1 + erow - srow; + + for(int counter = 0; counter < lines; counter++) + mvhline(srow + counter, scol, ' ' | gvid_attrcalc(atr), 1 + ecol - scol); + refresh(); + } + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + _vscroll(srow, scol, erow, ecol, atr, lines); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ah((byte)(lines > 0 ? 6 : 7)); + cpu.al((byte)absolute(lines)); + cpu.bh((byte)atr); + cpu.ch((byte)srow); + cpu.cl((byte)scol); + cpu.dh((byte)erow); + cpu.dl((byte)ecol); + cpu.genint(0x10); + } + + #elif defined(__OS2__) + + BYTE tmp[2]; + tmp[0] = ' '; + tmp[1] = (BYTE)atr; + if(lines > 0) + VioScrollUp((USHORT)srow, (USHORT)scol, (USHORT)erow, (USHORT)ecol, (USHORT)lines, tmp, 0); + else + VioScrollDn((USHORT)srow, (USHORT)scol, (USHORT)erow, (USHORT)ecol, (USHORT)-lines, tmp, 0); + + #elif defined(__WIN32__) + + CHAR_INFO fill; + fill.Char.UnicodeChar = 0; + fill.Char.AsciiChar = ' '; + fill.Attributes = (WORD)atr; + + SMALL_RECT r; + r.Left = (SHORT)scol; + r.Top = (SHORT)srow; + r.Right = (SHORT)ecol; + r.Bottom = (SHORT)erow; + + COORD c; + c.X = (SHORT)scol; + c.Y = (SHORT)(srow - lines); + + ScrollConsoleScreenBuffer(gvid_hout, &r, &r, c, &fill); + + #elif defined(__UNIX__) + + _vscroll(srow, scol, erow, ecol, atr, lines); + + gdma ptr = gdmaptr(scol, srow); + int len = ecol-scol+1; + for(int nrow=srow; nrow<=erow; nrow++) { + vputansi(nrow, scol, ptr, len); + ptr += ATTRSIZE*gvid->numcols; + } + + #endif +} + + +// ------------------------------------------------------------------ +// Returns true if cursor invisible + +bool vcurhidden() { + + return __vcurhidden; +} + +// ------------------------------------------------------------------ +// Get cursor position + +void vposget(int* row, int* col) { + + #if defined(__USE_NCURSES__) + + getyx(stdscr, gvid->currow, gvid->curcol); + + #elif defined(__MSDOS__) + + i86 cpu; + cpu.ah(3); + cpu.bh(0); + cpu.genint(0x10); + gvid->currow = cpu.dh(); + gvid->curcol = cpu.dl(); + + #elif defined(__OS2__) + + USHORT _getrow, _getcol; + VioGetCurPos(&_getrow, &_getcol, 0); + gvid->currow = _getrow; + gvid->curcol = _getcol; + + #elif defined(__WIN32__) + + CONSOLE_SCREEN_BUFFER_INFO i; + GetConsoleScreenBufferInfo(gvid_hout, &i); + gvid->currow = i.dwCursorPosition.Y; + gvid->curcol = i.dwCursorPosition.X; + + #elif defined(__UNIX__) + + // Not available + + #endif + + *row = gvid->currow; + *col = gvid->curcol; +} + + +// ------------------------------------------------------------------ +// Set cursor position + +void vposset(int row, int col) { + + gvid->currow = row; + gvid->curcol = col; + + #if defined(__USE_NCURSES__) + + move(row, col); + refresh(); + + #elif defined(__MSDOS__) + + i86 cpu; + cpu.ah(2); + cpu.bh(0); + cpu.dh((byte)row); + cpu.dl((byte)col); + cpu.genint(0x10); + + #elif defined(__OS2__) + + VioSetCurPos((USHORT)row, (USHORT)col, 0); + + #elif defined(__WIN32__) + + // No need to set the cursor position if its not visible + // Strangely, this is a major speedup to screen-output + + if(__vcurhidden) + return; + + COORD c; + c.X = (SHORT)col; + c.Y = (SHORT)row; + SetConsoleCursorPosition(gvid_hout, c); + + #elif defined(__UNIX__) + + gvid_printf("\x1B[%u;%uH", row+1, col+1); + + #endif +} + + +// ------------------------------------------------------------------ +// Clears the screen and homes the cursor + +void vclrscr() { + + #if defined(__USE_NCURSES__) + vclrscr((byte)gvid_dosattrcalc(vgetw(gvid->currow, gvid->curcol))); + #else + vclrscr((byte)(vgetw(gvid->currow, gvid->curcol) >> 8)); + #endif +} + + +// ------------------------------------------------------------------ +// Clears the screen using given attribute and homes the cursor + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +static void _vclrscr(int atr) { + + int len = gvid->numrows * gvid->numcols; + + _vputx(0, 0, atr, ' ', len); +} +#endif + + + +// ------------------------------------------------------------------ +// Clears the screen using given attribute and homes the cursor + +void vclrscr(int atr) { + + #if defined(__USE_NCURSES__) + + for(int row = 0; row < LINES; row++) + mvhline(row, 0, ' ' | gvid_attrcalc(atr), COLS); + move(0, 0); + refresh(); + + #elif defined(__MSDOS__) + + if(gvid->isdma()) { + _vclrscr(atr); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + cpu.ax(0x0600); // clear screen by scrolling it + cpu.bh((byte)atr); + cpu.cx(0); + cpu.dh((byte)(gvid->numrows - 1)); + cpu.dl((byte)(gvid->numcols - 1)); + cpu.genint(0x10); + } + + #elif defined(__OS2__) + + BYTE tmp[2]; + tmp[0] = ' '; + tmp[1] = (BYTE)atr; + VioScrollUp(0, 0, 0xFFFF, 0xFFFF, 0xFFFF, tmp, 0); + + #elif defined(__WIN32__) + + COORD c; + c.X = c.Y = 0; + DWORD wr, len = gvid->numrows * gvid->numcols; + FillConsoleOutputCharacter(gvid_hout, ' ', len, c, &wr); + FillConsoleOutputAttribute(gvid_hout, (WORD)atr, len, c, &wr); + + #elif defined(__UNIX__) + + _vclrscr(atr); + + gvid_printf("%s\x1B[2J", gvid_newattr(atr)); + + #endif + + vposset(0,0); +} + + +// ------------------------------------------------------------------ +// Saves the current screen and returns pointer to buffer + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +static void _vsave(word* buf, int len1, int srow, int scol, int erow) { + + const int len2 = len1*sizeof(word); + gdma p = gdmaptr(scol, srow); + for(int nrow=srow; nrow<=erow; nrow++) { + gdmacpy(_my_ds(), (gdma)buf, _dos_ds, (gdma)p, len2); + p += ATTRSIZE*gvid->numcols; + buf += len1; + } +} +#endif + + +// ------------------------------------------------------------------ +// Saves the current screen and returns pointer to buffer + +vatch* vsave(int __srow, int __scol, int __erow, int __ecol) { + + if(__srow == -1) __srow = 0; + if(__scol == -1) __scol = 0; + if(__erow == -1) __erow = gvid->numrows-1; + if(__ecol == -1) __ecol = gvid->numcols-1; + + vatch* sbuf = (vatch*)throw_xcalloc((((__erow-__srow+1)*(__ecol-__scol+1))+4), sizeof(vatch)); + + if(sbuf) { + + vatch* buf = sbuf; + + buf[0] = (vatch)__srow; + buf[1] = (vatch)__scol; + buf[2] = (vatch)__erow; + buf[3] = (vatch)__ecol; + + #if defined(__USE_NCURSES__) + + int srow = *buf++; + int scol = *buf++; + int erow = *buf++; + int ecol = *buf++; + + for(int row=srow; row<=erow; row++) + for(int col=scol; col<=ecol; col++) + *buf++ = mvinch(row, col); + + #elif defined(__MSDOS__) + + int srow = *buf++; + int scol = *buf++; + int erow = *buf++; + int ecol = *buf++; + + int len1 = ecol-scol+1; + + if(gvid->isdma()) { + _vsave(buf, len1, srow, scol, erow); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + byte* p = (byte*)buf; + for(byte row=(byte)srow; row<=erow; row++) { + for(byte col=(byte)scol; col<=ecol; col++) { + cpu.ah(2); + cpu.bh(0); + cpu.dh(row); + cpu.dl(col); + cpu.genint(0x10); + cpu.ah(8); + cpu.bh(0); + cpu.genint(0x10); + *p++ = cpu.al(); + *p++ = cpu.ah(); + } + } + } + + #elif defined(__OS2__) + + USHORT srow = *buf++; + USHORT scol = *buf++; + USHORT erow = *buf++; + USHORT ecol = *buf++; + + USHORT len1 = (USHORT)(ecol-scol+1); + + #if defined(__BORLANDC__) + PCHAR16 ptr = (PCHAR16)buf; + #else + PCH ptr = (PCH)buf; + #endif + + USHORT len2 = (USHORT)(len1*sizeof(word)); + for(USHORT nrow=srow; nrow<=erow; nrow++) { + VioReadCellStr(ptr, &len2, nrow, scol, 0); + ptr += len2; + } + + #elif defined(__WIN32__) + + COORD coord; + DWORD x; + SHORT srow = *buf++; + SHORT scol = *buf++; + SHORT erow = *buf++; + SHORT ecol = *buf++; + + coord.X = scol; + + SHORT len1 = (SHORT)(ecol-scol+1); + char* p = (char *) buf; + + for(SHORT nrow=srow; nrow<=erow; nrow++) { + coord.Y = nrow; + ReadConsoleOutputAttribute(gvid_hout, gvid->bufwrd, len1, coord, &x); + ReadConsoleOutputCharacter(gvid_hout, gvid->bufchr, len1, coord, &x); + + word* q = gvid->bufwrd; + char* c = gvid->bufchr; + + for(int i = 0; i < len1; i++) { + *p++ = *c++; + *p++ = (byte) *q++; + } + } + + #elif defined(__UNIX__) + + int srow = *buf++; + int scol = *buf++; + int erow = *buf++; + int ecol = *buf++; + + int len1 = ecol-scol+1; + + _vsave(buf, len1, srow, scol, erow); + + #endif + } + + return sbuf; +} + + +// ------------------------------------------------------------------ +// Redraws a previously saved screen + +#if (defined(__MSDOS__) or defined(__UNIX__)) and not defined(__USE_NCURSES__) +static void _vredraw(word* buf, int len1, int srow, int scol, int erow) { + + const int len2 = len1*sizeof(word); + gdma p = gdmaptr(scol, srow); + for(int nrow=srow; nrow<=erow; nrow++) { + gdmacpy(_dos_ds, (gdma)p, _my_ds(), (gdma)buf, len2); + p += ATTRSIZE*gvid->numcols; + buf += len1; + } +} +#endif + + +// ------------------------------------------------------------------ +// Redraws a previously saved screen + +void vredraw(vatch* buf, int __srow, int __scol, int __erow, int __ecol) { + + if(__srow != -1) buf[0] = (vatch)__srow; + if(__scol != -1) buf[1] = (vatch)__scol; + if(__erow != -1) buf[2] = (vatch)__erow; + if(__ecol != -1) buf[3] = (vatch)__ecol; + + #if defined(__USE_NCURSES__) + + int srow = *buf++; + int scol = *buf++; + int erow = *buf++; + int ecol = *buf++; + + for(int row=srow; row<=erow; row++) + for(int col=scol; col<=ecol; col++) + mvaddch(row, col, *buf++); + + refresh(); + + #elif defined(__MSDOS__) + + int srow = *buf++; + int scol = *buf++; + int erow = *buf++; + int ecol = *buf++; + + int len1 = ecol-scol+1; + + if(gvid->isdma()) { + _vredraw(buf, len1, srow, scol, erow); + } + else if(gvid->isbios() or gvid->iscga()) { + i86 cpu; + byte* p = (byte*)buf; + for(byte row=(byte)srow; row<=erow; row++) { + for(byte col=(byte)scol; col<=ecol; col++) { + cpu.ah(2); + cpu.bh(0); + cpu.dh(row); + cpu.dl(col); + cpu.genint(0x10); + cpu.ah(9); + cpu.al(*p++); + cpu.bh(0); + cpu.bl(*p++); + cpu.cx(1); + cpu.genint(0x10); + } + } + } + + #elif defined(__OS2__) + + USHORT srow = *buf++; + USHORT scol = *buf++; + USHORT erow = *buf++; + USHORT ecol = *buf++; + + USHORT len1 = (USHORT)(ecol-scol+1); + USHORT len2 = (USHORT)(len1*sizeof(word)); + + #if defined(__BORLANDC__) + PCHAR16 ptr = (PCHAR16)buf; + #else + PCH ptr = (PCH)buf; + #endif + + for(USHORT nrow=srow; nrow<=erow; nrow++) { + VioWrtCellStr(ptr, len2, nrow, scol, 0); + ptr += len2; + } + + #elif defined(__WIN32__) + + SHORT srow = *buf++; + SHORT scol = *buf++; + SHORT erow = *buf++; + SHORT ecol = *buf++; + + SHORT len1 = (SHORT)(ecol-scol+1); + + for(SHORT nrow=srow; nrow<=erow; nrow++) { + vputws(nrow, scol, buf, len1); + buf += len1; + } + + #elif defined(__UNIX__) + + int srow = *buf++; + int scol = *buf++; + int erow = *buf++; + int ecol = *buf++; + + int len1 = ecol-scol+1; + + _vredraw(buf, len1, srow, scol, erow); + + int atr = *buf >> 8; + char* color = gvid_newattr(atr); + gvid_printf("%s", color); + + for(int nrow=srow; nrow<=erow; nrow++) { + vputansi(nrow, scol, buf, len1); + buf += len1; + } + + #endif +} + + +// ------------------------------------------------------------------ +// Restores a previously saved screen and frees buffer + +void vrestore(vatch* buf, int srow, int scol, int erow, int ecol) { + + vredraw(buf, srow, scol, erow, ecol); +} + + +// ------------------------------------------------------------------ +// Sets the cursor shape/size + +void vcurset(int sline, int eline) { + + if(eline) { + gvid->curr.cursor.start = sline; + gvid->curr.cursor.end = eline; + __vcurhidden = false; + } + + #if defined(__USE_NCURSES__) + + if((sline == 0) and (eline == 0)) + curs_set(0); + else if((eline - sline) <= 3) + curs_set(1); + else + curs_set(2); + + #elif defined(__MSDOS__) + + if(eline == 0) { + int _dvhide = __gdvdetected ? 0x01 : 0x30; + sline = ((gvid->adapter>=V_HGC) and (gvid->adapter<=V_INCOLOR)) ? 0x3F : _dvhide; + } + + i86 cpu; + cpu.ah(1); + cpu.ch((byte)sline); + cpu.cl((byte)eline); + cpu.genint(0x10); + + #elif defined(__OS2__) + + VIOCURSORINFO vioci; + VioGetCurType(&vioci, 0); + vioci.yStart = (USHORT)sline; + vioci.cEnd = (USHORT)eline; + vioci.attr = (USHORT)((eline == 0) ? 0xFFFF : gvid->curr.color.textattr); + VioSetCurType(&vioci, 0); + + #elif defined(__WIN32__) + + CONSOLE_CURSOR_INFO cci; + + if(eline) + vposset(gvid->currow, gvid->curcol); + + cci.dwSize = (eline and sline) ? sline : 100; + cci.bVisible = eline ? true : false; + + SetConsoleCursorInfo(gvid_hout, &cci); + + #elif defined(__UNIX__) + + gvid_printf("\033[?25%c", eline ? 'h' : 'l'); + + #endif +} + + +// ------------------------------------------------------------------ +// Hides the cursor + +void vcurhide() { + + if(not __vcurhidden) { + #if defined(__USE_NCURSES__) + curs_set(0); + #else + vcurset(0,0); + #endif + __vcurhidden = true; + } +} + + +// ------------------------------------------------------------------ +// Reveals the cursor + +void vcurshow() { + + if(__vcurhidden) { + #if defined(__USE_NCURSES__) + curs_set(gvid->curr.cursor.end ? 2 : 1); + #else + vcurset(gvid->curr.cursor.start, gvid->curr.cursor.end); + #endif + __vcurhidden = false; + } +} + + +// ------------------------------------------------------------------ +// Sets a large cursor + +void vcurlarge() { + + #if defined(__USE_NCURSES__) + curs_set(2); + #else + vcurshow(); + + #if defined(__MSDOS__) + + switch(gvid->adapter) { + case V_CGA: + vcurset(1,7); + break; + case V_EGA: + if(gvid->numrows == 25) { + vcurset(1,7); + } + else { + word* p = (word*)0x0463; // video BIOS data area + outpw(*p,0x000A); // update cursor start register + outpw(*p,0x0A0B); // update cursor end register + } + break; + case V_VGA: + vcurset(1,7); + break; + default: // one of the monochrome cards + vcurset(1,12); + } + + #elif defined(__OS2__) + + vcurset(1, gvid->curr.screen.cheight-1); + + #elif defined(__WIN32__) + + vcurset(90, true); + + #endif + #endif +} + + +// ------------------------------------------------------------------ +// Sets a small cursor + +void vcursmall() { + + #if defined(__USE_NCURSES__) + curs_set(1); + #else + vcurshow(); + + #if defined(__MSDOS__) + + switch(gvid->adapter) { + case V_CGA: + vcurset(6,7); + break; + case V_EGA: + if(gvid->numrows == 25) { + vcurset(6,7); + } + else { + word* p = (word*)0x0463; // video BIOS data area + outpw(*p,0x060A); // update cursor start register + outpw(*p,0x000B); // update cursor end register + } + break; + case V_VGA: + vcurset(6,7); + break; + default: // one of the monochrome cards + vcurset(11,12); + } + + #elif defined(__OS2__) + + vcurset(gvid->curr.screen.cheight-2, gvid->curr.screen.cheight-1); + + #elif defined(__WIN32__) + + vcurset(13, true); + + #endif + #endif +} + + +// ------------------------------------------------------------------ +// Table of characters used to display boxes +// +// Access box table characters via: +// _box_table(boxtype, x) +// +// where: +// boxtype is the number of the box type you want to use (0 - 5) +// +// x will be one of the following: +// 0 - upper left corner +// 1 - upper horizontal line +// 2 - upper right corner +// 3 - left vertical line +// 4 - right vertical line +// 5 - lower left corner +// 6 - lower horizontal line +// 7 - lower right corner +// 8 - middle junction +// 9 - left vertical junction +// 10 - right vertical junction +// 11 - upper horizontal junction +// 12 - lower horizontal junction +// 13 - checkerboard +// 14 - solid block +// ------------------------------------------------------------------ + +#if not defined(__USE_NCURSES__) + +char* __box_table[] = { + + #if defined(__UNIX__) // This table will be actually patched at startup... + + ".-.||`-'+||-- #", // box type 0 Single border + ".-.||`-'+||-- #", // box type 1 Double border + ".-.||`-'+||-- #", // box type 2 Single top + ".-.||`-'+||-- #", // box type 3 Double top + " #", // box type 4 With empty border + ".-.||`-'+||-- #", // box type 5 No border at all + ".-.||`-'+||-- #", // box type 6 Blocky border + ".-.||`-'+||-- #", // box type 7 ASCII border + "lqkxxmqjntuwvaa", // box type 8 xterm single border + + #else + + "ÚÄ¿³³ÀÄÙÅôÂÁ°±", // box type 0 Single border + "ÉÍ»ººÈͼÎ̹ËÊ°±", // box type 1 Double border + "ÖÄ·ººÓĽ×ǶÒа±", // box type 2 Single top + "Õ͸³³Ô;ØƵÑÏ°±", // box type 3 Double top + " °±", // box type 4 With empty border + "ÚÄ¿³³ÀÄÙÅôÂÁ°±", // box type 5 No border at all + "ÜÜÜÝÞßßßÝÝÝÝÝ°±", // box type 6 Blocky border + ".-.||`-'+||--##", // box type 7 ASCII border + "lqkxxmqjntuwvaa", // box type 8 xterm single border + + #endif +}; +#else + +// ncurses ACS_nnn characters are usually computed at runtime, so +// we cannot use a static array + +chtype _box_table(int type, int c) { + + char asciiborder[] = ".-.||-'+||--##"; + + switch(type) { + case 4: + switch(c) { + case 13: + return ACS_BOARD; + case 14: + return ACS_BLOCK; + default: + return (chtype) ' '; + } + case 6: + switch(c) { + case 13: + return ACS_BOARD; + default: + return ACS_BLOCK; + } + case 7: + return (chtype) (asciiborder[c]); + default: + switch (c) { + case 0: + return ACS_ULCORNER; + case 1: + case 6: + return ACS_HLINE; + case 2: + return ACS_URCORNER; + case 3: + case 4: + return ACS_VLINE; + case 5: + return ACS_LLCORNER; + case 7: + return ACS_LRCORNER; + case 8: + return ACS_PLUS; + case 9: + return ACS_LTEE; + case 10: + return ACS_RTEE; + case 11: + return ACS_TTEE; + case 12: + return ACS_BTEE; + case 13: + return ACS_BOARD; + default: + return ACS_BLOCK; + } + } +} + +#endif + + +// ------------------------------------------------------------------ + +#if defined(__UNIX__) and not defined(__USE_NCURSES__) +void gvid_boxcvt(char* s) { + + while(*s) { + switch(*s) { + case 'Ú': *s = _box_table(8, 0); break; + case 'Ä': *s = _box_table(8, 1); break; + case '¿': *s = _box_table(8, 2); break; + case '³': *s = _box_table(8, 4); break; + case 'À': *s = _box_table(8, 5); break; + case 'Ù': *s = _box_table(8, 7); break; + case 'Å': *s = _box_table(8, 8); break; + case 'Ã': *s = _box_table(8, 9); break; + case '´': *s = _box_table(8, 10); break; + case 'Â': *s = _box_table(8, 11); break; + case 'Á': *s = _box_table(8, 12); break; + } + s++; + } +} +#endif + + +// ------------------------------------------------------------------ +// Draws a text box on the screen + +void vbox(int srow, int scol, int erow, int ecol, int box, int hiattr, int loattr) { + + if(loattr == -1) + loattr = hiattr; + else if(loattr == -2) + loattr = (int)((hiattr & 0x08) ? (hiattr & 0xF7) : (hiattr | 0x08)); + + #if defined(__UNIX__) + hiattr |= ACSET; + loattr |= ACSET; + #endif + + vputc(srow, scol, hiattr, _box_table(box, 0)); // Top left corner + vputx(srow, scol+1, hiattr, _box_table(box, 1), ecol-scol-1); // Top border + vputc(srow, ecol, loattr, _box_table(box, 2)); // Top right corner + vputy(srow+1, scol, hiattr, _box_table(box, 3), erow-srow-1); // Left border + vputy(srow+1, ecol, loattr, _box_table(box, 4), erow-srow-1); // Right border + vputc(erow, scol, hiattr, _box_table(box, 5)); // Bottom left corner + vputx(erow, scol+1, loattr, _box_table(box, 6), ecol-scol-1); // Bottom border + vputc(erow, ecol, loattr, _box_table(box, 7)); // Bottom right corner +} + + +// ------------------------------------------------------------------ +// Fills an area of screen with a character & attribute + +void vfill(int srow, int scol, int erow, int ecol, vchar chr, int atr) { + + int width = ecol-scol+1; + for(int crow=srow; crow<=erow; crow++) + vputx(crow, scol, atr, chr, width); +} + + +// ------------------------------------------------------------------ +// Gets the character part of a character-attribute group + +vchar vgchar (vatch chat) { + + #if defined(__USE_NCURSES__) + return chat & (A_CHARTEXT | A_ALTCHARSET); + #else + return chat & 0xff; + #endif +} + + +// ------------------------------------------------------------------ +// Gets the attribute part of a character-attribute group + +int vgattr (vatch chat) { + + #if defined(__USE_NCURSES__) + return gvid_dosattrcalc(chat); + #else + return (chat >> 8) & 0xff; + #endif +} + + +// ------------------------------------------------------------------ +// Sets the given character in a character-attribute group + +vatch vschar (vatch chat, vchar chr) { + + #if defined(__USE_NCURSES__) + return (chr&(A_CHARTEXT|A_ALTCHARSET))|(chat&~(A_CHARTEXT|A_ALTCHARSET)); + #else + return (chat & 0xff00) | chr; + #endif +} + + +// ------------------------------------------------------------------ +// Sets the given attribute in a character-attribute group + +vatch vsattr (vatch chat, int atr) { + + #if defined(__USE_NCURSES__) + return (chat & (A_CHARTEXT | A_ALTCHARSET)) | gvid_attrcalc(atr); + #else + return (chat & 0xff) | (atr << 8); + #endif +} + + +// ------------------------------------------------------------------ +// Compose character-attribute group from character and attribute + +vatch vcatch (vchar chr, int atr) { + + #if defined(__USE_NCURSES__) + return chr | gvid_attrcalc(atr); + #else + return (chr & 0xff) | ((atr << 8) & 0xff00) ; + #endif +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gvidinit.cpp b/goldlib/gall/gvidinit.cpp new file mode 100644 index 0000000..41e292d --- /dev/null +++ b/goldlib/gall/gvidinit.cpp @@ -0,0 +1,1023 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// Copyright (C) 2000 Jacobo Tarrio +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Device-independent video functions +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#if defined(__WATCOMC__) or defined(__DJGPP__) +#include +#endif +#include + +#if defined(__OS2__) +#define INCL_BASE +#include +#endif + +#if defined(__WIN32__) +#include +#endif + +#if not defined(__USE_NCURSES__) and defined(__UNIX__) +#include +#include +#include +#include +#endif + +#if defined(__DJGPP__) +#include +#include +#endif + + +// ------------------------------------------------------------------ +// Check if Borland C++ for OS/2 1.0 header has been fixed + +#if defined(__OS2__) and defined(__BORLANDC__) + #if __BORLANDC__ <= 0x400 + #ifndef BCOS2_BSESUB_FIXED + #error There is a bug in the BSESUB.H header. Please fix it. + // + // Add/change the following in BSESUB.H: + // + // #define BCOS2_BSESUB_FIXED + // APIRET16 APIENTRY16 VioGetState (PVOID16 pState, HVIO hvio); + // APIRET16 APIENTRY16 VioSetState (PVOID16 pState, HVIO hvio); + // + // Borland forgot this (was only PVOID) ^^ + // + #endif + #endif +#endif + + +// ------------------------------------------------------------------ +// Global video data + +#ifdef __WIN32__ +HANDLE gvid_hout; +#endif + +GVid *gvid; + +int __gdvdetected = false; + +#if defined(__USE_NCURSES__) + +// add statics here + +#elif defined(__UNIX__) + +int gvid_stdout = -1; +bool gvid_xterm = false; +const char* gvid_acs_enable; +const char* gvid_acs_disable; + +void _vputx(int row, int col, int atr, char chr, uint len); +void gvid_printf(const char* fmt, ...) __attribute__ ((format (printf, 1, 2))); + +#endif + + +// ------------------------------------------------------------------ +// Video Class constructor + +GVid::GVid() { + + #ifdef __DJGPP__ + dmaptr = dmadir = 0; + #else + dmaptr = dmadir = NULL; + #endif + bufchr = NULL; + bufwrd = NULL; + bufansi = NULL; + + init(); +} + + +// ------------------------------------------------------------------ +// Video Class destructor + +GVid::~GVid() { + + #if defined(__USE_NCURSES__) + + attrset(A_NORMAL); + if(not --curses_initialized) + endwin(); + + #elif defined(__UNIX__) + // "\033<" Enter ANSI mode + // "\033[?5l" Normal screen + // "\033[0m" Normal character attributes + + gvid_printf("\033<\033[?5l\033[0m"); + + #endif + #ifndef __DJGPP__ + if(dmaptr != dmadir) throw_xfree(dmaptr); + #endif + throw_xfree(bufwrd); + throw_xfree(bufchr); + throw_xfree(bufansi); +} + + +// ------------------------------------------------------------------ + +void GVid::init() { + + #if defined(__USE_NCURSES__) + if(not curses_initialized++) + initscr(); + noecho(); + nonl(); + intrflush(stdscr, FALSE); + #endif + + // Detect video adapter + detectadapter(); + + // Detect original video information + detectinfo(&orig); + memcpy(&curr, &orig, sizeof(GVidInfo)); + + #if defined(__MSDOS__) + device = GVID_DMA; + #elif defined(__OS2__) + device = GVID_OS2; + #elif defined(__WIN32__) + device = GVID_W32; + #endif + + #if defined(__USE_NCURSES__) + dmaptr = dmadir = NULL; + #elif defined(__WATCOMC__) and defined(__386__) + dmaptr = dmadir = (gdma)(videoseg << 4); + #elif defined(__DJGPP__) + dmaptr = dmadir = ScreenPrimary; + #elif defined(__OS2__) or defined(__WIN32__) + dmaptr = dmadir = NULL; + #elif defined(__UNIX__) + dmaptr = (gdma)throw_xcalloc((orig.screen.rows+1)*orig.screen.columns, sizeof(word)); + dmadir = NULL; + #else + dmaptr = dmadir = (gdma)MK_FP(videoseg, 0); + #endif + + bufchr = NULL; + bufwrd = NULL; + bufansi = NULL; + + resetcurr(); +} + +// ------------------------------------------------------------------ +// Video adapter detect + +int GVid::detectadapter() { + + // Initialize to a valid value + adapter = GV_NONE; + + #if defined(__USE_NCURSES__) + + start_color(); + + /* init colors */ + short mycolors[] = { COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, + COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE }; + for(int i = 1; i < 64 and i < COLOR_PAIRS; i++) + init_pair(i, mycolors[(~i)&0x07], mycolors[(i>>3)&0x07]); + + adapter = V_VGA; + + #elif defined(__MSDOS__) + + i86 cpu; + + // Get video mode + cpu.ah(V_GET_MODE); + cpu.genint(0x10); + int _got_mode = cpu.al(); + + // Check for PS/2 compatible video BIOS by calling the get + // video configuration function. If it exists, the video + // configuration code will be returned in BL. + + cpu.ax(0x1A00); + cpu.genint(0x10); + + if(cpu.al() == 0x1A) { + + switch(cpu.bl()) { + case 0x00: + adapter = GV_NONE; + break; + case 0x01: + adapter = V_MDA; + break; + case 0x02: + adapter = V_CGA; + break; + case 0x04: + adapter = V_EGA; + break; + case 0x05: + adapter = V_EGAMONO; + break; + case 0x07: + adapter = (_got_mode == 7) ? V_VGAMONO : V_VGA; + break; + case 0x08: + adapter = (_got_mode == 7) ? V_VGAMONO : V_VGA; + break; + case 0x0A: + case 0x0C: + adapter = V_MCGA; + break; + case 0x0B: + adapter = V_MCGAMONO; + break; + default: + adapter = V_VGA; // We hope it is VGA compatible! + } + } + else { + + // OK, we know that it's not a PS/2 BIOS, so check for an EGA. + // If an EGA is not present, BH will be unchanged on return. + + cpu.ah(0x12); + cpu.bl(0x10); + cpu.genint(0x10); + + if(cpu.bl() - 0x10) { + adapter = cpu.bh() ? V_EGAMONO : V_EGA; + } + else { + + // Now we know it's not an EGA. Get the BIOS equipment + // flag and test for CGA, MDA, or no video adapter. + + cpu.genint(0x11); + + switch(cpu.al() & 0x30) { + case 0x00: + adapter = (_got_mode == 7) ? V_VGAMONO : V_VGA; // EGA, VGA, or PGA + break; + case 0x10: + adapter = GV_NONE; // 40x25 color + break; + case 0x20: + adapter = V_CGA; // 80x25 color + break; + case 0x30: + adapter = V_MDA; // 80x25 monochrome + break; + } + } + } + + #ifndef __DJGPP__ + + // Set video segment + #if defined(__BORLANDC__) and defined(__DPMI32__) + videoseg = (word)((adapter & V_MONO) ? __SegB000 : __SegB800); + #else + videoseg = (word)((adapter & V_MONO) ? 0xB000 : 0xB800); + #endif + + // check for presence of DESQview by using the DOS Set + // System Date function and trying to set an invalid date + + cpu.ax(0x2B01); // DOS Set System Date + cpu.ch('D'); + cpu.cl('E'); + cpu.dh('S'); + cpu.dl('Q'); + cpu.genint(0x21); + + // if error, then DESQview not present + if(cpu.al() != 0xFF) { + + __gdvdetected = true; + + #if defined(__WATCOMC__) and defined(__386__) + memset(&RMI, 0, sizeof(RMI)); + RMI.EAX = 0x0000FE00; + RMI.ES = videoseg; + cpu.ax(0x0300); + cpu.bl(0x10); + cpu.bh(0); + cpu.cx(0); + cpu.es(FP_SEG(&RMI)); + cpu.edi(FP_OFF(&RMI)); + cpu.genint(0x31); + videoseg = RMI.ES; + #else + cpu.ah(0xFE); // DV get alternate video buffer + cpu.es(videoseg); + cpu.di(0x0000); + cpu.genint(0x10); + videoseg = cpu.es(); + #endif + } + + #endif // __DJGPP__ + + #elif defined(__OS2__) + + { + VIOCONFIGINFO vioconfiginfo; + memset(&vioconfiginfo, 0, sizeof(VIOCONFIGINFO)); + vioconfiginfo.cb = sizeof(VIOCONFIGINFO); + VioGetConfig(0, &vioconfiginfo, 0); + switch(vioconfiginfo.adapter) { + case DISPLAY_MONOCHROME: + adapter = V_MDA; + break; + case DISPLAY_CGA: + adapter = V_CGA; + break; + case DISPLAY_EGA: + adapter = V_EGA; + break; + case DISPLAY_VGA: + adapter = V_VGA; + break; + default: + adapter = V_VGA; // We hope it is VGA compatible! + } + if(vioconfiginfo.display == DISPLAY_MONOCHROME) + adapter |= V_MONO; + } + + #elif defined(__WIN32__) + + gvid_hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, + OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL); + + SetFileApisToOEM(); + + adapter = V_VGA; + + #elif defined(__UNIX__) + + const char* term = getenv("TERM"); + if(term and strneql(term, "xterm", 5)) { + gvid_xterm = true; + for(int n=0; n<8; n++) + __box_table[n] = __box_table[8]; + } + + gvid_acs_enable = gvid_xterm ? "\033)0\033(B\016" : "\033[11m"; + gvid_acs_disable = gvid_xterm ? "\033(B\033)B\017" : "\033[10m"; + + gvid_stdout = fileno(stdout); + + adapter = V_VGA; + + #endif + + return adapter; +} + + +// ------------------------------------------------------------------ +// Video info detect + +void GVid::detectinfo(GVidInfo* _info) { + + // Reset all original values + memset(_info, 0, sizeof(GVidInfo)); + + #if defined(__USE_NCURSES__) + + _info->screen.mode = 0; + _info->screen.rows = LINES; + _info->screen.columns = COLS; + getyx(stdscr, _info->cursor.row, _info->cursor.column); + _info->color.textattr = 7; + _info->cursor.start = 11; + _info->cursor.end = 12; + _info->cursor.attr = 7; + _info->color.intensity = 1; + _info->color.overscan = 0; + + #elif defined(__MSDOS__) + + i86 cpu; + + // Get video mode and number of columns + cpu.ah(V_GET_MODE); + cpu.genint(0x10); + _info->screen.mode = cpu.al(); + _info->screen.columns = cpu.ah(); + + // Get the number of screen rows + if(adapter >= V_EGA) { + cpu.ax(V_GET_FONT_INFO); + cpu.dx(0); + cpu.genint(0x10); + _info->screen.rows = cpu.dl() + ((adapter & V_EGA) ? 0 : 1); + if(_info->screen.rows == 24) // Normally nonsense + _info->screen.rows++; + //_info->screen.cheight = cpu.cx(); + _info->screen.cheight = 8; + _info->screen.cwidth = 8; + } + else { + _info->screen.rows = 25; + _info->screen.cheight = 8; + _info->screen.cwidth = 8; + } + + // Get character attribute under the cursor + cpu.ah(V_RD_CHAR_ATTR); + cpu.bh(0); + cpu.genint(0x10); + _info->color.textattr = cpu.ah(); + + // Get cursor position and form + cpu.ah(V_GET_CURSOR_POS); + cpu.bh(0); + cpu.genint(0x10); + _info->cursor.row = cpu.dh(); + _info->cursor.column = cpu.dl(); + _info->cursor.start = cpu.ch(); + _info->cursor.end = cpu.cl(); + _info->cursor.attr = (word)_info->color.textattr; + // Get overscan color + if(adapter & V_VGA) { + cpu.ax(0x1008); + cpu.bh(0xFF); + cpu.genint(0x10); + _info->color.overscan = cpu.bh(); + } + + // Get intensity state + { + // Check bit 5 at 0000:0465 + #if defined(__DJGPP__) + _info->color.intensity = (_farpeekb (_dos_ds, 0x465) & 0x20) ? 0 : 1; + #else + byte* _bptr = (byte*)0x0465; + _info->color.intensity = (*_bptr & 0x20) ? 0 : 1; + #endif + + } + + #elif defined(__OS2__) + + // Get video mode and number of rows and columns + { + VIOMODEINFO viomodeinfo; + memset(&viomodeinfo, 0, sizeof(VIOMODEINFO)); + viomodeinfo.cb = sizeof(VIOMODEINFO); + VioGetMode(&viomodeinfo, 0); + _info->screen.mode = viomodeinfo.fbType; + _info->screen.rows = viomodeinfo.row; + _info->screen.columns = viomodeinfo.col; + _info->screen.cheight = viomodeinfo.vres / viomodeinfo.row; + _info->screen.cwidth = viomodeinfo.hres / viomodeinfo.col; + } + + // Get cursor position and character attribute under the cursor + { + USHORT usRow, usColumn; + VioGetCurPos(&usRow, &usColumn, 0); + _info->cursor.row = usRow; + _info->cursor.column = usColumn; + BYTE chat[2]; + USHORT len = 2; + #if defined(__EMX__) + VioReadCellStr((PCH)chat, &len, usRow, usColumn, 0); + #else + VioReadCellStr((CHAR*)chat, &len, usRow, usColumn, 0); + #endif + _info->color.textattr = chat[1]; + } + + // Get cursor form + { + VIOCURSORINFO viocursorinfo; + memset(&viocursorinfo, 0, sizeof(VIOCURSORINFO)); + VioGetCurType(&viocursorinfo, 0); + _info->cursor.start = viocursorinfo.yStart; + _info->cursor.end = viocursorinfo.cEnd; + _info->cursor.attr = viocursorinfo.attr; + } + + // Get intensity state + { + VIOINTENSITY viointensity; + memset(&viointensity, 0, sizeof(VIOINTENSITY)); + viointensity.cb = sizeof(VIOINTENSITY); + viointensity.type = 0x0002; + VioGetState(&viointensity, 0); + _info->color.intensity = viointensity.fs ? 1 : 0; + } + + // Get overscan color + { + VIOOVERSCAN viooverscan; + memset(&viooverscan, 0, sizeof(VIOOVERSCAN)); + viooverscan.cb = sizeof(VIOOVERSCAN); + viooverscan.type = 0x0001; + VioGetState(&viooverscan, 0); + _info->color.overscan = (int)viooverscan.color; + } + + #elif defined(__WIN32__) + + // Get video mode and number of rows and columns + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(gvid_hout, &csbi); + + _info->screen.mode = 0; + _info->screen.rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + _info->screen.columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; + + // Get cursor position and character attribute under the cursor + _info->cursor.row = csbi.dwCursorPosition.Y - csbi.srWindow.Top; + _info->cursor.column = csbi.dwCursorPosition.X - csbi.srWindow.Left; + _info->color.textattr = csbi.wAttributes; + + // Get cursor form + CONSOLE_CURSOR_INFO cci; + GetConsoleCursorInfo(gvid_hout, &cci); + + _info->cursor.start = (int) 1; + _info->cursor.end = cci.bVisible ? (int) 15 : 0; + _info->cursor.attr = (word)(cci.bVisible ? 7 : 0); + + // Get intensity state + _info->color.intensity = 1; + + // Get overscan color + _info->color.overscan = 0; + + #elif defined(__UNIX__) + + int r = 0, c = 0; + + if(r <= 0) { + char *s = getenv("LINES"); + if(s) { + //printf("getenv(\"LINES\") = %s\n", s); + r = atoi(s); + } + } + + if(c <= 0) { + char *s = getenv("COLUMNS"); + if(s) { + //printf("getenv(\"COLUMNS\") = %s\n", s); + c = atoi(s); + } + } + + //printf("init1: c=%i, r=%i\n", c, r); + + #if defined(TIOCGSIZE) + if(r <= 0 or c <= 0) { + struct ttysize sz; + + do { + if((ioctl(1,TIOCGSIZE,&sz) == 0) or (ioctl(0, TIOCGSIZE, &sz) == 0) or (ioctl(2, TIOCGSIZE, &sz) == 0)) { + c = (int)sz.ts_cols; + r = (int)sz.ts_lines; + break; + } + } while(errno == EINTR); + } + //printf("init2: c=%i, r=%i\n", c, r); + #elif defined(TIOCGWINSZ) + if(r <= 0 or c <= 0) { + struct winsize wind_struct; + + do { + if((ioctl(1,TIOCGWINSZ,&wind_struct) == 0) or (ioctl(0, TIOCGWINSZ, &wind_struct) == 0) or (ioctl(2, TIOCGWINSZ, &wind_struct) == 0)) { + c = (int)wind_struct.ws_col; + r = (int)wind_struct.ws_row; + break; + } + } while(errno == EINTR); + } + //printf("init3: c=%i, r=%i\n", c, r); + #endif + + + if((r <= 0) or (r > 200)) + r = 24; + if((c <= 0) or (c > 250)) + c = 80; + + //printf("init4: c=%i, r=%i\n", c, r); + + //*dmadir = 0; + + _info->screen.mode = 0; + _info->screen.rows = r; + _info->screen.columns = c; + _info->cursor.row = 0; + _info->cursor.column = 0; + _info->color.textattr = 7; + _info->cursor.start = 11; + _info->cursor.end = 12; + _info->cursor.attr = 7; + _info->color.intensity = 1; + _info->color.overscan = 0; + + #endif + + getpalette(_info->color.palette); +} + + +// ------------------------------------------------------------------ +// Reset current video info + +void GVid::resetcurr() { + + currow = curr.cursor.row; + curcol = curr.cursor.column; + + numrows = curr.screen.rows; + numcols = curr.screen.columns; + + throw_xfree(bufchr); + throw_xfree(bufwrd); + throw_xfree(bufansi); + + bufchr = (vchar*)throw_xcalloc(sizeof(vchar), numcols+1); + bufwrd = (vatch*)throw_xcalloc(sizeof(vatch), numcols+1); + bufansi = (vchar*)throw_xcalloc(sizeof(vchar), (11*numcols)+1); + + setdevice(device); +} + + +// ------------------------------------------------------------------ +// Sets video output device + +void GVid::setdevice(int _device) { + + device = _device; +} + + +// ------------------------------------------------------------------ +// Sets video mode + +void GVid::setmode(int _mode) { + + if(_mode) { + #if defined(__MSDOS__) + + i86 cpu; + cpu.ah(0x00); + cpu.al((byte)_mode); + cpu.genint(0x10); + + #endif + } + + detectinfo(&curr); + resetcurr(); +} + + +// ------------------------------------------------------------------ +// Sets screen rows + +void GVid::setrows(int _rows) { + + int origrows = curr.screen.rows; + + #if defined(__USE_NCURSES__) + + NW(_rows); + + #elif defined(__MSDOS__) + i86 cpu; + + // Set video mode 3 (80xNN) + if(curr.screen.mode != 3) { + cpu.ax(0x0003); + cpu.genint(0x10); + } + + if(adapter >= V_EGA) { + if(_rows == 28 and adapter >= V_VGA) { // vga-only + cpu.ax(0x1202); + cpu.bl(0x30); + cpu.genint(0x10); + cpu.ax(0x1111); + cpu.bl(0); + cpu.genint(0x10); + } + else if(_rows >= 43) { + cpu.ax(0x1112); // Load 8x8 character set + cpu.bl(0x00); + cpu.genint(0x10); + cpu.ax(0x1200); // Select alternate print-screen routine + cpu.bl(0x20); + cpu.genint(0x10); + if(adapter & V_EGA) { + // Disable cursor size emulation + byte* _bptr = (byte*)0x0487; + *_bptr |= (byte)0x01; + // Set cursor size + cpu.ah(0x01); + cpu.al((byte)orig.screen.mode); + cpu.cx(0x0600); + cpu.genint(0x10); + } + } + else { + if(adapter & V_EGA) { + // Enable cursor size emulation + byte* _bptr = (byte*)0x0487; + *_bptr &= (byte)0xFE; + } + // Set cursor size + cpu.ah(0x01); + cpu.al((byte)orig.screen.mode); + cpu.cx(0x0607); + cpu.genint(0x10); + } + } + + #elif defined(__OS2__) + + VIOMODEINFO viomodeinfo; + memset(&viomodeinfo, 0, sizeof(VIOMODEINFO)); + viomodeinfo.cb = sizeof(VIOMODEINFO); + VioGetMode(&viomodeinfo, 0); + viomodeinfo.row = (USHORT)_rows; + VioSetMode(&viomodeinfo, 0); + + #elif defined(__WIN32__) or defined(__UNIX__) + + NW(_rows); + + #endif + + if(origrows < _rows) + vfill(origrows, 0, _rows, 80, ' ', 7); + + detectinfo(&curr); + resetcurr(); +} + + +// ------------------------------------------------------------------ +// Set the screen border (overscan) color + +void GVid::setoverscan(int _overscan) { + + #if defined(__USE_NCURSES__) + + NW (_overscan); + + #elif defined(__MSDOS__) + + i86 cpu; + cpu.ah(0x0B); + cpu.bh(0x00); + cpu.bl((byte)_overscan); + cpu.genint(0x10); + + #elif defined(__OS2__) + + VIOOVERSCAN viooverscan; + memset(&viooverscan, 0, sizeof(VIOOVERSCAN)); + viooverscan.cb = sizeof(VIOOVERSCAN); + viooverscan.type = 0x0001; + VioGetState(&viooverscan, 0); + viooverscan.color = (BYTE)_overscan; + VioSetState(&viooverscan, 0); + + #elif defined(__WIN32__) or defined(__UNIX__) + + NW(_overscan); + + #endif +} + + +// ------------------------------------------------------------------ +// Set intensity/blinking state + +void GVid::setintensity(int _intensity) { + + #if defined(__USE_NCURSES__) + + NW(_intensity); + + #elif defined(__MSDOS__) + + #ifdef __DJGPP__ + + if(_intensity) + intensevideo(); + else + blinkvideo(); + + #else + + if(adapter & V_CGA) { + word* _wptr = (word*)0x0463; + byte* _bptr = (byte*)0x0465; + uint port = *_wptr + 4; + uint reg = *_bptr; + if(_intensity) + reg &= 0xDF; + else + reg |= 0x20; + outp(port, reg); + } + else { + i86 cpu; + cpu.ax(0x1003); + cpu.bh(0x00); + cpu.bl((byte)(_intensity ? 0 : 1)); + cpu.genint(0x10); + } + + #endif // __DJGPP__ + + #elif defined(__OS2__) + + VIOINTENSITY viointensity; + memset(&viointensity, 0, sizeof(VIOINTENSITY)); + viointensity.cb = sizeof(VIOINTENSITY); + viointensity.fs = (USHORT)(_intensity ? 1 : 0); + viointensity.type = 0x0002; + VioSetState(&viointensity, 0); + + #elif defined(__WIN32__) or defined(__UNIX__) + + NW(_intensity); + + #endif +} + + +// ------------------------------------------------------------------ + +void GVid::getpalette(int* _palette) { + + #if defined(__USE_NCURSES__) + + NW(_palette); + + #elif defined(__MSDOS__) + + // Get palette state + if(adapter & V_VGA) { + i86 cpu; + for(byte n=0; n<16; n++) { + cpu.ax(0x1007); // GET INDIVIDUAL PALETTE REGISTER + cpu.bh(0xFF); + cpu.bl(n); + cpu.genint(0x10); + _palette[n] = cpu.bh(); + } + } + else { + // Set to standard palette colors + for(byte n=0; n<16; n++) + _palette[n] = n + ((n > 7) ? 48 : 0); + } + + #elif defined(__OS2__) + + // Get palette state + BYTE viopalstate[38]; + PVIOPALSTATE pviopalstate; + memset(viopalstate, 0, sizeof(viopalstate)); + pviopalstate = (PVIOPALSTATE)viopalstate; + pviopalstate->cb = sizeof(viopalstate); + pviopalstate->type = 0; + pviopalstate->iFirst = 0; + VioGetState(pviopalstate, 0); + for(byte n=0; n<16; n++) + _palette[n] = pviopalstate->acolor[n]; + + #elif defined(__WIN32__) or defined(__UNIX__) + + NW(_palette); + + #endif +} + + +// ------------------------------------------------------------------ + +void GVid::setpalette(int* _palette) { + + #if defined(__USE_NCURSES__) + + NW(_palette); + + #elif defined(__MSDOS__) + + if(adapter & (V_EGA|V_MCGA|V_VGA)) { + i86 cpu; + for(byte n=0; n<16; n++) { + if(_palette[n] != -1) { + cpu.ax(0x1000); + cpu.bl(n); + cpu.bh((byte)_palette[n]); + cpu.genint(0x10); + } + } + } + + #elif defined(__OS2__) + + BYTE viopalstate[38]; + PVIOPALSTATE pviopalstate; + memset(viopalstate, 0, sizeof(viopalstate)); + pviopalstate = (PVIOPALSTATE)viopalstate; + pviopalstate->cb = sizeof(viopalstate); + pviopalstate->type = 0; + pviopalstate->iFirst = 0; + VioGetState(pviopalstate, 0); + for(byte n=0; n<16; n++) + if(_palette[n] != -1) + pviopalstate->acolor[n] = (USHORT)_palette[n]; + VioSetState(pviopalstate, 0); + + #elif defined(__WIN32__) or defined(__UNIX__) + + NW(_palette); + + #endif +} + + +// ------------------------------------------------------------------ + +void GVid::restore_cursor() { + + vcurset(orig.cursor.start, orig.cursor.end); + vcurshow(); + vposset(orig.cursor.row-1, 0); +} + + +// ------------------------------------------------------------------ + +void GVid::resize_screen(int columns, int rows) { + + numcols = curr.screen.columns = columns; + numrows = curr.screen.rows = rows; + + bufchr = (vchar*)throw_xrealloc(bufchr, numcols); + bufwrd = (vatch*)throw_xrealloc(bufwrd, numcols*2); + bufansi = (vchar*)throw_xrealloc(bufansi, 1+(11*numcols)); + + #if defined(__UNIX__) and not defined(__USE_NCURSES__) + dmaptr = (gdma)throw_xrealloc(dmaptr, (rows+1)*columns*sizeof(word)); + #endif +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwildmat.cpp b/goldlib/gall/gwildmat.cpp new file mode 100644 index 0000000..a46349d --- /dev/null +++ b/goldlib/gall/gwildmat.cpp @@ -0,0 +1,196 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// A wildcard pattern matching function. Based on TIN source. +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +/* +** Do shell-style pattern matching for ?, \, [], and * characters. +** Might not be robust in face of malformed patterns; e.g., "foo[a-" +** could cause a segmentation violation. It is 8bit clean. +** +** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. +** Rich $alz is now . +** April, 1991: Replaced mutually-recursive calls with in-line code +** for the star character. +** +** Special thanks to Lars Mathiesen for the ABORT code. +** This can greatly speed up failing wildcard patterns. For example: +** pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-* +** text 1: -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1 +** text 2: -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1 +** Text 1 matches with 51 calls, while text 2 fails with 54 calls. Without +** the ABORT code, it takes 22310 calls to fail. Ugh. The following +** explanation is from Lars: +** The precondition that must be fulfilled is that DoMatch will consume +** at least one character in text. This is true if *p is neither '*' nor +** '\0'.) The last return has ABORT instead of FALSE to avoid quadratic +** behaviour in cases like pattern "*a*b*c*d" with text "abcxxxxx". With +** FALSE, each star-loop has to run to the end of the text; with ABORT +** only the last one does. +** +** Once the control of one instance of DoMatch enters the star-loop, that +** instance will return either TRUE or ABORT, and any calling instance +** will therefore return immediately after (without calling recursively +** again). In effect, only one star-loop is ever active. It would be +** possible to modify the code to maintain this context explicitly, +** eliminating all recursive calls at the cost of some complication and +** loss of clarity (and the ABORT stuff seems to be unclear enough by +** itself). I think it would be unwise to try to get this into a +** released version unless you have a good test data base to try it out +** on. +*/ + + +// ------------------------------------------------------------------ + +int gwildmatch::match_internal(const char* text, const char* pattern, bool ignorecase) { + + register int last; + register int matched; + register int reverse; + const char* p = pattern; + + for( ; *p; text++, p++) { + if(*text == NUL and *p != '*') + return -1; + switch (*p) { + case '?': + // Match anything + continue; + case '*': + while(*++p == '*') // Consecutive stars act just like one. + continue; + if(*p == NUL) // Trailing star matches everything + return true; + while(*text) { + if((matched = match_internal(text++, p, ignorecase)) != false) + return matched; + } + return -1; + case '[': + reverse = p[1] == '^' ? true : false; + if(reverse) // Inverted character class + p++; + matched = false; + if(p[1] == ']' or p[1] == '-') { + if(ignorecase) { + if(tolower(*++p) == tolower(*text)) + matched = true; + } + else { + if(*++p == *text) + matched = true; + } + } + for(last = *p; *++p and *p != ']'; last = *p) { + // This next line requires a good C compiler + if(ignorecase) { + if(*p == '-' and p[1] != ']' ? tolower(*text) <= tolower(*++p) and tolower(*text) >= tolower(last) : tolower(*text) == tolower(*p)) + matched = true; + } + else { + if(*p == '-' and p[1] != ']' ? *text <= *++p and *text >= last : *text == *p) + matched = true; + } + } + if(matched == reverse) + return false; + continue; + case '\\': + // Literal match with following character + p++; + // FALLTHROUGH + default: + if(ignorecase) { + if(tolower(*text) != tolower(*p)) + return false; + } + else { + if(*text != *p) + return false; + } + continue; + } + } + + return *text == NUL; +} + + +// ------------------------------------------------------------------ + +bool gwildmatch::match(const char* text, const char* pattern, bool ignorecase) { + + if(*pattern == '*' and pattern[1] == NUL) + return true; + return match_internal(text, pattern, ignorecase) == true; +} + + +// ------------------------------------------------------------------ +// 4DOS-style wildcard string match. + +bool strwild(const char* str, const char* wild) { + + while(*str) { + if(*wild == '*') { // Match all + if(wild[1] == NUL) + return true; + else { + char *buf = (char *)alloca(strlen(wild)); + strcpy(buf, wild+1); + char* ptr = strpbrk(buf, "*?"); + if(ptr) + *ptr = NUL; + ptr = (char*)striinc(buf, str); + if(ptr) { + str = ptr + strlen(buf); + wild += strlen(buf) + 1; + } + else + break; + } + } + else if(toupper(*str) == toupper(*wild) or *wild == '?') { + wild++; + str++; + } + else + break; + } + if((*str == NUL) and (*wild == NUL or (*wild == '*' and wild[1] == NUL))) + return true; + + return false; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gwildmat.h b/goldlib/gall/gwildmat.h new file mode 100644 index 0000000..ccadb9e --- /dev/null +++ b/goldlib/gall/gwildmat.h @@ -0,0 +1,77 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// A wildcard pattern matching function. Based on TIN source. +// ------------------------------------------------------------------ + + +#ifndef __GWILDMAT_H +#define __GWILDMAT_H + +#include + + +// ------------------------------------------------------------------ + +class gwildmatch { + +protected: + + int match_internal(const char* text, const char* pattern, bool ignorecase); + +public: + + bool match(const char* text, const char* pattern, bool ignorecase); + +}; + + +// ------------------------------------------------------------------ + +inline bool gwildmat(const char* text, const char* pattern, bool ignorecase=true) { + + class gwildmatch m; + return m.match(text, pattern, ignorecase); +} + + +// ------------------------------------------------------------------ + +inline bool gwildmati(const char* text, const char* pattern) { + + class gwildmatch m; + return m.match(text, pattern, true); +} + + +// ------------------------------------------------------------------ +// 4DOS-style wildcard pattern match + +bool strwild(const char* str, const char* wild); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinall.h b/goldlib/gall/gwinall.h new file mode 100644 index 0000000..5a5ce6d --- /dev/null +++ b/goldlib/gall/gwinall.h @@ -0,0 +1,443 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// Windowing functions. +// ------------------------------------------------------------------ + +#ifndef __gwinall_h +#define __gwinall_h + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// Error codes returned from windowing functions + +#define W_NOERROR 0 // no error +#define W_ESCPRESS 1 // Escape key was pressed +#define W_ALLOCERR 2 // memory allocation error +#define W_NOTFOUND 3 // record not found +#define W_NOACTIVE 4 // no active window +#define W_INVCOORD 5 // invalid coordinates +#define W_INVFORMT 6 // invalid format string +#define W_NOINPDEF 7 // no input fields defined +#define W_STRLONG 8 // string too long for window +#define W_INVBTYPE 9 // invalid box type +#define W_NOBORDER 10 // no window border +#define W_NOHIDDEN 11 // no hidden windows +#define W_NOTHIDD 12 // window is not hidden +#define W_NOSELECT 13 // no selectable menu items +#define W_NOITMDEF 14 // no menu items defined +#define W_NOMNUEND 15 // no end of menu specified +#define W_NOMNUDEF 16 // no menu defined +#define W_NOMNUBEG 17 // no begin of menu specified +#define W_NOFRMDEF 18 // no form defined +#define W_NOFRMBEG 19 // no begin of form specified +#define W_NOHLPDEF 20 // no help record defined +#define W_HLPSTKOV 21 // help stack overflow +#define W_HLPSTKUN 22 // help stack underflow +#define W_DOSERROR 23 // DOS error +#define W_NOMATCH 24 // no files matched input filespec +#define W_INVTAGID 25 // invalid tag identifier + + +// ------------------------------------------------------------------ +// Window border identifiers + +#define TP_BORD 0 // top border +#define BT_BORD 1 // bottom border +#define LT_BORD 2 // left border +#define RT_BORD 3 // right border + + +// ------------------------------------------------------------------ +// Direction codes + +#define D_DOWN 0 +#define D_UP 1 +#define D_LEFT 2 +#define D_RIGHT 3 +#define SDOWN D_DOWN // scroll down +#define SUP D_UP // scroll up + + +// ------------------------------------------------------------------ +// Scrollbar orientation + +const int W_HORZ = 1; +const int W_VERT = 2; + + +// ------------------------------------------------------------------ +// Menu item record definition + +struct _item_t { + _item_t* prev; // pointer to previous record + _item_t* next; // pointer to next record + void* child; // pointer to submenu's record + const char* str; // address of selection string + const char* desc; // text description of menu option + VfvCP select; // address of selection function + VfvCP before; // address of "before" function + VfvCP after; // address of "after" function + gkey hotkey; // hot key to select function + int tagid; // tag identifier + int help; // help category number + int wrow; // start of text - window row + int wcol; // start of text - window column + char schar; // quick selection character + int fmask; // special feature mask + int dwhdl; // description window handle + int dwrow; // description window row + int dwcol; // description window column + int dattr; // description attribute + int redisp; // redisplay flag +}; + + +// ------------------------------------------------------------------ +// Window menu record definition + +struct _menu_t { + _menu_t* prev; // pointer to prev menu structure + _menu_t* next; // pointer to next menu structure + _menu_t* parent; // pointer to parent menu + _item_t* item; // pointer to head menu item + _item_t* citem; // pointer to current menu item + VfvCP open; // address of post-opening function + int tagcurr; // tag ID of item selection bar on + int usecurr; // will menu use current window? + int srow; // starting row of menu window + int scol; // starting column of menu window + int erow; // ending row of menu window + int ecol; // ending column of menu window + int btype; // menu window border type + int battr; // menu window "hi" border attribute + int loattr; // menu window "lo" border attribute + int sbattr; // menu window scrollbar attribute + int wattr; // menu window attribute + int menutype; // menu type mask + int barwidth; // width of menu bar or zero + int textpos; // offset of text from start of bar + int textattr; // attribute of menu text + int scharattr; // attribute of selection character + int noselattr; // non-selectable text attribute + int barattr; // attribute of selection bar + const char* title; // menu title string or NULL if no title + int titlepos; // position of menu title (TLEFT,TCENTER,TRIGHT) + int titleattr; // attribute of menu title + int shadattr; // shadow attribute or -1 if no shadow + int items; // number of items in menu +}; + + +// ------------------------------------------------------------------ +// Window input field definition + +struct _field_t { + _field_t* prev; // pointer to previous field + _field_t* next; // pointer to next field + char* str; // address of receiving string + char* buf; // address of temp receive string + const char* format; // input field format string + IfcpCP validate; // address of validation function + VfvCP before; // address of "before" function + VfvCP after; // address of "after" function + int help; // help category number + int lenbuf; // length of buffer + int lenfld; // length of screen input field + int lenfmt; // length of format string + int wrow; // start of input - window row + int wcol; // start of input - window column + int mode; // 0=init, 1=update, 2=cond update + int decpos; // decimal position (numeric) + int redisp; // redisplay flag + char fconv; // field conversion character +}; + + +// ------------------------------------------------------------------ +// Window data entry form definition + +typedef gkey (*KfipCP)(int*); + +struct _form_t { + KfipCP getkey; // pointer to alternate get func + _form_t* prev; // pointer to previous form record + _form_t* next; // pointer to next form record + _field_t* field; // pointer to head field record + _field_t* cfield; // pointer to current field record + gkey* termkey; // addr of int for terminating key + const char* pformat; // format string pointer + char* pbuf; // buffer string pointer + int cwrow; // current window row + int cwcol; // current window column + int decimal; // decimal field flag + int insert; // insert mode flag + int fieldattr; // field attribute + int textattr; // text attribute +}; + + +// ------------------------------------------------------------------ +// Structure of window records + +struct _wrec_t { + _wrec_t* prev; // pointer to previous window record + _wrec_t* next; // pointer to next window record + _form_t* form; // pointer to head form record + vatch* wbuf; // address of window's buffer + vatch* wsbuf; // address of window shadow's buffer + const char* title; // address of window's title string + int whandle; // window's handle + int help; // help category number + int srow; // start row of window + int scol; // start column of window + int erow; // end row of window + int ecol; // end column of window + int btype; // window's box type + int wattr; // window's initial text attribute + int battr; // attribute of window's border + int loattr; // attribute of window's border + int sbattr; // attribute of window's scrollbar + int border; // has border? 0 = no, 1 = yes + int row; // window's current cursor row + int column; // window's current cursor column + int attr; // window's current text attribute + int tpos; // position of window's title + int tattr; // attribute of window's title + int wsattr; // attribute of window's shadow +}; + + +// ------------------------------------------------------------------ + +class _help_t; + + +// ------------------------------------------------------------------ +// Window information record + +class GWin { + +public: + + _wrec_t* active; // pointer to active window + _wrec_t* hidden; // pointer to head hidden window + _menu_t* menu; // pointer to head menu record + _menu_t* cmenu; // pointer to current menu record + _help_t* helptr; // pointer to help info record + int handle; // last handle given to a window + int help; // current help category + int werrno; // error num from last window func + int total; // total number of open windows + int mlevel; // system variable used in menus + int ilevel; // system variable used in menus + int esc; // check for Esc in input funcions? + int tabwidth; // window TTY output tab width + vchar fillch; // character to fill windows with + int style; // how to open the windows + +public: + + GWin(); + ~GWin(); + +}; + +extern GWin gwin; + + +// ------------------------------------------------------------------ +// Window open styles + +#define STYLE_NORMAL 0 +#define STYLE_EXPLODE 1 +#define STYLE_EXPLODENOISY 2 + + +// ------------------------------------------------------------------ +// Fmask definitions for wmenuitem() + +#define M_HASPD 1 // has pull-down menu attached +#define M_NOSEL 2 // is not selectable +#define M_CLOSE 4 // close menu after select func +#define M_CLALL 8 // close all menus when selected +#define M_CLOSB 16 // close menu before select func + + +// ------------------------------------------------------------------ +// Menutype definitions for wmenuend() + +#define M_HORZ 1 // horizontal menu +#define M_VERT 2 // vertical menu +#define M_OMNI 7 // omnidirectional menu +#define M_PD 8 // pull-down menu +#define M_NOQS 16 // disable quick selection +#define M_SAVE 32 // save last bar position + + +// ------------------------------------------------------------------ +// Special return codes from wmenuget() + +#define M_EXIT 32764 // exit menu +#define M_EXITALL 32765 // exit all menus +#define M_PREVPD 32766 // previous pull-down menu +#define M_NEXTPD 32767 // next pull-down menu + + +// ------------------------------------------------------------------ +// Window title position definitions for wtitle() + +#define TTOP 0 // Top border +#define TLEFT 1 // Left justified +#define TCENTER 2 // Centered +#define TRIGHT 3 // Right justified +#define TBOTTOM 4 // Bottom border + + +// ------------------------------------------------------------------ +// Values for the Proportional Bar + +#define PROP_PAGE 1 +#define PROP_BARGRAPH 2 + + +// ------------------------------------------------------------------ + +extern int wpickstr_tag; + + +// ------------------------------------------------------------------ +// Function prototypes + +int wactiv (int whandle); +int wactiv_ (int whandle); +int wborder (int btype); +int wbox (int wsrow, int wscol, int werow, int wecol, int btype, int attr); +int wcclear (int attr); +int wcenters (int wrow, int attr, const char* str); +int wchkbox (int wsrow, int wscol, int werow, int wecol); +int wchkcol (int wcol); +int wchkcoord (int wrow, int wcol); +int wchkrow (int wrow); +int wclose (); +int wcloseall (); +int wclreol (); +int wclreos (); +int wcopy (int nsrow, int nscol); +int wdelline (int wrow, int direc); +int wdrag (int direction); +int wdupc (char ch, int count); +int wfill (int wsrow, int wscol, int werow, int wecol, vchar ch, int attr); +_wrec_t* wfindrec (int whandle); +int wgotoxy (int wrow, int wcol); +int whandle (); +int whide (); +int whline (int wsrow, int wscol, int count, int btype, int attr); +int wmessage (const char* str, int border, int leftofs, int attr); +int wmove (int nsrow, int nscol); +int wopen (int srow, int scol, int erow, int ecol, int btype, int battr, int wattr, int sbattr=-1, int loattr=-1); +inline int wopen_ (int srow, int scol, int vlen, int hlen, int btype, int battr, int wattr, int sbattr=-1, int loattr=-1) { return wopen(srow, scol, srow+vlen-1, scol+hlen-1, btype, battr, wattr, sbattr, loattr); } +int wperror (const char* message); +char* wpickfile (int srow, int scol, int erow, int ecol, int btype, int bordattr, int winattr, int barattr, bool title, const char* filespec, char* selectedfile, VfvCP open, bool casesens=false); +int wpickstr (int srow, int scol, int erow, int ecol, int btype, int bordattr, int winattr, int barattr, char* strarr[], int initelem, VfvCP open); +int wprintc (int wrow, int wcol, int attr, vchar ch); +int wprintf (const char* format, ...) __attribute__ ((format (printf, 1, 2))); +int wprintaf (int attr, const char* format, ...) __attribute__ ((format (printf, 2, 3))); +int wprintfs (int wrow, int wcol, int attr, const char* format, ...) __attribute__ ((format (printf, 4, 5))); +int wprints (int wrow, int wcol, int attr, const char* str); +int wprintvs (int wrow, int wcol, int attr, const vchar* str); +int wprintns (int wrow, int wcol, int attr, const char* str, uint len, vchar fill=' ', int fill_attr=-1); +int wprintsf (int wrow, int wcol, int attr, const char* format, const char* str); +int wprintws (int wrow, int wcol, vatch* buf, uint len); +void wpropbar (int mode, int xx, int yy, long len, long barlen, int attr, long pos, long size); +int wputc (vchar ch); +int wputs (const char* str); +int wputx (int wrow, int wcol, int attr, vchar chr, uint len); +int wreadcur (int* wrow, int* wcol); +int wscroll (int count, int direc); +void wscrollbar (int orientation, uint total, uint maxpos, uint pos, int sadd=0); +int wscrollbox (int wsrow, int wscol, int werow, int wecol, int count, int direction); +int wshadoff (); +int wshadow (int attr); +int wsize (int nerow, int necol); +int wslide (int nsrow, int nscol); +void wtextattr (int attr); +int wtitle (const char* str, int tpos, int tattr); +int wunhide (int whandle); +int wunlink (int w); +int wvline (int wsrow, int wscol, int count, int btype, int attr); +int wwprints (int whandle, int wrow, int wcol, int attr, const char* str); +int wwprintstr (int whandle, int wrow, int wcol, int attr, const char* str); + +int wmenubeg (int srow, int scol, int erow, int ecol, int btype, int battr, int wattr, VfvCP open, int menutype=M_VERT); +inline int wmenubeg_ (int srow, int scol, int vlen, int hlen, int btype, int battr, int wattr, VfvCP open, int menutype=M_VERT) { return wmenubeg(srow, scol, srow+vlen-1, scol+hlen-1, btype, battr, wattr, open, menutype); } +int wmenubegc (); +int wmenuend (int taginit, int menutype, int barwidth, int textpos, int textattr, int scharattr, int noselattr, int barattr); +int wmenuget (); +int wmenuiba (VfvCP before, VfvCP after); +int wmenuidsab (int tagid); +int wmenuienab (int tagid); +_item_t* wmenuifind (int tagid); +int wmenuinext (int tagid); +int wmenuitem (int wrow, int wcol, const char* str, char schar, int tagid, int fmask, VfvCP select, gkey hotkey, int help); +int wmenuitxt (int whdl, int wrow, int wcol, int attr, const char* str); + + +// ------------------------------------------------------------------ +// Inline functions + +inline void wtextattr(int attr) { gwin.active->attr = attr; } + +inline int wclear () { return wcclear(gwin.active->wattr); } +inline void wfillch (vchar a) { gwin.fillch=a; } +inline vchar wgetc (int wrow, int wcol) { return vgetc(gwin.active->srow+wrow+gwin.active->border,gwin.active->scol+wcol+gwin.active->border); } +inline int wisactiv (int a) { return a == gwin.active->whandle; } +inline void wrestore (vatch* wbuf) { vrestore(wbuf); } +inline vatch* wsave (int srow, int scol, int erow, int ecol) { return vsave(srow, scol, erow, ecol); } +inline int wsetesc (int a) { int t=gwin.esc; gwin.esc=a; return t; } +inline void wsetstyle (int a) { gwin.style = a; } +inline int wstyle () { return gwin.style; } +inline void wtabwidth (int a) { gwin.tabwidth = (a==0) ? 1 : a; } + +inline _field_t* winpfcurr () { return gwin.active->form->cfield; } + +inline _menu_t* wmenumcurr () { return gwin.cmenu; } +inline _item_t* wmenuicurr () { return wmenumcurr()->citem; } + +inline int wmenutitshad(const char* title, int pos, int attr, int shadattr) { gwin.cmenu->title=title; gwin.cmenu->titlepos=pos; gwin.cmenu->titleattr=attr; gwin.cmenu->shadattr=shadattr; return W_NOERROR; } + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinbase.cpp b/goldlib/gall/gwinbase.cpp new file mode 100644 index 0000000..5a437e6 --- /dev/null +++ b/goldlib/gall/gwinbase.cpp @@ -0,0 +1,2097 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// Windowing kernel. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Local optimizations + +#define GOLD_INLINE inline +#define GOLD_WCHK + + +// ------------------------------------------------------------------ + +static GOLD_INLINE int _wchkrow(int wrow) { + + return ((wrow<0) or (wrow>((gwin.active->erow-gwin.active->border)-(gwin.active->srow+gwin.active->border)))) ? true : false; +} + +static GOLD_INLINE int _wchkcol(int wcol) { + + return ((wcol<0) or (wcol>((gwin.active->ecol-gwin.active->border)-(gwin.active->scol+gwin.active->border)))) ? true : false; +} + +static GOLD_INLINE int _wchkcoord(int wrow, int wcol) { + + return (_wchkrow(wrow) or _wchkcol(wcol)) ? true : false; +} + + +// ------------------------------------------------------------------ +// Checks validity of given window row coordinate + +int wchkrow(int wrow) { + + return _wchkrow(wrow); +} + + +// ------------------------------------------------------------------ +// Checks validity of given window column coordinate + +int wchkcol(int wcol) { + + return _wchkcol(wcol); +} + + +// ------------------------------------------------------------------ +// Checks validity of given window coordinates + +int wchkcoord(int wrow, int wcol) { + + return _wchkcoord(wrow, wcol); +} + + +// ------------------------------------------------------------------ +// Checks for valid window box coordinates + +int wchkbox(int wsrow, int wscol, int werow, int wecol) { + + return (_wchkcoord(wsrow,wscol) or _wchkcoord(werow,wecol) or (wsrow>werow) or (wscol>wecol)) ? true : false; +} + + +// ------------------------------------------------------------------ +// Sets window cursor coordinates + +int wgotoxy(int wrow, int wcol) { + + // check for valid cursor coordinates + #ifdef GOLD_WCHK + if(wchkcoord(wrow,wcol)) + return gwin.werrno=W_INVCOORD; + #endif + + // calculate effective cursor coordinates and update window record + int row = gwin.active->row = gwin.active->srow + wrow + gwin.active->border; + int col = gwin.active->column = gwin.active->scol + wcol + gwin.active->border; + + // set cursor location + vposset(row,col); + + // return with no error + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Opens a window and makes it active + +int wopen(int srow, int scol, int erow, int ecol, int btype, int battr, int wattr, int sbattr, int loattr) { + + // check for valid box type + if(btype<0 or btype>7) { + gwin.werrno=W_INVBTYPE; + return 0; + } + + // see if window is to have a border + int border = (btype==5) ? NO : YES; + + // check for valid coordinates + if(srow>(erow-border) or scol>(ecol-border)) { + gwin.werrno=W_INVCOORD; + return 0; + } + + // allocate memory for new record + _wrec_t* wrec = (_wrec_t*)throw_xmalloc(sizeof(_wrec_t)); + if(wrec==NULL) { + gwin.werrno=W_ALLOCERR; + return 0; + } + + // save affected area of screen + vatch* wbuf = vsave(srow,scol,erow,ecol); + if(wbuf==NULL) { + throw_xrelease(wrec); + gwin.werrno=W_ALLOCERR; + return 0; + } + + // add new record to linked list + if(gwin.active!=NULL) + gwin.active->next=wrec; + wrec->prev=gwin.active; + wrec->next=NULL; + gwin.active=wrec; + + //printf("wopen(%i,%i,%i,%i,%i,%i,%i,%i,%i)" NL, srow, scol, erow, ecol, btype, battr, wattr, sbattr, loattr); + //getxch(); + + // draw and fill text box on screen + switch(gwin.style) { + case STYLE_NORMAL: + if(border) + vbox(srow,scol,erow,ecol,btype,battr,loattr); + vfill(srow+border,scol+border,erow-border,ecol-border,gwin.fillch,wattr); + break; + } + + // increment window handle counter + gwin.handle++; + + // save window info in window record + gwin.active->wbuf = wbuf; + gwin.active->whandle = gwin.handle; + gwin.active->srow = srow; + gwin.active->scol = scol; + gwin.active->erow = erow; + gwin.active->ecol = ecol; + gwin.active->btype = btype; + gwin.active->wattr = wattr; + gwin.active->battr = battr; + gwin.active->loattr = loattr; + gwin.active->sbattr = sbattr; + gwin.active->border = border; + gwin.active->row = srow+border; + gwin.active->column = scol+border; + gwin.active->attr = wattr; + gwin.active->title = NULL; + gwin.active->tpos = 0; + gwin.active->help = 0; + gwin.active->form = NULL; + gwin.active->wsbuf = NULL; + + // increment total number of open windows + gwin.total++; + + // initialize cursor location to window row 0 column 0 + wgotoxy(0,0); + + // return normally + gwin.werrno=W_NOERROR; + return gwin.handle; +} + + +// ------------------------------------------------------------------ +// Closes a window + +int wclose() { + + // check for active window + if(!gwin.total or !gwin.active) + return(gwin.werrno=W_NOACTIVE); + + // if window has a shadow, close shadow first + if(gwin.active->wsbuf!=NULL) + wshadoff(); + + // restore contents of and free memory held by window + vrestore(gwin.active->wbuf); + throw_xrelease(gwin.active->wbuf); + + // decrement total number of open windows + gwin.total--; + + // free memory held by window's record and update linked list + _wrec_t *wrec = gwin.active->prev; + throw_xrelease(gwin.active); + gwin.active=wrec; + if(gwin.active!=NULL) + gwin.active->next=NULL; + + // update cursor location and help category + if(gwin.active!=NULL) { + vposset(gwin.active->row,gwin.active->column); + if(gwin.active->help) + gwin.help=gwin.active->help; + } + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Closes all open windows + +int wcloseall() { + + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + while(gwin.total) + if(wclose()) + return gwin.werrno; + + // close hidden windows too + _wrec_t* prev; + while(gwin.hidden!=NULL) { + prev = gwin.hidden->prev; + throw_xfree(gwin.hidden->wbuf); + throw_xfree(gwin.hidden); + gwin.hidden = prev; + } + + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Gives active window a shadow + +int wshadow(int attr) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // see if window already has a shadow + if(gwin.active->wsbuf!=NULL) + return gwin.werrno=W_NOERROR; + + // get window coordinates from the window's record + int srow = gwin.active->srow; + int scol = gwin.active->scol; + int erow = gwin.active->erow; + int ecol = gwin.active->ecol; + + // allocate buffer to hold shadow's contents + vatch* wsbuf = (vatch*)throw_xmalloc((((erow-srow)*sizeof(vatch))+ecol-scol+1)*sizeof(vatch)); + + if(wsbuf == NULL) + return gwin.werrno=W_ALLOCERR; + + // start at upper right corner of shadow and work down + int crow = srow+1; + int ccol = ecol+1; + vatch* q = wsbuf; + + // draw shadow to right of window + while(crow<=erow) { + + // read current screen characters/attributes and save in shadow's buffer + vatch tmp[2]; + *q = vgetw(crow, ccol); + tmp[0] = vsattr(*q, attr); + q++; + *q = vgetw(crow, ccol + 1); + tmp[1] = vsattr(*q, attr); + q++; + + // write characters back to screen using shadow's attribute + vputws(crow++, ccol, tmp, 2); + } + + // start at lower left corner of shadow and work right + crow = erow+1; + ccol = scol+2; + int stop = ecol+2; + int len = stop - ccol + 1; + vatch* wptr = (vatch*)gvid->bufwrd; + + // draw bottom shadow + while(ccol<=stop) { + + // read current screen character/attribute and save in shadow's buffer + //word chat = *q++ = vgetw(crow, ccol); + + // write character back to screen using shadow's attribute + //vputc(crow, ccol++, attr, (char)chat); + + // read attribs/chars and store in buffers + *q = vgetw(crow, ccol++); + *wptr++ = vsattr(*q, attr); + q++; + } + + // display complete buffer + vputws(crow, scol+2, gvid->bufwrd, len); + + // save info in window's record + gwin.active->wsbuf = wsbuf; + gwin.active->wsattr = attr; + + // reset cursor + vposset(gwin.active->row,gwin.active->column); + + // return with no error + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Removes shadow from active window + +int wshadoff() { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // if window doesn't have a shadow, ignore request + if(gwin.active->wsbuf==NULL) + return gwin.werrno=W_NOERROR; + + // get window coordinates from the window's record + int srow = gwin.active->srow; + int scol = gwin.active->scol; + int erow = gwin.active->erow; + int ecol = gwin.active->ecol; + + // start at upper right corner of shadow and work down + int crow = srow+1; + int ccol = ecol+1; + vatch* q = gwin.active->wsbuf; + + // delete shadow to right of window + while(crow<=erow) { + vputw(crow, ccol, *q++); + vputw(crow++, ccol+1, *q++); + } + + // start at lower left corner of shadow and work right + crow = erow+1; + ccol = scol+2; + int stop = ecol+2; + + // delete bottom shadow + while(ccol<=stop) + vputw(crow,ccol++,*q++); + + // free memory held by shadow + throw_xrelease(gwin.active->wsbuf); + + // update window's record + gwin.active->wsattr = 0xFF; + + // return with no error + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Scrolls the active window up or down + +int wscroll(int count, int direction) { + + // check for window border + int border = gwin.active->border; + + vscroll( + gwin.active->srow + border, + gwin.active->scol + border, + gwin.active->erow - border, + gwin.active->ecol - ((border or (gwin.active->sbattr != -1)) ? 1 : 0), + gwin.active->wattr, + direction == SUP ? count : -count + ); + + // return with no error + return gwin.werrno = W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Scrolls a region of the active window up or down + +int wscrollbox(int wsrow, int wscol, int werow, int wecol, int count, int direction) { + + // check for window border + int border = gwin.active->border; + + vscroll( + gwin.active->srow+wsrow+border, + gwin.active->scol+wscol+border, + gwin.active->srow+werow+border, + gwin.active->scol+wecol+border, + gwin.active->wattr, + direction == SUP ? count : -count + ); + + // return with no error + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Displays a character inside active window + +int wputc(char ch) { + + int cwcol; + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // get coordinates from window's record + int crow = gwin.active->row; + int ccol = gwin.active->column; + int scol = gwin.active->scol; + int border = gwin.active->border; + + // test the input character for control characters + switch(ch) { + case '\n': + crow++; + case '\r': + ccol=scol+border; + break; + case '\b': + if(ccol==(scol+border)) { + ccol=gwin.active->ecol-border; + crow--; + if(crow<(gwin.active->srow+border)) + crow++; + } + else { + ccol--; + } + break; + case '\t': + cwcol=ccol-border-scol; + ccol+=(tabstop(cwcol,gwin.tabwidth)-cwcol); + break; + default: + vputc(crow, ccol++, gwin.active->attr, ch); + } + + // see if wrap-around is needed + if(ccol > (gwin.active->ecol-border)) { + ccol = scol+border; + crow++; + } + + // see if scroll is needed + if(crow > (gwin.active->erow-border)) { + wscroll(1,SUP); + crow--; + } + + // update window's record + gwin.active->row=crow; + gwin.active->column=ccol; + + // reset cursor position + vposset(crow,ccol); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Reads current cursor location inside window + +int wreadcur(int* wrow, int* wcol) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // read effective cursor coordinates + int row,col; + vposget(&row,&col); + + // calculate window cursor coordinates + *wrow = row - gwin.active->srow - gwin.active->border; + *wcol = col - gwin.active->scol - gwin.active->border; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Display a character specified number of times + +int wdupc(char ch, int count) { + + // check for active window + if(!gwin.total) + return(gwin.werrno=W_NOACTIVE); + + // display ch for count times + while(count--) + wputc(ch); + + // return with gwin.werrno set by wputc() + return(gwin.werrno); +} + + +// ------------------------------------------------------------------ +// Clears the active window in specified attribute + +int wcclear(int attr) { + + register int border; + + // check for active window + + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for window border + + border=gwin.active->border; + + vfill( + gwin.active->srow+border, + gwin.active->scol+border, + gwin.active->erow-border, + gwin.active->ecol-border, + gwin.fillch, + attr + ); + + // home the cursor + + wgotoxy(0,0); + + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Clears from cursor postion to end of window's line + +int wclreol() { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // clear to end of window's line + vputx( + gwin.active->row, + gwin.active->column, + gwin.active->attr, + gwin.fillch, + gwin.active->ecol - gwin.active->border - gwin.active->column + 1 + ); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Clears from cursor postion to end of window + +int wclreos() { + + int wrow, werow, wr, wc; + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // save current window row and column + wreadcur(&wr, &wc); + + wrow = wr; + werow = gwin.active->erow - gwin.active->srow - gwin.active->border; + wclreol(); + wrow++; + + while(wrow <= werow) { + wgotoxy(wrow,0); + wclreol(); + wrow++; + } + + // restore window row and column + wgotoxy(wr,wc); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// This function will process an Escape sequence when encountered + +static const char* process_esc(const char* str) { + + int wrow,wcol; + + int attr = gwin.active->attr; + + const char *p = str; + for(; *p==ESC; p++) { + + switch(*(++p)) { + + case '+': // increase text attribute + wtextattr(++attr); + break; + + case '-': // decrease text attribute + wtextattr(--attr); + break; + + case 'A': // change attribute + wtextattr(*++p); + break; + + case 'F': // change foreground attribute + wtextattr((int)((*++p&7)|(attr&248))); + break; + + case 'B': // change background attribute + wtextattr((int)((*++p&112)|(attr&143))); + break; + + case 'I': // toggle intensity bit + wtextattr((int)((attr&8)?(attr&247):(attr|8))); + break; + + case 'L': // toggle blinking bit + wtextattr((int)((attr&128)?(attr&127):(attr|128))); + break; + + case 'X': // reverse attribute + wtextattr(revsattr(attr)); + break; + + case 'R': // set cursor row + wreadcur(&wrow,&wcol); + wgotoxy(*++p,wcol); + break; + + case 'C': // set cursor column + wreadcur(&wrow,&wcol); + wgotoxy(wrow,*++p); + break; + + case 'E': // erase + switch(*++p) { + case 'W': // erase window + wclear(); + break; + case 'S': // erase to end of window + wclreos(); + break; + case 'L': // erase to end of window's line + wclreol(); + break; + } + break; + + case 'D': // duplicate character + { + char ch = *++p; + wdupc(ch,*++p); + } + break; + + default: + p--; + } + } + + return --p; +} + + +// ------------------------------------------------------------------ +// Displays a string inside active window + +int wputs(const char* str) { + + int cwcol; + const char* q; + + // get effective coordinates from window's record + int* crow = &(gwin.active->row); + int* ccol = &(gwin.active->column); + int scol = gwin.active->scol; + int border = gwin.active->border; + + // do while not end of string + for(q=str; *q; q++) { + + // test the input character for control characters + switch(*q) { + case '\n': + (*crow)++; + case '\r': + *ccol=scol+border; + break; + case '\b': + if(*ccol==(scol+border)) { + *ccol=gwin.active->ecol-border; + (*crow)--; + if(*crow<(gwin.active->srow+border)) + (*crow)++; + } + else { + (*ccol)--; + } + break; + case '\t': + cwcol=(*ccol)-border-scol; + (*ccol)+=(tabstop(cwcol,gwin.tabwidth)-cwcol); + break; + case ESC: + q=process_esc(q); + break; + default: + vputc(*crow, (*ccol)++, gwin.active->attr, *q); + } + + // see if wrap-around is needed + if((*ccol) > (gwin.active->ecol-border)) { + *ccol=scol+border; + (*crow)++; + } + + // see if scroll is needed + if((*crow) > (gwin.active->erow-border)) { + wscroll(1,SUP); + (*crow)--; + } + } + + // reset cursor position + vposset(*crow,*ccol); + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ +// Displays a character inside active window + +int wprintc(int wrow, int wcol, int atr, vchar chr) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid coordinates + #ifdef GOLD_WCHK + if(wchkcoord(wrow,wcol)) + return gwin.werrno=W_INVCOORD; + #endif + + vputc(wrow+gwin.active->srow+gwin.active->border, wcol+gwin.active->scol+gwin.active->border, atr, chr); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Outputs a formatted string to active window + +int wprintf(const char* format, ...) { + + va_list argptr; + char buf[255]; + + // format string using specified parameters into buffer + va_start(argptr,format); // access argument list + int result = vsprintf(buf,format,argptr); // create string using argument list + va_end(argptr); // end access of argument list + + // display the created string + wputs(buf); + + return result; +} + + +// ------------------------------------------------------------------ +// Print a formatted string at a specific position and attribute + +int wprintfs(int wrow, int wcol, int attr, const char* format, ...) { + + va_list argptr; + char buf[256]; + + *buf = NUL; + va_start(argptr, format); + int result = vsprintf(buf, format, argptr); + va_end(argptr); + + wprints(wrow, wcol, attr, buf); + + return result; +} + + +// ------------------------------------------------------------------ +// Displays a string inside active window + +int wprints(int wrow, int wcol, int attr, const char* str) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid coordinates + #ifdef GOLD_WCHK + if(wchkcoord(wrow,wcol)) + return gwin.werrno=W_INVCOORD; + #endif + + vputs(gwin.active->srow+wrow+gwin.active->border,gwin.active->scol+wcol+gwin.active->border,attr,str); + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Displays a string inside active window + +int wprintvs(int wrow, int wcol, int attr, const vchar* str) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid coordinates + #ifdef GOLD_WCHK + if(wchkcoord(wrow,wcol)) + return gwin.werrno=W_INVCOORD; + #endif + + vputvs(gwin.active->srow+wrow+gwin.active->border,gwin.active->scol+wcol+gwin.active->border,attr,str); + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int wputx(int wrow, int wcol, int attr, vchar chr, uint len) { + + vputx(gwin.active->srow+wrow+gwin.active->border,gwin.active->scol+wcol+gwin.active->border,attr,chr,len); + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Displays a string inside active window + +int wprintns(int wrow, int wcol, int attr, const char* str, uint len, vchar fill, int fill_attr) { + + char* istr = throw_xstrdup(str); + char* ostr = istr; + char och = *ostr; + uint olen = strlen(istr); + if(len < olen) { + ostr += len; + och = *ostr; + *ostr = NUL; + } + int retval = wprints(wrow, wcol, attr, istr); + if(len < olen) + *ostr = och; + else if(len > olen) + retval = wputx(wrow, wcol+olen, fill_attr != -1 ? fill_attr : attr, fill, len-olen); + throw_xfree(istr); + return retval; +} + + +// ------------------------------------------------------------------ +// Displays attrib/char buffer inside active window + +int wprintws(int wrow, int wcol, vatch* buf, uint len) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid coordinates + #ifdef GOLD_WCHK + if(wchkcoord(wrow,wcol)) + return gwin.werrno=W_INVCOORD; + #endif + + // see if window has border + int border = gwin.active->border; + + // calculate effective coordinates + int row = gwin.active->srow+wrow+border; + int col = gwin.active->scol+wcol+border; + + // display buffer + vputws(row, col, buf, len); + + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Returns address of record of given window handle + +_wrec_t* wfindrec(int whandle) { + + _wrec_t *wrec; + + // scan through linked list for record belonging to requested handle + + wrec = gwin.active; + while(wrec) { + if(whandle==wrec->whandle) + break; + wrec=wrec->prev; + } + + if(wrec == NULL) { + + // Search through the hidden windows + + wrec = gwin.hidden; + while(wrec) { + if(whandle==wrec->whandle) + break; + wrec=wrec->prev; + } + } + + // return address of found record + return wrec; +} + + +// ------------------------------------------------------------------ +// Hides active window + +int whide() { + + vatch* p; + int shattr; + _wrec_t *temp; + + // check for active window + if(!gwin.total) + return(gwin.werrno=W_NOACTIVE); + + // save active window + p = vsave(gwin.active->srow,gwin.active->scol,gwin.active->erow,gwin.active->ecol); + + // check for/close window's shadow + if(gwin.active->wsbuf!=NULL) { + shattr = gwin.active->wsattr; + wshadoff(); + gwin.active->wsattr = shattr; + } + else { + gwin.active->wsattr = -1; + } + + // restore contents of active window's buffer + vrestore(gwin.active->wbuf); + throw_xfree(gwin.active->wbuf); + gwin.active->wbuf = p; + + // update visible window record linked list + temp = gwin.active; + gwin.active = gwin.active->prev; + if(gwin.active) + gwin.active->next = NULL; + gwin.total--; + + // update hidden window record linked list + if(gwin.hidden) + gwin.hidden->next = temp; + temp->prev = gwin.hidden; + temp->next = NULL; + gwin.hidden = temp; + + // update cursor location and help category + if(gwin.active) { + vposset(gwin.active->row,gwin.active->column); + if(gwin.active->help) + gwin.help = gwin.active->help; + } + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ +// Unhides a previously hidden window + +int wunhide(int whandle) { + + vatch* p; + _wrec_t* found; + + // check pointer to hidden window linked list ; must not be NULL + if(gwin.hidden==NULL) + return gwin.werrno=W_NOHIDDEN; + + // check to see if input window handle == 0. if so, then + // that means to unhide the most recently hidden window. + if(!whandle) + whandle=gwin.hidden->whandle; + + // scan through linked list for record belonging to requested handle + found=gwin.hidden; + while(found!=NULL) { + if(whandle==found->whandle) + break; + found=found->prev; + } + + // was handle found in hidden window record linked list? + if(found==NULL) { + + // see if handle is in visible window record linked list + if(wfindrec(whandle)==NULL) + return gwin.werrno=W_NOTFOUND; + else + return gwin.werrno=W_NOTHIDD; + } + + // save area of screen where window is to unhide at + if((p=vsave(found->srow,found->scol,found->erow,found->ecol))==NULL) + return gwin.werrno=W_ALLOCERR; + + // restore contents of hidden window back to screen + vrestore(found->wbuf); + throw_xfree(found->wbuf); + found->wbuf=p; + + // update hidden window record linked list + if(found->prev!=NULL) + found->prev->next=found->next; + if(found->next==NULL) + gwin.hidden=found->prev; + else + found->next->prev=found->prev; + + // update visible window record linked list + if(gwin.active!=NULL) + gwin.active->next=found; + found->prev=gwin.active; + found->next=NULL; + gwin.active=found; + gwin.total++; + + // if window had a shadow before hiding, give it one again + if(gwin.active->wsattr!=-1) + wshadow(gwin.active->wsattr); + + // update help category + if(gwin.active->help) + gwin.help=gwin.active->help; + + // reset cursor + vposset(gwin.active->row,gwin.active->column); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Unlinks and frees a window from memory, but does not manipulate +// the screen at all + +int wunlink(int w) { + + _wrec_t *found, *prev, *next; + + // check to see if input window handle == 0. if + // so, then that means to unlink the active window. + if(!w) + w=gwin.active->whandle; + + // find address of window record for given window handle + if((found=wfindrec(w))==NULL) + return gwin.werrno=W_NOTFOUND; + + // free memory held by shadow's buffer (if shadow exists) + if(found->wsbuf!=NULL) + throw_xrelease(found->wsbuf); + + // free memory held by window's buffer + throw_xrelease(found->wbuf); + + // decrement total number of open windows + gwin.total--; + + // re-link list pointers around window record to remove + prev=found->prev; + next=found->next; + if(prev!=NULL) + prev->next=next; + if(next!=NULL) + next->prev=prev; + + // free memory held by window record + throw_xfree(found); + + // see if active window has changed + if(next==NULL) { + if(prev!=NULL) { + gwin.active=prev; + if(gwin.active->help) + gwin.help=gwin.active->help; + } + } + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Local variables + +static _wrec_t *__curr, *__found; +static int __crow, __ccol; +static int __gattr; +static const char* __p; + + +// ------------------------------------------------------------------ +// This function dectects if given window is blocking the current +// window or its shadow at specified coordinates + +static GOLD_INLINE int window_blocking() { + + return (__crow>=__curr->srow and __crow<=__curr->erow and __ccol>=__curr->scol and __ccol<=__curr->ecol) ? YES : NO; +} + + +// ------------------------------------------------------------------ +// This function detects if a given window's bottom shadow is +// blocking the current window or its shadow at specified coordinates + +static GOLD_INLINE int bshadow_blocking() { + + if(__crow==(__curr->erow+1)) + if((__ccol>=(__curr->scol+2)) and (__ccol<=(__curr->ecol+2))) + return YES; + else + return NO; + + return NO; +} + + +// ------------------------------------------------------------------ +// This function detects if a given window's right shadow is blocking +// the current window or its shadow at specified coordinates + +static GOLD_INLINE int rshadow_blocking() { + + if(__ccol==(__curr->ecol+1) or __ccol==(__curr->ecol+2)) + if((__crow>=(__curr->srow+1)) and (__crow<=__curr->erow)) + return YES; + else + return NO; + + return NO; +} + + +// ------------------------------------------------------------------ + +static GOLD_INLINE vatch* calc_window(_wrec_t *wrec) { + + return wrec->wbuf+4+((__crow-wrec->srow)*(wrec->ecol-wrec->scol+1))+(__ccol-wrec->scol); +} + + +// ------------------------------------------------------------------ + +static GOLD_INLINE vatch* calc_bshadow(_wrec_t *wrec) { + + return wrec->wsbuf+((((__crow-wrec->srow-1)*2)+(__ccol-wrec->scol-2))); +} + + +// ------------------------------------------------------------------ + +static GOLD_INLINE vatch* calc_rshadow(_wrec_t *wrec) { + + return wrec->wsbuf+((((__crow-wrec->srow-1)*2)+(__ccol-wrec->ecol-1))); +} + + +// ------------------------------------------------------------------ +// This function will exchange the contents of the applicable buffers + +static void swap_contents(vatch* pfound, vatch* pcurr, int shadow) { + + register _wrec_t *wptr; + register vatch temp, chat; + + // display character from current position in window to + // activate on the screen. if character is part of a + // shadow, reflect the character on the screen. + + temp = vgetw(__crow, __ccol); + if(shadow&2) + *pcurr = vschar(*pcurr, vgchar(temp)); + chat = ((vgattr(temp) & 0x80) and shadow) ? vsattr(*pcurr, vgattr(*pcurr | 0x80)) : *pcurr; + vputw(__crow, __ccol, chat); + + // let window position directly above position + // to activate have the character that it holds + + *pcurr = *pfound; + + // if current character position to activate will + // activate over a shadow in another window + + if(shadow&1) { + + // resolve all shadows upwards + + wptr = __curr; + chat = vsattr(*pfound, __curr->wsattr); + + for(__curr=__curr->next;__curr!=NULL;__curr=__curr->next) { + + if(window_blocking()) { + *(calc_window(__curr)) = chat; + chat = temp; + break; + } + else { + if(bshadow_blocking()) + *(calc_bshadow(__curr)) = chat; + else { + if(rshadow_blocking()) + *(calc_rshadow(__curr)) = chat; + } + } + } + + temp = chat; + __curr = wptr; + } + + // let character position activated hold character + // that was on the screen in the same position + + *pfound = temp; +} + + +// ------------------------------------------------------------------ + +int wactiv(int whandle) { + + register int startcol, stopcol; + _wrec_t *prev, *next; + + // check for active window + + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // if window is already active, ignore request + + if(whandle==gwin.active->whandle) + return gwin.werrno=W_NOERROR; + + // find address of window's record + + __found=wfindrec(whandle); + if(__found==NULL) + return gwin.werrno=W_NOTFOUND; + + // check every character position in window to activate + + for(__crow=__found->srow;__crow<=__found->erow;__crow++) { + for(__ccol=__found->scol;__ccol<=__found->ecol;__ccol++) { + + // check all window records "above" window to activate + + for(__curr=__found->next;__curr!=NULL;__curr=__curr->next) { + + // see if current position in window to activate + // is blocked by same position in test window + + if(window_blocking()) { + + // calculate buffer addresses and swap contents + + swap_contents(calc_window(__found),calc_window(__curr),0); + break; + } + + // see if test window has a shadow + + if(__curr->wsbuf!=NULL) { + + // see if shadow to the right of test window is + // blocking the current position of window to activate + + if(rshadow_blocking()) { + swap_contents(calc_window(__found),calc_rshadow(__curr),1); + break; + } + + // see if shadow to the bottom of test window is + // blocking the current position of window to activate + + if(bshadow_blocking()) { + swap_contents(calc_window(__found),calc_bshadow(__curr),1); + break; + } + } + } + } + } + + // if window to activate has a shadow, then check + // every character position in the shadow to see + // if it is blocked by another window or window shadow + + if(__found->wsbuf!=NULL) { + + // search the right shadow of window to activiate + + startcol=__found->ecol+1; + stopcol=startcol+1; + for(__crow=__found->srow+1;__crow<=__found->erow;__crow++) { + for(__ccol=startcol;__ccol<=stopcol;__ccol++) { + + // check all window records "above" shadow to activate + + for(__curr=__found->next;__curr!=NULL;__curr=__curr->next) { + + // see if current position in shadow to activate + // is blocked by same position in current window + + if(window_blocking()) { + + // calculate buffer addresses and swap contents + + swap_contents(calc_rshadow(__found),calc_window(__curr),2); + break; + } + + // see if test window has a shadow + + if(__curr->wsbuf!=NULL) { + + // see if current position of window to activate is + // blocked by the right shadow of the test window + + if(rshadow_blocking()) { + swap_contents(calc_rshadow(__found),calc_rshadow(__curr),3); + break; + } + + // see if current position of window to activate is + // blocked by the bottom shadow of the test window + + if(bshadow_blocking()) { + swap_contents(calc_rshadow(__found),calc_bshadow(__curr),3); + break; + } + } + } + } + } + + // search bottom shadow + + startcol=__found->scol+2; + stopcol=__found->ecol+2; + __crow=__found->erow+1; + for(__ccol=startcol;__ccol<=stopcol;__ccol++) { + + // check all window records "above" shadow to activate + + for(__curr=__found->next;__curr!=NULL;__curr=__curr->next) { + + // see if current position in shadow to activate + // is blocked by same position in test window + + if(window_blocking()) { + + // calculate buffer addresses and swap contents + + swap_contents(calc_bshadow(__found),calc_window(__curr),2); + break; + } + + // see if test window has a shadow + + if(__curr->wsbuf!=NULL) { + if(rshadow_blocking()) { + swap_contents(calc_bshadow(__found),calc_rshadow(__curr),3); + break; + } + if(bshadow_blocking()) { + swap_contents(calc_bshadow(__found),calc_bshadow(__curr),3); + break; + } + } + } + } + } + + // re-link pointer to window record to be activated + + prev=__found->prev; + next=__found->next; + if(prev!=NULL) + prev->next=next; + next->prev=prev; + gwin.active->next=__found; + __found->prev=gwin.active; + __found->next=NULL; + gwin.active=__found; + + // update help category + + if(gwin.active->help) + gwin.help=gwin.active->help; + + // reset cursor position + + vposset(gwin.active->row,gwin.active->column); + + // return normally + + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Activates a window without overlap checking + +int wactiv_(int whandle) { + + // if window is already active, ignore request + if(gwin.active and (whandle == gwin.active->whandle)) + return gwin.werrno = W_NOERROR; + + // find address of window's record + __found = wfindrec(whandle); + if(__found == NULL) + return gwin.werrno = W_NOTFOUND; + + // re-link pointer to window record to be activated + _wrec_t* prev = __found->prev; + _wrec_t* next = __found->next; + if(prev) + prev->next = next; + next->prev = prev; + gwin.active->next = __found; + __found->prev = gwin.active; + __found->next = NULL; + gwin.active = __found; + + // update help category + if(gwin.active->help) + gwin.help = gwin.active->help; + + // reset cursor position + vposset(gwin.active->row,gwin.active->column); + + // return normally + return gwin.werrno = W_NOERROR; +} + + +// ------------------------------------------------------------------ +// this function will update buffers above window string will be displayed in + +static void update_buffers(vatch* pcurr, int shadow) { + + _wrec_t* tcurr; + int tgattr; + + // put current string character and attribute into found window's buffer + + *pcurr = vcatch(*__p, __gattr); + + // if window's shadow is what's blocking, check to see + // if it is the highest shadow. If it is, display the + // character in the shadow's attribute, otherwise search + // for other blocking windows + + if(shadow) { + if(__curr->next==NULL) { + vputc(__crow, __ccol, vgattr(*pcurr)&0x80 ? (__curr->wsattr|BLINK) : __curr->wsattr, (vchar)*pcurr); + } + else { + tcurr = __curr; + __curr = __curr->next; + tgattr = __gattr; + __gattr = __curr->wsattr; + if(window_blocking()) + update_buffers(calc_window(__curr), 0); + else { + if(bshadow_blocking()) + update_buffers(calc_bshadow(__curr), 1); + else { + if(rshadow_blocking()) + update_buffers(calc_rshadow(__curr), 1); + } + } + __gattr = tgattr; + __curr = tcurr; + } + } +} + + +// ------------------------------------------------------------------ + +int wwprints(int whandle, int wrow, int wcol, int attr, const char* str) { + + // check for existance of active window or hidden windows + if(!gwin.total and gwin.hidden==NULL) + return gwin.werrno=W_NOACTIVE; + + // find address of window's record + int hidden = NO; + _wrec_t* found = wfindrec(whandle); + if(found==NULL) { + found = gwin.hidden; + while(found) { + if(whandle==found->whandle) + break; + found = found->prev; + } + if(found==NULL) + return gwin.werrno=W_NOTFOUND; + hidden = YES; + } + + // see if window has a border + int border = found->border; + + // calculate effective coordinates + int ecol = found->ecol-border; + __crow = found->srow+wrow+border; + __ccol = found->scol+wcol+border; + __gattr = attr; + __p = str; + + // check for valid coordinates + if((__crow > (found->erow-border)) or (__ccol > ecol)) + return gwin.werrno=W_INVCOORD; + + // save current cursor position + int oldrow, oldcol; + if(gvid->isbios()) + vposget(&oldrow,&oldcol); + + // do while not end-of-string and not end-of-window + while(__ccol <= ecol and *__p) { + + // see if output window is hidden. if so, then there + // is no need to check for blocking windows/shadows + if(hidden) + *(calc_window(found)) = vcatch(*__p, attr); + else { + + // check all window records "above" window to activate + for(__curr=found->next; __curr!=NULL; __curr=__curr->next) { + + // see if current position in window to activate + // is blocked by same position in test window + if(window_blocking()) { + + // calculate buffer addresses and swap contents + update_buffers(calc_window(__curr), 0); + break; + } + + // see if test window has a shadow + if(__curr->wsbuf!=NULL) { + + // see if shadow to the right of test window is + // blocking the current position of window to activate + if(rshadow_blocking()) { + update_buffers(calc_rshadow(__curr), 1); + break; + } + + // see if shadow to the bottom of test window is + // blocking the current position of window to activate + if(bshadow_blocking()) { + update_buffers(calc_bshadow(__curr), 1); + break; + } + } + } + + // if current position is not blocked, + // then display char to screen + if(__curr==NULL) + vputc(__crow, __ccol, attr, *__p); + } + + // update pointer into string and current column + __ccol++; + __p++; + } + + // restore old cursor position + if(gvid->isbios()) + vposset(oldrow,oldcol); + + // return to caller + return gwin.werrno = *__p ? W_STRLONG : W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int wwprintstr(int whandle, int wrow, int wcol, int attr, const char* str) { + + // check for existance of active window or hidden windows + if(!gwin.total and gwin.hidden==NULL) + return gwin.werrno=W_NOACTIVE; + + // find address of window's record + _wrec_t* found = wfindrec(whandle); + if(found==NULL) { + found = gwin.hidden; + while(found) { + if(whandle==found->whandle) + break; + found = found->prev; + } + if(found==NULL) + return gwin.werrno=W_NOTFOUND; + } + + // display string + vputs(found->srow+wrow+found->border, found->scol+wcol+found->border, attr, str); + + // return to caller + return gwin.werrno = W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Changes the active window's border box type + +int wborder(int btype) { + + register int border; + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid box type + if(btype<0||btype>7) + return gwin.werrno=W_INVBTYPE; + + // see if window is to have a border + border = (btype==5) ? NO : YES; + + // redraw window's border + vbox( + gwin.active->srow, + gwin.active->scol, + gwin.active->erow, + gwin.active->ecol, + btype, + border ? gwin.active->battr : gwin.active->wattr, + border ? gwin.active->loattr : gwin.active->wattr + ); + + // update window's record + gwin.active->btype=btype; + gwin.active->border=border; + + // see if cursor position needs to be updated + if((gwin.active->row==gwin.active->srow) or + (gwin.active->row==gwin.active->erow) or + (gwin.active->column==gwin.active->scol) or + (gwin.active->column==gwin.active->ecol)) { + wgotoxy(0,0); + } + + // re-display title if one exists + if(gwin.active->title!=NULL) + wtitle(gwin.active->title,gwin.active->tpos,gwin.active->tattr); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Fills a region of active window w/specified char/attribute + +int wfill(int wsrow, int wscol, int werow, int wecol, vchar chr, int atr) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid coordinates + if(wchkbox(wsrow,wscol,werow,wecol)) + return gwin.werrno=W_INVCOORD; + + // check for window border + int border = gwin.active->border; + + // fill in specified region + vfill( + gwin.active->srow+wsrow+border, + gwin.active->scol+wscol+border, + gwin.active->srow+werow+border, + gwin.active->scol+wecol+border, + chr, + atr + ); + + // return with no error + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Returns the handle of the active window + +int whandle() { + + // test for active window + if(!gwin.total) { + gwin.werrno=W_NOACTIVE; + return 0; + } + + // return normally + gwin.werrno = W_NOERROR; + return gwin.active->whandle; +} + + +// ------------------------------------------------------------------ +// Displays text on window's top or bottom border + +int wmessage(const char* str, int border, int leftofs, int attr) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // make sure window has a border + if(!gwin.active->border) + return gwin.werrno=W_NOBORDER; + + int left = gwin.active->scol+1; + int right = gwin.active->ecol-1; + int width = right-left+1; + int len = strlen(str); + + // Center string + if(leftofs < 0) + leftofs = (len > (width-2)) ? left : (((width/2)+left)-(len/2)); + + // make sure string fits in window + if((gwin.active->scol+leftofs+len-1) > (gwin.active->ecol)) + return gwin.werrno=W_STRLONG; + + // display string + vputs(border ? gwin.active->erow : gwin.active->srow, gwin.active->scol+leftofs, attr, str); + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Proportion bar + +void wpropbar(int mode, int xx, int yy, long len, long barlen, int attr, long pos, long size) { + + // mode = PROP_PAGE or PROP_BARGRAPH. + // xx, yy = start position in window. + // len = length (in chars) of progress field. + // attr = color to use for progress field. + // pos = present position. + // size = total size of field. + + #if 0 // defined(__linux__) + const char _fld = ':'; + const char _bar = '#'; + const char _up = '^'; + const char _dwn = 'v'; + #else + const vchar _fld = ACS_BOARD; + const vchar _bar = ACS_BLOCK; + const vchar _up = '\x18'; + const vchar _dwn = '\x19'; + #endif + + int dir=0, x, y; + long first, width, length; + + if(len > 0) + dir = 1; // Vertical + else + len = -len; // Horizontal + + if(not barlen) + length = size-len; + else + length = size; + + if((size > len) or (mode!=PROP_PAGE)) { + if(not barlen) + barlen = (len*len)/size; + if(not barlen) + barlen = 1; + width = len-barlen; + first = (pos*width)/length; + } + else { + first = 0; + barlen = len; + } + + if(dir) { + if(mode==PROP_PAGE) { + if(pos > 0) + wprintc(yy,xx,revsattr(attr),_up); + else + wprintc(yy,xx,revsattr(attr),' '); + if(pos+len < size) + wprintc(yy+(int)len-1,xx,revsattr(attr),_dwn); + else + wprintc(yy+(int)len-1,xx,revsattr(attr),' '); + } + for(y=yy+(mode==PROP_PAGE); y<(yy+first); y++) { + wprintc(y,xx,attr|ACSET,mode==PROP_BARGRAPH?_bar:_fld); + } + for(; y<(yy+first+barlen); y++) { + wprintc(y,xx,attr|ACSET,_bar); + } + for(; y<(yy+len-(mode==PROP_PAGE)); y++) { + wprintc(y,xx,attr|ACSET,_fld); + } + } + else { + for(x=xx; x<(xx+first); x++) { + wprintc(yy,x,attr|ACSET,mode==PROP_BARGRAPH?_bar:_fld); + } + for(; x<(xx+first+barlen); x++) { + wprintc(yy,x,attr|ACSET,_bar); + } + for(; x<(xx+len); x++) { + wprintc(yy,x,attr|ACSET,_fld); + } + } +} + + +// ------------------------------------------------------------------ +// Gives active window a title + +int wtitle(const char* str, int tpos, int tattr) { + + // check for active window + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // redraw box if deleting or moving title + if(str==NULL or gwin.active->title!=NULL) { + if(gwin.active->border) { + vputx( + ((tpos&TBOTTOM) ? gwin.active->erow : gwin.active->srow), + gwin.active->scol+1, + gwin.active->battr|ACSET, + _box_table(gwin.active->btype, (tpos&TBOTTOM)?6:1), + gwin.active->ecol-gwin.active->scol-1 + ); + } + } + + // if not deleting the title, calculate position and display it + if(str) { + + int left = gwin.active->scol+1; + int right = gwin.active->ecol-1; + int width = right-left+1; + int len = strlen(str); + + // don't display title if window is borderless + if(gwin.active->border) { + + int start; + + switch(tpos&~TBOTTOM) { + case TLEFT: + //start = (len>(width-3)) ? left : (left+1); + start = left; + break; + case TCENTER: + start = (len>(width-2)) ? left : (((width/2)+left)-(len/2)); + break; + default: // default is TRIGHT + { + int offs = width-len; + if(offs>2) + offs--; + start = (len>width) ? left : (left+offs+1); + } + } + + // allocate space for window title string, and copy it there + char* p = (char*)throw_xmalloc(((width>len) ? width : len)+1); + if(p==NULL) + return gwin.werrno=W_ALLOCERR; + strcpy(p, str); + *(p+width) = NUL; + + // display title string + vputs((tpos&TBOTTOM)?gwin.active->erow:gwin.active->srow, start, tattr, p); + + // free allocated space + throw_xfree(p); + + } + } + + // update window's record + gwin.active->title=str; + gwin.active->tpos=tpos; + gwin.active->tattr=tattr; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +void wscrollbar(int orientation, uint total, uint maxpos, uint pos, int sadd) { + + #if 0 // defined(__linux__) + const char barchar = '|'; + const char thumbchar = '#'; + const char arrowupchar = '^'; + const char arrowdownchar = 'v'; + const char arrowleftchar = '<'; + const char arrowrightchar = '>'; + #else + const vchar barchar = _box_table(gwin.active->btype, 13); + const vchar thumbchar = ' '; // '\xDB'; + const vchar arrowupchar = '\x18'; + const vchar arrowdownchar = '\x19'; + const vchar arrowleftchar = '\x1B'; + const vchar arrowrightchar = '\x1A'; + #endif + + int attr = (gwin.active->sbattr == -1) ? gwin.active->battr : gwin.active->sbattr; + int thumbattr = revsattr(attr); + + int srow, scol; + uint visiblelen, barlen; + uint maxthumbpos, thumbpos, thumblen; + + if(maxpos == 0) + maxpos = 1; + + if(orientation == W_VERT) { + srow = gwin.active->srow + gwin.active->border + sadd; + scol = gwin.active->ecol; + visiblelen = (gwin.active->erow - (gwin.active->srow+sadd)) + 1 - (gwin.active->border?2:0); + } + else { + srow = gwin.active->erow; + scol = gwin.active->scol + gwin.active->border + sadd; + visiblelen = (gwin.active->ecol - (gwin.active->scol+sadd)) + 1 - (gwin.active->border?2:0) - 2; + } + + barlen = visiblelen - 2; + thumblen = (visiblelen*barlen) / total; + if(thumblen == 0) + thumblen = 1; + else if(thumblen > barlen) + thumblen = barlen; + maxthumbpos = barlen - thumblen; + thumbpos = (pos*maxthumbpos) / maxpos; + uint thumbdiv = (pos*maxthumbpos) % maxpos; + if((thumbdiv >= (maxpos/2)) and (maxpos > 1)) + thumbpos++; + if(thumbpos > maxthumbpos) + thumbpos = maxthumbpos; + + if(orientation == W_VERT) { + register int row = srow; + register int erow1 = srow + thumbpos + 1; + register int erow2 = erow1 + thumblen; + register int erow3 = srow + barlen + 1; + vputc(row++, scol, revsattr(attr), arrowupchar); + while(row < erow1) + vputc(row++, scol, attr|ACSET, barchar); + while(row < erow2) + vputc(row++, scol, thumbattr|ACSET, thumbchar); + while(row < erow3) + vputc(row++, scol, attr|ACSET, barchar); + vputc(row, scol, revsattr(attr), arrowdownchar); + } + else { + register int col = scol; + register int ecol1 = scol + thumbpos + 1; + register int ecol2 = ecol1 + thumblen; + register int ecol3 = scol + barlen + 1; + vputc(srow, col++, revsattr(attr), arrowleftchar); + while(col < ecol1) + vputc(srow, col++, attr|ACSET, barchar); + while(col < ecol2) + vputc(srow, col++, thumbattr|ACSET, thumbchar); + while(col < ecol3) + vputc(srow, col++, attr|ACSET, barchar); + vputc(srow, col, revsattr(attr), arrowrightchar); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwindow.cpp b/goldlib/gall/gwindow.cpp new file mode 100644 index 0000000..ee00025 --- /dev/null +++ b/goldlib/gall/gwindow.cpp @@ -0,0 +1,91 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Windowing wrapper class. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +int gwindow::printf(const char* format, ...) { + + char buf[255]; + va_list argptr; + va_start(argptr,format); + int result = vsprintf(buf,format,argptr); + va_end(argptr); + puts(buf); + return result; +} + + +// ------------------------------------------------------------------ + +int gwindow::printf(int color, const char* format, ...) { + + char buf[255]; + va_list argptr; + va_start(argptr,format); + int result = vsprintf(buf,format,argptr); + va_end(argptr); + text_color(color); + puts(buf); + return result; +} + + +// ------------------------------------------------------------------ + +int gwindow::printf(int row, int col, const char* format, ...) { + + va_list argptr; + char buf[256]; + *buf = NUL; + va_start(argptr, format); + int result = vsprintf(buf, format, argptr); + va_end(argptr); + prints(row, col, window_color, buf); + return result; +} + + +// ------------------------------------------------------------------ + +int gwindow::printf(int row, int col, int color, const char* format, ...) { + + va_list argptr; + char buf[256]; + *buf = NUL; + va_start(argptr, format); + int result = vsprintf(buf, format, argptr); + va_end(argptr); + prints(row, col, color, buf); + return result; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwindow.h b/goldlib/gall/gwindow.h new file mode 100644 index 0000000..f0d63a3 --- /dev/null +++ b/goldlib/gall/gwindow.h @@ -0,0 +1,687 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Windowing class. +// ------------------------------------------------------------------ + +#ifndef __gwindow_h +#define __gwindow_h + + +// ------------------------------------------------------------------ + +#include +#include + +#undef getc +#undef putc + + +// ------------------------------------------------------------------ + +inline void wgetc(int wrow, int wcol, int* atr, vchar* chr) { + + vgetc(wrow+gwin.active->srow+gwin.active->border, wcol+gwin.active->scol+gwin.active->border, atr, chr); +} + + +// ------------------------------------------------------------------ + +struct gscrollbar_data { + long minpos; // Minimum range position + long maxpos; // Maximum range position + long pos; // Position of the thumb button + long page; // Size of the visible part +}; + + +// ------------------------------------------------------------------ + +class gwindow { + +protected: + + _wrec_t* wrec; + + int owner; + + int window_style; + + int window_color; + + int border_hi_color; + int border_lo_color; + + int scrollbar_color; + + int title_color; + int title_position; + + int message_color; + + int shadow_color; + +public: + + int start_row; + int start_column; + + int end_row; + int end_column; + + enum { + title_top = TTOP, + title_left = TLEFT, + title_center = TCENTER, + title_right = TRIGHT, + title_bottom = TBOTTOM, + border_top = TP_BORD, + border_bottom = BT_BORD, + border_left = LT_BORD, + border_right = RT_BORD, + scrollbar_horizontal = W_HORZ, + scrollbar_vertical = W_VERT, + direction_down = D_DOWN, + direction_up = D_UP, + direction_left = D_LEFT, + direction_right = D_RIGHT, + bordertype_single = BT_SINGLE, + bordertype_double = BT_DOUBLE, + bordertype_singletop = BT_SINGLETOP, + bordertype_doubletop = BT_DOUBLETOP, + bordertype_blanks = BT_BLANKS, + bordertype_none = BT_NONE, + bordertype_blocks = BT_BLOCKS, + bordertype_ascii = BT_ASCII, + bordertypes = 7 + }; + + gwindow(); + gwindow(int old_handle); + virtual ~gwindow(); + + void init(); + + int height() { return 1 + end_row - start_row; } + int width() { return 1 + end_column - start_column; } + + int border_type() { return window_style & bordertypes; } + bool has_border() { return border_type() != BT_NONE; } + + vchar boxchar_upper_left_corner() { return _box_table(border_type(), 0); } + vchar boxchar_upper_horizontal_line() { return _box_table(border_type(), 1); } + vchar boxchar_upper_right_corner() { return _box_table(border_type(), 2); } + vchar boxchar_left_vertical_line() { return _box_table(border_type(), 3); } + vchar boxchar_right_vertical_line() { return _box_table(border_type(), 4); } + vchar boxchar_lower_left_corner() { return _box_table(border_type(), 5); } + vchar boxchar_lower_horizontal_line() { return _box_table(border_type(), 6); } + vchar boxchar_lower_right_corner() { return _box_table(border_type(), 7); } + vchar boxchar_middle_junction() { return _box_table(border_type(), 8); } + vchar boxchar_left_vertical_junction() { return _box_table(border_type(), 9); } + vchar boxchar_right_vertical_junction() { return _box_table(border_type(), 10); } + vchar boxchar_upper_horizontal_junction() { return _box_table(border_type(), 11); } + vchar boxchar_lower_horizontal_junction() { return _box_table(border_type(), 12); } + + void set_window_at(int srow, int scol); + void set_window_size(int vlen, int hlen); + + void open(int srow, int scol, int erow, int ecol, int style, int bcolor, int wcolor, int sbcolor=-1, int locolor=-1); + void openxy(int srow, int scol, int vlen, int hlen, int style, int bcolor, int wcolor, int sbcolor=-1, int locolor=-1); + void open(); + void close(); + void unlink(); + + void hide(); + void unhide(); + + int active(); + void activate(); + void activate_quick(); + + int cursor_row(); + int cursor_column(); + + void text_color(int color); + + void move_cursor(int row, int column); + + void title(const char* title, int color=-1, int position=-1); + void no_title(); + + void message(const char* text, int border, int leftofs, int color=-1); + + void shadow(int color=-1); + void no_shadow(); + + void set_vscrollbar_range(int minpos, int maxpos, int visible, int total, int redraw); + void set_hscrollbar_range(int minpos, int maxpos, int visible, int total, int redraw); + + void set_vscrollbar_pos(int pos, int redraw); + void set_hscrollbar_pos(int pos, int redraw); + + void set_scrollbar_color(int color); + + void vscrollbar(uint total, uint maxpos, uint pos, int sadd=0); + void hscrollbar(uint total, uint maxpos, uint pos, int sadd=0); + + void scroll_down(int count=1); + void scroll_up(int count=1); + + void scroll_box_down(int scol, int srow, int ecol, int erow, int count=1); + void scroll_box_up(int scol, int srow, int ecol, int erow, int count=1); + + void getc(int row, int col, int* atr, vchar* chr); + + void putc(vchar ch); + void puts(const char* text); + void printc(int row, int col, int color, vchar ch); + void prints(int row, int col, int color, const char* text); + void printvs(int row, int col, int color, const vchar* text); + void prints(int row, int col, int color, const string& text); + void printns(int row, int col, int color, const char* text, int len, vchar fill=' ', int fill_color=-1); + + int printf(const char* format, ...) __attribute__ ((format (printf, 2, 3))); + int printf(int color, const char* format, ...) __attribute__ ((format (printf, 3, 4))); + int printf(int row, int col, const char* format, ...) __attribute__ ((format (printf, 4, 5))); + int printf(int row, int col, int color, const char* format, ...) __attribute__ ((format (printf, 5, 6))); + + void fill_char(vchar ch); + void fill(int wsrow, int wscol, int werow, int wecol, vchar ch, int color); + void vertical_line(int wsrow, int wscol, int count, int btype, int color); + void horizontal_line(int wsrow, int wscol, int count, int btype, int color); + void clear(int color=-1); + void clear_eol(); + void drag(int direction, int howmuch=1); + void slide(int row, int col); + void putx(int wrow, int wcol, int color, char chr, uint len); + void printws(int wrow, int wcol, vatch* buf, uint len); + void print_center(int row, int color, const char* text); +}; + + +// ------------------------------------------------------------------ + +inline void gwindow::init() { + + wrec = NULL; + start_row = start_column = 0; + end_row = gvid->curr.screen.rows - 1; + end_column = gvid->curr.screen.columns - 1; + window_style = 0; + window_color = BLACK|_LGREY; + border_hi_color = BLUE|_LGREY; + border_lo_color = -1; + scrollbar_color = -1; + title_color = BLUE|_LGREY; + title_position = title_center; + message_color = BLUE|_LGREY; + shadow_color = DGREY|_BLACK; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::set_window_at(int srow, int scol) { + + start_row = srow; + start_column = scol; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::set_window_size(int vlen, int hlen) { + + end_row = start_row + vlen - 1; + end_column = start_column + hlen - 1; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::open(int srow, int scol, int erow, int ecol, int style, int bcolor, int wcolor, int sbcolor, int locolor) { + + start_row = srow; + start_column = scol; + end_row = erow; + end_column = ecol; + window_color = wcolor; + window_style = style; + border_hi_color = bcolor; + border_lo_color = locolor; + scrollbar_color = sbcolor; + + wopen(srow, scol, erow, ecol, style, bcolor, wcolor, sbcolor, locolor); + wrec = gwin.active; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::openxy(int srow, int scol, int vlen, int hlen, int style, int bcolor, int wcolor, int sbcolor, int locolor) { + + open(srow, scol, srow+vlen-1, scol+hlen-1, style, bcolor, wcolor, sbcolor, locolor); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::open() { + + open(start_row, start_column, end_row, end_column, window_style, border_hi_color, window_color, scrollbar_color, border_lo_color); +} + + +// ------------------------------------------------------------------ + +inline int gwindow::active() { + + return wrec == gwin.active; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::activate_quick() { + + if(!active()) + wactiv_(wrec->whandle); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::close() { + + if(wrec) { + activate_quick(); + wclose(); + wrec = NULL; + } +} + + +// ------------------------------------------------------------------ + +inline void gwindow::unlink() { + + wunlink(wrec->whandle); + wrec = NULL; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::hide() { + + activate_quick(); + whide(); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::unhide() { + + wunhide(wrec->whandle); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::activate() { + + if(!active()) + wactiv(wrec->whandle); +} + + +// ------------------------------------------------------------------ + +inline int gwindow::cursor_row() { + + return wrec->row; +} + + +// ------------------------------------------------------------------ + +inline int gwindow::cursor_column() { + + return wrec->column; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::text_color(int color) { + + window_color = color; + activate_quick(); + wtextattr(color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::set_scrollbar_color(int color) { + + wrec->sbattr = color; + scrollbar_color = color; +} + + +// ------------------------------------------------------------------ + +inline void gwindow::move_cursor(int row, int column) { + + activate_quick(); + wgotoxy(row, column); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::title(const char* title, int color, int position) { + + if(color != -1) + title_color = color; + if(position != -1) + title_position = position; + activate_quick(); + wtitle(title, title_position, title_color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::no_title() { + + title(NULL); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::message(const char* text, int border, int leftofs, int color) { + + if(color != -1) + message_color = color; + activate_quick(); + wmessage(text, border, leftofs, message_color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::shadow(int color) { + + if(color != -1) + shadow_color = color; + activate_quick(); + wshadow(shadow_color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::no_shadow() { + + activate_quick(); + wshadoff(); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::vscrollbar(uint total, uint maxpos, uint pos, int sadd) { + + activate_quick(); + wscrollbar(scrollbar_vertical, total, maxpos, pos, sadd); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::hscrollbar(uint total, uint maxpos, uint pos, int sadd) { + + activate_quick(); + wscrollbar(scrollbar_horizontal, total, maxpos, pos, sadd); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::scroll_down(int count) { + + activate_quick(); + wscroll(count, direction_down); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::scroll_up(int count) { + + activate_quick(); + wscroll(count, direction_up); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::scroll_box_down(int scol, int srow, int ecol, int erow, int count) { + + activate_quick(); + wscrollbox(scol, srow, ecol, erow, count, direction_down); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::scroll_box_up(int scol, int srow, int ecol, int erow, int count) { + + activate_quick(); + wscrollbox(scol, srow, ecol, erow, count, direction_up); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::getc(int row, int col, int* atr, vchar* chr) { + + activate_quick(); + wgetc(row, col, atr, chr); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::putc(vchar ch) { + + activate_quick(); + wputc(ch); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::puts(const char* text) { + + activate_quick(); + wputs(text); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::printc(int row, int col, int color, vchar ch) { + + activate_quick(); + wprintc(row, col, color, ch); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::prints(int row, int col, int color, const char* text) { + + activate_quick(); + wprints(row, col, color == -1 ? window_color : color, text); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::printvs(int row, int col, int color, const vchar* text) { + + activate_quick(); + wprintvs(row, col, color == -1 ? window_color : color, text); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::prints(int row, int col, int color, const string& text) { + + prints(row, col, color, text.c_str()); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::printns(int row, int col, int color, const char* text, int len, vchar fill, int fill_color) { + + activate_quick(); + wprintns(row, col, color, text, len, fill, fill_color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::fill_char(vchar ch) { + + activate_quick(); + wfillch(ch); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::fill(int wsrow, int wscol, int werow, int wecol, vchar ch, int color) { + + activate_quick(); + wfill(wsrow, wscol, werow, wecol, ch, color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::vertical_line(int wsrow, int wscol, int count, int btype, int color) { + + activate_quick(); + wvline(wsrow, wscol, count, btype, color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::horizontal_line(int wsrow, int wscol, int count, int btype, int color) { + + activate_quick(); + whline(wsrow, wscol, count, btype, color); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::clear(int color) { + + activate_quick(); + wcclear(color == -1 ? window_color : color); +} + + +// ------------------------------------------------------------------ + +inline gwindow::gwindow() { + + init(); + owner = true; +} + + +// ------------------------------------------------------------------ + +inline gwindow::gwindow(int old_handle) { + + init(); + owner = false; + + wrec = wfindrec(old_handle); + + start_row = wrec->srow; + start_column = wrec->scol; + end_row = wrec->erow; + end_column = wrec->ecol; + window_color = wrec->wattr; + window_style = wrec->btype; + border_hi_color = wrec->battr; + border_lo_color = wrec->loattr; + scrollbar_color = wrec->sbattr; +} + + +// ------------------------------------------------------------------ + +inline gwindow::~gwindow() { + + if(owner) + close(); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::slide(int row, int col) { + + activate_quick(); + wslide(row, col); +} + + +// ------------------------------------------------------------------ + +inline void gwindow::print_center(int row, int color, const char* text) { + + activate_quick(); + wcenters(row, color, text); +} + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinhelp.h b/goldlib/gall/gwinhelp.h new file mode 100644 index 0000000..41be15b --- /dev/null +++ b/goldlib/gall/gwinhelp.h @@ -0,0 +1,102 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Help. +// ------------------------------------------------------------------ + +#ifndef __gwinhelp_h +#define __gwinhelp_h + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Window help information record + +class _help_t { + +public: + + int help[20]; // help stack + const char* file; // help file name + int helpptr; // help stack pointer + gkey key; // help hot key + int winattr; // help window attribute + int textattr; // help window text attribute + int selattr; // selection text attribute + int barattr; // selection bar attribute + int srow; // help window start row + int scol; // help window start column + int erow; // help window end row + int ecol; // help window end column + int btype; // help window box type + int title; // display "Help" title? + VfvCP open; // pointer to open function + gfile* fp; // help file + long offset; // help file offset +}; + + +// ------------------------------------------------------------------ +// Help index file record definition + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +typedef struct _hlpidx_t { + word help; + char category[30]; + long offset; +} Hlpr; + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +int whelpcat(int cat); +int whelpclr(); +int whelpdef(const char* file, gkey key, int winattr, int textattr, int selattr, int barattr, VfvCP open); +int whelpop(); +int whelpopc(); +int whelppcat(int cat); +int whelpush(); +int whelpushc(int cat); +int whelpwin(int srow, int scol, int erow, int ecol, int btype, int title); +void whelpcompile(const char* helpfile, long& offset); +inline int whelpundef() { return whelpdef(NULL,0,0,0,0,0,NULL); } + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinhlp1.cpp b/goldlib/gall/gwinhlp1.cpp new file mode 100644 index 0000000..6423118 --- /dev/null +++ b/goldlib/gall/gwinhlp1.cpp @@ -0,0 +1,768 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// ------------------------------------------------------------------ +// whelpdef() defines the help key, file, and window colors +// whelpwin() defines the help window boundaries +// whelpcat() sets the help category +// whelppcat() sets the help category, but pushes current one first +// whelpopc() pops the last saved help category into the void +// whelpclr() clears the help buffer +// whelpush() pushes the current help category onto the stack +// whelpushc() pushes the given help category onto the stack +// whelpop() pops last saved help category, sets current +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Constants + +#define MAXXREF 30 +#define BUFSIZE 80 +#define BASETAGID 200 + + +// ------------------------------------------------------------------ +// Global variables + +extern int gmnudropthrough; + + +// ------------------------------------------------------------------ +// Local variables + +bool whelpclosefile = false; +static char* catarray[MAXXREF]; +static int arraycnt = 0; +static char buf[BUFSIZE+1]; + +_help_t whelp = { + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, + NULL,-1,0,0,0,0,0,3,8,21,71,0,YES,NULL,NULL,0 +}; + + +// ------------------------------------------------------------------ +// Help index file record definition + +static Hlpr recd; + + +// ------------------------------------------------------------------ + +static void esc_esc() { + + setonkey(Key_Esc,NULL,0); + kbput(Key_Esc); + kbput(Key_Esc); +} + + +// ------------------------------------------------------------------ + +static void esc_pgdn() { + + setonkey(Key_Esc,NULL,0); + setonkey(Key_PgDn,NULL,0); + kbput(Key_Esc); + kbput(Key_PgDn); +} + + +// ------------------------------------------------------------------ + +static void esc_pgup() { + + setonkey(Key_Esc,NULL,0); + setonkey(Key_PgUp,NULL,0); + kbput(Key_Esc); + kbput(Key_PgUp); +} + + +// ------------------------------------------------------------------ + +static void not_found(const char* cat) { + + wtextattr(whelp.textattr); + wputs("\nHelp category not found: "); + wputs(cat); + wputs("\nPress a key to continue."); + waitkey(); +} + + +// ------------------------------------------------------------------ + +static int find_cat_name(const char* cat) { + + int found=NO; + + // Reset file pointer. + whelp.fp->fseekset(whelp.offset); + + // Check for "*I" marker. + whelp.fp->fgets(buf, BUFSIZE); + if(strnieql(buf,"*I",2)) { + + // Search index for help category entry. If found, + // then advance file pointer to specified position. + for(;;) { + whelp.fp->fread(&recd,sizeof(Hlpr)); + if(recd.offset==-1L) + break; + if(strieql(recd.category,cat)) { + whelp.fp->fseekset(whelp.offset + recd.offset); + found=YES; + break; + } + } + } + + // If help category was not found, display an error message. + if(not found) + not_found(cat); + + return found; +} + + +// ------------------------------------------------------------------ + +static int find_cat_number(int cat) { + + int found=NO; + + // Reset file pointer. + whelp.fp->fseekset(whelp.offset); + + // Check for "*I" marker. + whelp.fp->fgets(buf, BUFSIZE); + if(strnieql(buf,"*I",2)) { + + // Search index for help category entry. If found, + // then advance file pointer to specified position. + for(;;) { + whelp.fp->fread(&recd,sizeof(Hlpr)); + if(recd.offset==-1L) + break; + if(recd.help==cat) { + whelp.fp->fseekset(whelp.offset + recd.offset); + found=YES; + break; + } + } + } + + // If help category was not found, display an error message. + if(!found) { + sprintf(buf, "%u", cat); + not_found(buf); + } + + return found; +} + + +// ------------------------------------------------------------------ + +static int find_page(long startpos, int pageofs) { + + long lastpagepos, currpos; + int currpage = 0; + int lines = whelp.srow; + + lastpagepos = currpos = startpos; + whelp.fp->fseekset(startpos); + + while(currpage < pageofs) { + whelp.fp->fgets(buf, BUFSIZE); + if(not whelp.fp->okay()) { + whelp.fp->fseekset(lastpagepos); + break; + } + lines++; + currpos=whelp.fp->ftell(); + if(strnieql(buf, "*E", 2)) { + whelp.fp->fseekset(lastpagepos); + break; + } + if(strnieql(buf, "*P", 2)) { + lastpagepos=currpos; + currpage++; + lines = whelp.srow; + } + else if(lines == whelp.erow-1) { + lastpagepos=currpos; + currpage++; + lines = whelp.srow; + } + } + + return currpage; +} + + +// ------------------------------------------------------------------ + +static void disp_cat() { + + int newpage, page, wrow, wcol, end, menuopen, itemopen; + long startpos; + _menu_t *curr; + char* p; + char* q; + gkey i, kbch; + + // initialize variables + page = wrow = wcol = end = menuopen = itemopen = 0; + + // save current info + startpos = whelp.fp->ftell(); + curr = gwin.cmenu; + + // set text attribute + wtextattr(whelp.textattr); + + for(;;) { + + // read next line from help file into buffer + whelp.fp->fgets(buf,BUFSIZE); + strtrim(buf); + + // if end-of-file or "*E" was found, assume end-of-category + end = strnieql(buf,"*E",2) ? YES : NO; + + // if end-of-category or new-page specified + if((wrow > whelp.erow-1) or strnieql(buf,"*P",2) or end) { + + loop: //////////////////////////////// + + const char* _help = " Help "; + char _title[80]; + sprintf(_title, " %s ", recd.category); + wtitle(NULL, TTOP, whelp.winattr); + wtitle(_title, TLEFT, whelp.winattr); + wtitle(NULL, TCENTER|TBOTTOM, whelp.winattr); + wmessage(_help, TP_BORD, whelp.ecol-whelp.scol-strlen(_help), whelp.winattr); + + // update bottom border of window with PgUp/PgDn info + if(page and not end) p = " PgUp/PgDn "; + else if(not page and end) p = ""; + else if(page and end) p = " PgUp "; + else p = " PgDn "; + wmessage(p,BT_BORD,whelp.ecol-whelp.scol-strlen(p),whelp.winattr); + wmessage(" ESC ",BT_BORD,1,whelp.winattr); + + // if one or more cross reference menu items were specified + if(arraycnt) { + + // depending on whether there are previous + // or next pages, define the PgUp/PgDn keys + if(page) + setonkey(Key_PgUp,esc_pgup,0); + if(not end) + setonkey(Key_PgDn,esc_pgdn,0); + + // define the Esc key + setonkey(Key_Esc,esc_esc,0); + + // end the menu and process it + wmenuend(BASETAGID,M_OMNI|M_NOQS,0,0,whelp.selattr,whelp.selattr,0,whelp.barattr); + gmnudropthrough = YES; + kbch = i = (gkey)wmenuget(); + gmnudropthrough = NO; + + // free the keys that were defined + if(page) + setonkey(Key_PgUp,NULL,0); + if(not end) + setonkey(Key_PgDn,NULL,0); + setonkey(Key_Esc,NULL,0); + + // turn off the menuopen flag and restore menu info + menuopen=NO; + gwin.cmenu=curr; + + // if Esc, PgDn, or PgUp was not pressed + if(i != 0xFFFF) { + + // convert tagid to array subscript + i -= (gkey)BASETAGID; + + // try to find selected category, if found set + // file pointer to it, otherwise reset file + // pointer back to previous help category + if(find_cat_name(catarray[i])) + startpos=whelp.fp->ftell(); + else + whelp.fp->fseekset(startpos); + + // clear help window and set + // position to upper left corner + wclear(); + wrow=page=0; + + // free menu item strings + for(i=0;iattr, q); + wcol += strlen(q); + q = p + 2; + } + else { + *p = NUL; + itemopen ^= 1; + wprints(wrow, wcol, gwin.active->attr, q); + if(not itemopen) { + if((catarray[arraycnt]=(char*)throw_malloc(strlen(q)+1))!=NULL) { + strcpy(catarray[arraycnt],q); + if(not menuopen) { + wmenubegc(); + menuopen=YES; + } + wmenuitem( + wrow, + wcol, + catarray[arraycnt], + *catarray[arraycnt], + BASETAGID+arraycnt, + 0, + NULL, + 0, + 0 + ); + arraycnt++; + } + } + wcol += strlen(q); + q = p + 1; + } + } + } while(p); + + // display text line and increment current window row + wprints(wrow, wcol, gwin.active->attr, q); + wrow++; + wcol=0; + } +} + + +// ------------------------------------------------------------------ + +static void help_handler() { + + register int i; + int help,cat; + int found; + KBnd* savekb; + + // save help category + help=gwin.help; + + // temporarily un-define the onkey list to avoid collision + savekb=chgonkey(NULL); + + // hide cursor + int cursorwashidden = vcurhidden(); + vcurhide(); + + // hide mouse cursor + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + + // open help window + if(not wopen(whelp.srow, whelp.scol, whelp.erow, whelp.ecol, whelp.btype, whelp.winattr, whelp.winattr)) + return; + + // display window title if specified + if(whelp.title) + wtitle("[ Help ]",TCENTER,whelp.winattr); + + // see if an open function was given. If so, then call it + if(whelp.open) + (*whelp.open)(); + + // determine help category to use. If the current help category + // is empty, check the stack for a help category there + cat=help; + if(not cat) { + if(whelp.helpptr>-1) { + for(i=whelp.helpptr;i>=0;i--) { + if(whelp.help[i]) { + cat=whelp.help[i]; + break; + } + } + } + } + + // check for no defined help category + if(not cat) { + wtextattr(whelp.textattr); + wputs("\nNo help category defined.\nPress a key to continue."); + waitkey(); + } + else { + + if(not whelp.fp) { + whelpclosefile = true; + whelp.fp = new gfile; throw_new(whelp.fp); + whelp.fp->fopen(whelp.file,"rb"); + if(not whelp.fp->isopen()) { + wtextattr(whelp.textattr); + wputs("\nHelp file not found: "); + wputs(whelp.file); + wputs("\nPress a key to continue."); + waitkey(); + } + } + + if(whelp.fp->isopen()) { + + whelp.fp->fseekset(whelp.offset); + + // find help category in help file + found=find_cat_number(cat); + + // read and display help category text + if(found) + disp_cat(); + } + + if(whelpclosefile) { + whelp.fp->fclose(); + delete whelp.fp; + whelp.fp = NULL; + } + } + + // close help window + wclose(); + + // reset mouse info + #ifdef GOLD_MOUSE + if(gmou.FreeCursor()) + gmou.ShowCursor(); + #endif + + // reset cursor + if(not cursorwashidden) + vcurshow(); + + // clear any onkeys defined in "open" function and relink the onkey list + freonkey(); + chgonkey(savekb); + + // restore help category + gwin.help=help; +} + + +// ------------------------------------------------------------------ + +int whelpdef(const char* file, gkey key, int winattr, int textattr, int selattr, int barattr, VfvCP open) { + + // is help disengagement requested? If so, un-define the help key. + if(file==NULL) { + if(gwin.helptr==NULL) + return gwin.werrno=W_NOHLPDEF; + else { + gwin.helptr=NULL; + whelpclr(); + setonkey(whelp.key,NULL,0); + } + } + else { + + // attach help key to help handler + if(setonkey(key,help_handler,0)) + return gwin.werrno=W_ALLOCERR; + + // point global help info pointer to internal struct + gwin.helptr=&whelp; + } + + // add information to window help information record + whelp.file = file; + whelp.key = key; + whelp.winattr = winattr; + whelp.textattr = textattr; + whelp.selattr = selattr; + whelp.barattr = barattr; + whelp.open = open; + + // return with no error + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int whelpwin(int srow, int scol, int erow, int ecol, int btype, int title) { + + // make sure help has been defined + if(gwin.helptr==NULL) + return gwin.werrno=W_NOHLPDEF; + + // load given coordinates into local static structure + whelp.srow =srow; + whelp.scol =scol; + whelp.erow =erow; + whelp.ecol =ecol; + whelp.btype=btype; + whelp.title=title; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int whelpcat(int cat) { + + // make sure help record has been defined + if(gwin.helptr==NULL) + return gwin.werrno=W_NOHLPDEF; + + // determine if help is to be global or window + if(gwin.active) + gwin.active->help=cat; + gwin.help=cat; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int whelppcat(int cat) { + + // check for existance of help, and push + // current help category onto help stack + if(whelpush()) + return gwin.werrno; + + // set help category + return whelpcat(cat); +} + + +// ------------------------------------------------------------------ + +int whelpopc() { + + // make sure help has been defined + if(gwin.helptr==NULL) + return gwin.werrno=W_NOHLPDEF; + + // check for stack underflow + if(whelp.helpptr==-1) + return gwin.werrno=W_HLPSTKUN; + + // decrement stack pointer + whelp.helpptr--; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int whelpclr() { + + // make sure help has been defined + if(gwin.helptr==NULL) + return gwin.werrno=W_NOHLPDEF; + + // clear help category and reset help stack pointer + gwin.help=0; + whelp.helpptr=-1; + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int whelpush() { + + // make sure help has been defined + if(gwin.helptr==NULL) + return(gwin.werrno=W_NOHLPDEF); + + // push the current help category onto the help stack + return(whelpushc(gwin.help)); +} + + +// ------------------------------------------------------------------ + +int whelpushc(int cat) { + + // make sure help has been defined + if(gwin.helptr==NULL) + return(gwin.werrno=W_NOHLPDEF); + + // check for stack overflow + if(gwin.helptr->helpptr==19) + return(gwin.werrno=W_HLPSTKOV); + + // add help category to stack and increment stack pointer + gwin.helptr->help[++gwin.helptr->helpptr]=cat; + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int whelpop() { + + // make sure help has been defined + if(gwin.helptr==NULL) + return(gwin.werrno=W_NOHLPDEF); + + // check for stack underflow + if(gwin.helptr->helpptr==-1) + return(gwin.werrno=W_HLPSTKUN); + + // restore help category and decrement stack pointer + gwin.help=gwin.helptr->help[gwin.helptr->helpptr--]; + if(gwin.active) + gwin.active->help=gwin.help; + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinhlp2.cpp b/goldlib/gall/gwinhlp2.cpp new file mode 100644 index 0000000..b8d12b0 --- /dev/null +++ b/goldlib/gall/gwinhlp2.cpp @@ -0,0 +1,99 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Help file compiler. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +extern _help_t whelp; + + +// ------------------------------------------------------------------ + +void whelpcompile(const char* helpfile, long& offset) { + + gfile ifp(helpfile, "rb"); + if(ifp) { + + ifp.setvbuf(); + + int count = 0; + char buf[1024]; + while(ifp.fgets(buf, sizeof(buf))) { + if(strnieql(buf, "*B ", 3)) + count++; + } + ifp.rewind(); + + Hlpr* helpindex = (Hlpr*)throw_xcalloc(count+2, sizeof(Hlpr)); + + long relative_offset = 0; + + whelp.fp->fputs("*I\r\n"); + whelp.fp->fwrite(helpindex, count+1, sizeof(Hlpr)); + whelp.fp->fputs("\r\n\r\n"); + relative_offset += 4 + ((count+1)*sizeof(Hlpr)) + 4; + + int counter = 0; + bool comment = true; + while(ifp.fgets(buf, sizeof(buf))) { + if(strnieql(buf, "*B ", 3)) { + comment = false; + helpindex[counter].help = atow(buf+3); + char* ptr = strchr(buf, ','); + strbtrim(strcpy(helpindex[counter].category, ptr ? ptr+1 : "")); + helpindex[counter].offset = relative_offset + strlen(buf); + counter++; + } + if(not comment) { + whelp.fp->fputs(buf); + relative_offset += strlen(buf); + } + if(strnieql(buf, "*E", 2)) + comment = true; + } + helpindex[counter].offset = -1L; + + whelp.fp->fseekset(offset); + whelp.fp->fputs("*I\r\n"); + whelp.fp->fwrite(helpindex, count+1, sizeof(Hlpr)); + offset += relative_offset; + whelp.fp->fseekset(offset); + + throw_xfree(helpindex); + + ifp.fclose(); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwininit.cpp b/goldlib/gall/gwininit.cpp new file mode 100644 index 0000000..b108d82 --- /dev/null +++ b/goldlib/gall/gwininit.cpp @@ -0,0 +1,328 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// Windowing kernel. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +#define GOLD_INLINE inline +#define GOLD_WCHK + + +// ------------------------------------------------------------------ +// Global window data + +GWin gwin; + + +// ------------------------------------------------------------------ +// Window Class constructor + +GWin::GWin() { + + active = NULL; // pointer to active window + hidden = NULL; // pointer to last hidden window + menu = NULL; // pointer to head menu record + cmenu = NULL; // pointer to current menu record + helptr = NULL; // pointer to help info record + handle = 0; // last handle given to a window + help = 0; // pointer to current help category + werrno = W_NOERROR; // error num from last window func + total = 0; // total number of open windows + mlevel = 0; // system variable used in menus + ilevel = 0; // system variable used in menus + esc = true; // check for Esc in input funcions? + tabwidth = 8; // window TTY output tab width + fillch = ' '; // character to fill windows with + style = STYLE_NORMAL; // window opening style +} + + +// ------------------------------------------------------------------ +// Window Class destructor + +GWin::~GWin() { + + // No action defined yet +} + + +// ------------------------------------------------------------------ +// Displays a string in centered in active window + +int wcenters(int wrow, int attr, const char* str) { + + register int window_width, string_length; + int start_column, border; + + // check for active window + + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid row + + if(wchkcoord(wrow,0)) + return gwin.werrno=W_INVCOORD; + + // check for window border + + border=gwin.active->border; + + // calculate start column & window width + + start_column = gwin.active->scol+border; + window_width = (gwin.active->ecol-border)-start_column+1; + + // check length of input string + + string_length=strlen(str); + if(string_length>window_width) + return gwin.werrno=W_STRLONG; + + // display the string + + vputs( + gwin.active->srow+wrow+border, + ((window_width/2)+start_column)-(string_length/2), + attr, + str + ); + + // return normally + + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ +// Smoothly drag a window 1 position in given direction + +int wdrag(int direction) { + + int srow, scol, erow, ecol, fill_row, fill_col, i; + int nsrow, nscol, nerow, necol, shad_attr=-1; + int chars_per_line, lines_per_win; + int vert_movement, horz_movement; + vatch* win_image; + vatch* wp; + vatch* p; + register vatch* src; + register vatch* dest; + + // check for active window + if(!gwin.total) + return(gwin.werrno=W_NOACTIVE); + + // get window coordinates + srow = gwin.active->srow; + scol = gwin.active->scol; + erow = gwin.active->erow; + ecol = gwin.active->ecol; + + // calculate lines-per-window and characters-per-line + lines_per_win = erow - srow + 1; + chars_per_line = ecol - scol + 1; + + // determine facts about direction of move + vert_movement=horz_movement=0; + switch(direction) { + case D_DOWN: + vert_movement=1; + lines_per_win--; + break; + case D_UP: + vert_movement=-1; + lines_per_win--; + break; + case D_LEFT: + horz_movement=-1; + chars_per_line--; + break; + case D_RIGHT: + default: + horz_movement=1; + chars_per_line--; + } + + // calculate new window coordinates + nsrow = srow + vert_movement; + nscol = scol + horz_movement; + nerow = erow + vert_movement; + necol = ecol + horz_movement; + + // if window has shadow, close it before the move + if(gwin.active->wsbuf!=NULL) { + shad_attr = gwin.active->wsattr; + wshadoff(); + } + + // save the current window image + win_image = vsave(srow,scol,erow,ecol); + if(win_image==NULL) + return(gwin.werrno=W_ALLOCERR); + + // save the area where the window will relocate to + wp = vsave(nsrow,nscol,nerow,necol); + if(wp==NULL) { + throw_xfree(win_image); + return(gwin.werrno=W_ALLOCERR); + } + + // change coordinates in saved window's buffer + // and restore window to new coordinates + win_image[0] = (vatch)nsrow; + win_image[1] = (vatch)nscol; + win_image[2] = (vatch)nerow; + win_image[3] = (vatch)necol; + vrestore(win_image); + throw_xfree(win_image); + + // start buffer positions past coordinates + src = gwin.active->wbuf + 4; + dest = wp + 4; + + if(direction==D_DOWN) + src += chars_per_line; + if(direction==D_UP) + dest += chars_per_line; + + // do the transfer of buffer contents + for(i=0; i < lines_per_win; i++) { + + if(direction==D_LEFT) + dest++; + if(direction==D_RIGHT) + src++; + + // move 1 line + memmove(dest, src, chars_per_line*sizeof(vatch)); + src += chars_per_line; + dest += chars_per_line; + + if(direction==D_LEFT) + src++; + if(direction==D_RIGHT) + dest++; + } + + // erase the trail that was left-over + p = gwin.active->wbuf + 4; + if(vert_movement) { + if(direction==D_DOWN) + fill_row=srow; + else { + p += (lines_per_win * chars_per_line); + fill_row=erow; + } + vputx(fill_row, scol, vgattr(*p), vgchar(*p), ecol-scol+1); + } + else { + if(direction==D_RIGHT) + fill_col=scol; + else { + p += chars_per_line; + fill_col=ecol; + } + for(i=srow;i<=erow;i++,p+=chars_per_line+1) + vputc(i, fill_col, vgattr(*p), vgchar(*p)); + } + + // free old window buffer + throw_xfree(gwin.active->wbuf); + + // update window record + gwin.active->wbuf = wp; + gwin.active->row = gwin.active->row - gwin.active->srow + nsrow; + gwin.active->column = gwin.active->column - gwin.active->scol + nscol; + gwin.active->srow = nsrow; + gwin.active->scol = nscol; + gwin.active->erow = nerow; + gwin.active->ecol = necol; + + // if window has shadow, redraw it + if(shad_attr!=-1) + wshadow((int)shad_attr); + + // reset cursor position + vposset(gwin.active->row,gwin.active->column); + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ +// Slides active window to a new location + +int wslide(int nsrow, int nscol) { + + int shattr=-1, err=0; + + // check for active windows + if(!gwin.total) + return gwin.werrno=W_NOACTIVE; + + // check for valid coordinates + if(nsrow<0 or nscol<0) + return gwin.werrno=W_INVCOORD; + + // if window has shadow, close it before the move + if(gwin.active->wsbuf!=NULL) { + shattr = gwin.active->wsattr; + wshadoff(); + } + + // slide it on over + while(gwin.active->scol>nscol and !err) err = wdrag(D_LEFT); + while(gwin.active->scolsrow>nsrow and !err) err = wdrag(D_UP); + while(gwin.active->srow + + +// ------------------------------------------------------------------ + +#define HORZ 0 +#define VERT 1 + + +// ------------------------------------------------------------------ + +#define ULC _box_table(bt, 0) // upper left corner +#define UHL _box_table(bt, 1) // upper horizontal line +#define URC _box_table(bt, 2) // upper right corner +#define LVL _box_table(bt, 3) // left vertical line +#define RVL _box_table(bt, 4) // right vertical line +#define LLC _box_table(bt, 5) // lower left corner +#define LHL _box_table(bt, 6) // lower horizontal line +#define LRC _box_table(bt, 7) // lower right corner +#define MJ _box_table(bt, 8) // middle junction +#define LVJ _box_table(bt, 9) // left vertical junction +#define RVJ _box_table(bt, 10) // right vertical junction +#define UHJ _box_table(bt, 11) // upper horizontal junction +#define LHJ _box_table(bt, 12) // lower horizontal junction + + +// ------------------------------------------------------------------ + +static int disp_char(int wrow,int wcol,int attr,int btype,vchar ch,int direc) { + + attr |= ACSET; + + // see if next to a border, if so, connect to it + if(gwin.active->border) { + + // abbreviate pointer + const int bt = btype; + + // calculate effective row and column + int row = gwin.active->srow+gwin.active->border+wrow; + int col = gwin.active->scol+gwin.active->border+wcol; + + // see if this is a horizontal or vertical line + if(direc==HORZ) { + + // make sure that the box type characters match + if(LVL==_box_table(gwin.active->btype, 3)) { + + // check left border + if(col==(gwin.active->scol+1)) { + vputc(row,gwin.active->scol,attr,LVJ); + ch=UHL; + } + + // check right border + if(col==(gwin.active->ecol-1)) { + vputc(row,gwin.active->ecol,attr,RVJ); + ch=UHL; + } + } + } + else { + + // make sure that the box type characters match + if(UHL==_box_table(gwin.active->btype, 1)) { + + // check top border + if(row==(gwin.active->srow+1)) { + vputc(gwin.active->srow,col,attr,UHJ); + ch=LVL; + } + + // check bottom border + if(row==(gwin.active->erow-1)) { + vputc(gwin.active->erow,col,attr,LHJ); + ch=LVL; + } + } + } + } + + // display character + if(wprintc(wrow,wcol,attr,ch)) + return gwin.werrno; + + // return normally + return 0; +} + + +// ------------------------------------------------------------------ + +static inline int isupvert(int btype, vchar ch) { + + const int bt = btype; + return (ch==LVL or ch==UHJ or ch==ULC or ch==URC or ch==LVJ or ch==RVJ or ch==MJ) ? YES : NO; +} + + +// ------------------------------------------------------------------ + +static inline int isdownvert(int btype, vchar ch) { + + const int bt = btype; + return (ch==LVL or ch==LHJ or ch==LLC or ch==LRC or ch==LVJ or ch==RVJ or ch==MJ) ? YES : NO; +} + + +// ------------------------------------------------------------------ + +static inline int islefthorz(int btype, vchar ch) { + + const int bt = btype; + return (ch==UHL or ch==LVJ or ch==LLC or ch==ULC or ch==UHJ or ch==LHJ or ch==MJ) ? YES : NO; +} + + +// ------------------------------------------------------------------ + +static inline int isrighthorz(int btype, vchar ch) { + + const int bt = btype; + return (ch==UHL or ch==RVJ or ch==LRC or ch==URC or ch==UHJ or ch==LHJ or ch==MJ) ? YES : NO; +} + + +// ------------------------------------------------------------------ + +int whline(int wsrow, int wscol, int count, int btype, int attr) { + + register int bt; + int row,col,up,down; + vchar ch; + + row=wsrow; + col=wscol; + + // abbreviate pointer + bt = btype; + + if(count) { + + // see if a left junction or corner is needed + up = isupvert (btype,wgetc(row-1,col)); + down = isdownvert(btype,wgetc(row+1,col)); + if(up&&down) + ch=LVJ; + else if(up) + ch=LLC; + else if(down) + ch=ULC; + else + ch=UHL; + + // display leftmost character + if(disp_char(row,col,attr,btype,ch,HORZ)) + return gwin.werrno; + col++; + count--; + } + + // do while not last character + while(count>1) { + + // see if a middle junction is needed + up = isupvert (btype,wgetc(row-1,col)); + down = isdownvert(btype,wgetc(row+1,col)); + if(up&&down) + ch=MJ; + else if(up) + ch=LHJ; + else if(down) + ch=UHJ; + else + ch=UHL; + + // display middle character + if(disp_char(row,col,attr,btype,ch,HORZ)) + return gwin.werrno; + col++; + count--; + } + + if(count) { + + // see if a right junction or corner is needed + up = isupvert (btype,wgetc(row-1,col)); + down = isdownvert(btype,wgetc(row+1,col)); + if(up&&down) + ch=RVJ; + else if(up) + ch=LRC; + else if(down) + ch=URC; + else + ch=UHL; + + // display rightmost character + if(disp_char(row,col,attr,btype,ch,HORZ)) + return gwin.werrno; + } + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int wvline(int wsrow, int wscol, int count, int btype, int attr) { + + register int bt; + int row,col,left,right; + vchar ch; + + row=wsrow; + col=wscol; + + // abbreviate pointer + bt = btype; + + if(count) { + + // see if a top junction or corner is needed + left = islefthorz (btype,wgetc(row,col-1)); + right = isrighthorz(btype,wgetc(row,col+1)); + if(left&&right) + ch=UHJ; + else if(left) + ch=URC; + else if(right) + ch=ULC; + else + ch=LVL; + + // display uppermost character + if(disp_char(row,col,attr,btype,ch,VERT)) + return gwin.werrno; + row++; + count--; + } + + // do while not last character + while(count>1) { + left = islefthorz (btype,wgetc(row,col-1)); + right = isrighthorz(btype,wgetc(row,col+1)); + if(left&&right) + ch=MJ; + else if(left) + ch=RVJ; + else if(right) + ch=LVJ; + else + ch=LVL; + + // display middle character + if(disp_char(row,col,attr,btype,ch,VERT)) + return gwin.werrno; + row++; + count--; + } + + if(count) { + + // see if a bottom junction or corner is needed + left = islefthorz (btype,wgetc(row,col-1)); + right = isrighthorz(btype,wgetc(row,col+1)); + if(left&&right) + ch=LHJ; + else if(left) + ch=LRC; + else if(right) + ch=LLC; + else + ch=LVL; + + // display bottommost character + if(disp_char(row,col,attr,btype,ch,VERT)) + return gwin.werrno; + } + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinmenu.cpp b/goldlib/gall/gwinmenu.cpp new file mode 100644 index 0000000..1996ae1 --- /dev/null +++ b/goldlib/gall/gwinmenu.cpp @@ -0,0 +1,1418 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// ------------------------------------------------------------------ +// wmenubeg() starts a menu definition +// wmenuitem() defines a menu item +// wmenuend() ends a menu definition +// wmenuget() processes the defined menu +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +int _finaltagid; + +int gmnudropthrough = NO; + + +// ------------------------------------------------------------------ +// prototypes for local functions + +static _item_t* down_item(_item_t *curr); +static _item_t* left_item(_item_t *curr); +static _item_t* right_item(_item_t *curr); +static _item_t* up_item(_item_t *curr); + + +// ------------------------------------------------------------------ +// menu item movement definitions + +#define ITM_LT 0 +#define ITM_RT 1 +#define ITM_UP 2 +#define ITM_DN 3 +#define ITM_FR 4 +#define ITM_LS 5 + + +// ------------------------------------------------------------------ +// array of function pointers to some of the item movement functions + +static _item_t *(*mnu_funcs[4])(_item_t *) = { + left_item, + right_item, + up_item, + down_item +}; + +// ------------------------------------------------------------------ +// flag used for initial display of menu selections + +static int dispdesc=YES; + + +// ------------------------------------------------------------------ +// this function will calculate the width of the selection bar + +static int calc_bar_width(_menu_t *wmenu,_item_t *witem) +{ + register int width; + + width=strlen(witem->str); + if(wmenu->barwidth) width=wmenu->barwidth; + return(width); +} + + +// ------------------------------------------------------------------ +// this function will calculate the window column +// at the center of the given menu item + +static int calc_center_item(_item_t *item) +{ + return( ((int)item->wcol) + (strlen(item->str)/2) ); +} + + +// ------------------------------------------------------------------ +// this function will hide the mouse cursor +// if mouse cursor mode is on + +static void hide_mouse_cursor_mnu(void) { + + #ifdef GOLD_MOUSE + if(gmou.FreeCursor()) + gmou.HideCursor(); + #endif +} + + +// ------------------------------------------------------------------ +// this function will display the mouse +// cursor if mouse cursor mode is on + +static void show_mouse_cursor_mnu(void) { + + #ifdef GOLD_MOUSE + if(gmou.FreeCursor()) { + gmou.ShowCursor(); + gmou.SetCursor(0,0xFFFF,((LGREY|_LGREY)<<8)); + } + #endif +} + + +// ------------------------------------------------------------------ +// this function calls the given function + +static void mnu_call_func(VfvCP func) { + + _menu_t *menu; + int w; + int err; + + hide_mouse_cursor_mnu(); + menu=gwin.cmenu; + w=whandle(); + err=whelpush(); + (*func)(); + wactiv(w); + if(!err) whelpop(); + gwin.cmenu=menu; + show_mouse_cursor_mnu(); +} + + +// ------------------------------------------------------------------ +// this function will call a menu item's "after" function if it exists + +static void call_after(_item_t *citem) +{ + if(citem->after!=NULL) + mnu_call_func(citem->after); +} + + +// ------------------------------------------------------------------ +// this function will call a menu item's "before" function if it exists + +static void call_before(_item_t *citem) +{ + if(citem->before!=NULL) + mnu_call_func(citem->before); +} + + +// ------------------------------------------------------------------ +// this function closes the current menu's window and reactivates +// the menu window open prior to opening the current menu window + +static void close_window(int w) +{ + if(!gwin.cmenu->usecurr) { + hide_mouse_cursor_mnu(); + wclose(); + wactiv(w); + show_mouse_cursor_mnu(); + } +} + + +// ------------------------------------------------------------------ +// this function displays a menu selection, using selection bar if specified + +static void disp_item(_item_t *witem,int bar) +{ + char ch; + int chattr; + _wrec_t* whp; + char buf[256]; + register const char* p; + register vatch* ptr=(vatch*)buf; + int i, textend,width,wcol,found=NO; + + // if mouse cursor is on, temporarily hide it + hide_mouse_cursor_mnu(); + + // initialize width of output and end of text + p = witem->str; + width = calc_bar_width(gwin.cmenu,witem); + textend = gwin.cmenu->textpos+strlen(p)-1; + wgotoxy(witem->wrow,wcol=witem->wcol); + + // display menu item including selection bar + for(i=0; itextpos||i>textend)?' ':(*p++); + + // select attribute of character to be displayed based upon if + // selection bar was specified, if the menu item is non-selectable, + // if the character is a tag character, or none of the above. + if(bar) + chattr = gwin.cmenu->barattr; + else if(witem->fmask&M_NOSEL) + chattr = gwin.cmenu->noselattr; + else if((ch==witem->schar)&&!found) { + found = YES; + chattr = gwin.cmenu->scharattr; + } + else + chattr = gwin.cmenu->textattr; + + // display character in selected attribute + //wprintc(witem->wrow,wcol++,chattr,ch); + + // Build menu line buffer + + *ptr++ = vcatch(ch,chattr); + } + + // Display complete buffer + wprintws(witem->wrow, wcol, (vatch*)buf, width); + + // display text description, if one exists + if(witem->desc!=NULL&&dispdesc) { + whp = wfindrec(witem->dwhdl); + i = (1 + whp->ecol - whp->scol) - (whp->border ? 2 : 0); + sprintf(buf, "%-*.*s", i, i, witem->desc); + wwprints(witem->dwhdl, witem->dwrow, witem->dwcol, witem->dattr, buf); + } + + // if mouse cursor is hidden, unhide it + show_mouse_cursor_mnu(); +} + + +// ------------------------------------------------------------------ +// this function finds the next menu selection down + +static _item_t * down_item(_item_t *curr) +{ + _item_t *best,*temp; + int brow,bcol,tcol,trow,crow,ccol,tdist,bdist; + + // initialize best record to NULL + best=NULL; + brow=bcol=32767; + + // calculate window column at center of current item + crow=(int)curr->wrow; + ccol=calc_center_item(curr); + + // search backwards through linked list, testing each item + for(temp=gwin.cmenu->item;temp!=NULL;temp=temp->prev) { + + // calculate window column at center of test item + trow=(int)temp->wrow; + tcol=calc_center_item(temp); + + if(trow>crow) { + tdist=abs((ccol-tcol)); + bdist=abs((ccol-bcol)); + if((trowwrow=-1; + best=down_item(temp); + throw_free(temp); + } + } + else + // see if menu selection is non-selectable + if(best->fmask&M_NOSEL) + best=down_item(best); + + // return best record + return(best); +} + + +// ------------------------------------------------------------------ +// this function finds the upper-leftmost menu selection + +static _item_t * first_item(void) +{ + _item_t *best,*temp; + + // initialize best record to highest record in linked list + best=gwin.cmenu->item; + + // search backwards through linked list, testing each item + for(temp=best->prev;temp!=NULL;temp=temp->prev) { + if( (temp->wrowwrow) || + ( (temp->wrow==best->wrow) && (temp->wcolwcol) ) ) + best=temp; + } + + // see if menu selection is non-selectable + if(best->fmask&M_NOSEL) best=right_item(best); + + // return best record + return(best); +} + + +// ------------------------------------------------------------------ +// this is a recursive function that frees a menu and all of its submenus + +static void free_menu(_menu_t *wmenu) +{ + _item_t *witem; + + // free all items in menu, including sub-menus + while(wmenu->item!=NULL) { + if(wmenu->item->child!=NULL) free_menu((_menu_t*)wmenu->item->child); + witem=wmenu->item->prev; + throw_free(wmenu->item); + wmenu->item=witem; + if(wmenu->item!=NULL) wmenu->item->next=NULL; + } + + // free the menu itself + throw_free(wmenu); +} + + +// ------------------------------------------------------------------ +// this function will find the bottom-rightmost menu selection + +static _item_t * last_item(void) +{ + _item_t *best,*temp; + int bcol; + + // initialize best record to highest record in linked list + best=gwin.cmenu->item; + bcol=best->wcol; + + // search backwards through linked list, testing each item + for(temp=best->prev;temp!=NULL;temp=temp->prev) { + if( (temp->wrow>best->wrow) || + ( (temp->wrow==best->wrow) && + (temp->wcol>bcol) ) ) { + best=temp; + bcol=best->wcol; + } + } + + // see if menu selection is non-selectable + if(best->fmask&M_NOSEL) best=left_item(best); + + // return best record + return(best); +} + + +// ------------------------------------------------------------------ +// this function is called after a menu bar move + +static void post_move(_item_t *citem) +{ + gwin.cmenu->citem=citem; + gwin.help=citem->help; + disp_item(citem,1); + call_before(citem); +} + + +// ------------------------------------------------------------------ +// this function prepares for a menu bar move + +static void pre_move(_item_t *citem) +{ + disp_item(citem,0); + call_after(citem); +} + + +// ------------------------------------------------------------------ +// this function moves the selection bar to another menu item, +// automatically taking care of necessary pre/post move actions + +static _item_t * goto_item(_item_t *citem,int which) +{ + _item_t *item; + + if(which==ITM_FR) item=first_item(); + else if(which==ITM_LS) item=last_item(); + else item=(*mnu_funcs[which])(citem); + if(item!=citem) { + pre_move(citem); + post_move(citem=item); + } + return(citem); +} + + +// ------------------------------------------------------------------ +// this function will find the menu selection to the left of current + +static _item_t * left_item(_item_t *curr) +{ + _item_t *best,*temp; + int wwidth,bpos,tpos,cpos; + + // calculate window width and current position + wwidth=gwin.cmenu->ecol - gwin.cmenu->scol + 1; + cpos=(curr->wrow * wwidth) + curr->wcol; + + // initialize best record to NULL, and best position to -1 + best=NULL; + bpos=-1; + + // search backwards through linked list, testing each item + for(temp=gwin.cmenu->item;temp!=NULL;temp=temp->prev) { + + // calculate position of test each item + tpos=(temp->wrow*wwidth) + temp->wcol; + + // compare position of test item with best item, current item + if(tpos>bpos && tposfmask&M_NOSEL) + best=left_item(best); + + // return best record + return(best); +} + + +// ------------------------------------------------------------------ +// this function determines if the mouse cursor is on a menu item + +#ifdef GOLD_MOUSE +static _item_t *mouse_on_item(_menu_t *menu,int mcrow,int mccol) +{ + int srow,scol,border,start,end; + _item_t *item,*found; + + found = NULL; + srow = menu->srow; + scol = menu->scol; + border = menu->btype==5?0:1; + for(item=menu->item;item!=NULL;item=item->prev) { + if(mcrow==(srow+border+item->wrow)) { + start = scol+border+item->wcol; + end = start+calc_bar_width(menu,item)-1; + if(mccol>=start&&mccol<=end) { + found=item; + break; + } + } + } + return(found); +} +#endif + + +// ------------------------------------------------------------------ + +static void pre_exit(int w,int close) +{ + _menu_t *wmenu; + + hide_mouse_cursor_mnu(); + + // if not using current window for menu, then close it + if(close) close_window(w); + + // if at highest menu then free the whole menu structure + if(gwin.cmenu==gwin.menu) { + wmenu=gwin.menu->prev; + if(gwin.cmenu!=NULL) + free_menu(gwin.cmenu); + gwin.menu=wmenu; + if(gwin.menu!=NULL) + gwin.menu->next=NULL; + gwin.cmenu=gwin.menu; + } +} + + +// ------------------------------------------------------------------ +// this function reads the mouse for input + +static gkey read_mouse(_item_t* citem) { + + #ifdef GOLD_MOUSE + register _item_t *item; + + // if free-floating mouse cursor support is on + if(gmou.FreeCursor()) { + + // clear mouse button queue + gmou.ClearEvents(); + + // loop until a key is pressed + while(!kbxhit() and gkbd.kbuf==NULL) { + + // call the keyboard loop function + //if(gkbd.kbloop!=NULL) + //(*gkbd.kbloop)(); + + // if left button was pressed, and mouse cursor is on + // a selectable menu item, then move selection bar to + // that item, and select it. If mouse cursor is on + // a main menu item of a pull-down menu system, then + // stuff that item's selection character into the CXL + // keyboard buffer and return Esc to close the current + // pull-down menu. + gmou.GetLeftRelease(); + if(gmou.Count()) { + item = mouse_on_item(gwin.cmenu,gmou.Row(),gmou.Column()); + if(item == NULL) { + if(gwin.cmenu->menutype&M_PD) { + item = mouse_on_item(gwin.cmenu->parent,gmou.Row(),gmou.Column()); + if(item and (!(item->fmask&M_NOSEL))) { + kbput(item->schar); + return Key_Esc; + } + } + } + else { + if(!(item->fmask&M_NOSEL)) { + if(citem != item) { + pre_move(citem); + gwin.cmenu->citem = citem = item; + post_move(item); + } + return Key_Ent; + } + } + } + + // if right button was pressed, simulate pressing the Esc key + gmou.GetRightRelease(); + if(gmou.Count()) + return Key_Esc; + } + } + #endif + + // return zero - it means a key was pressed + return 0; +} + + +// ------------------------------------------------------------------ +// this function will find the menu selection to the right of current + +static _item_t * right_item(_item_t *curr) +{ + _item_t *best,*temp; + int wwidth,bpos,tpos,cpos; + + // calculate window width and current position + wwidth=gwin.cmenu->ecol - gwin.cmenu->scol + 1; + cpos=(curr->wrow * wwidth) + curr->wcol; + + // initialize best record to NULL, and best position to 32767 + best=NULL; + bpos=32767; + + // search backwards through linked list, testing items + for(temp=gwin.cmenu->item;temp!=NULL;temp=temp->prev) { + + // calculate position of test item + tpos=(temp->wrow*wwidth) + temp->wcol; + + // compare position of test item with best item, current item + if(tposcpos) { + best=temp; + bpos=tpos; + } + } + + // if there wasn't a item to the right, then wrap around + if(best==NULL) + best=first_item(); + else + // see if menu selection is non-selectable + if(best->fmask&M_NOSEL) + best=right_item(best); + + // return best record + return(best); +} + + +// ------------------------------------------------------------------ +// this function finds the previous menu selection upwards + +static _item_t * up_item(_item_t *curr) +{ + _item_t *best,*temp; + int brow,bcol,tcol,crow,trow,ccol,tdist,bdist; + + // initialize best record to NULL + best = NULL; + brow = -1; + bcol = 32767; + + // calculate window column at center of current item + crow=(int)curr->wrow; + ccol=calc_center_item(curr); + + // search backwards through linked list, testing items + for(temp=gwin.cmenu->item;temp!=NULL;temp=temp->prev) { + + // calculate window column at center of test item + trow=(int)temp->wrow; + tcol=calc_center_item(temp); + + if(trowbrow)||((trow==brow&&tdistwrow=255; + best=up_item(temp); + throw_free(temp); + } + } + else + // see if menu selection is non-selectable + if(best->fmask&M_NOSEL) + best=up_item(best); + + // return best record + return(best); +} + + +// ------------------------------------------------------------------ + +int wmenubeg(int srow, int scol, int erow, int ecol, int btype, int battr, int wattr, VfvCP open, int menutype) { + + _menu_t* wmenu; + + // if this is a submenu, then make sure that it is under a menu item + if(gwin.mlevel>gwin.ilevel) return(gwin.werrno=W_NOITMDEF); + + // allocate memory for new menu record + if((wmenu=(_menu_t*)throw_malloc(sizeof(_menu_t)))==NULL) + return(gwin.werrno=W_ALLOCERR); + + // if menu is not a submenu, make it a new base menu record + if(!gwin.mlevel) { + if(gwin.menu!=NULL) gwin.menu->next=wmenu; + wmenu->prev=gwin.menu; + wmenu->next=NULL; + wmenu->parent=NULL; + gwin.menu=gwin.cmenu=wmenu; + } + else { + if(menutype & M_PD) + gwin.cmenu->item->fmask |= M_HASPD; // Has a pull-down menu + gwin.cmenu->item->fmask &= ~M_CLOSE; // Don't close parent menu + wmenu->parent=gwin.cmenu; + gwin.cmenu = (_menu_t*)(gwin.cmenu->item->child = wmenu); + } + + // save info in menu record + wmenu->srow=srow; + wmenu->scol=scol; + wmenu->erow=erow; + wmenu->ecol=ecol; + wmenu->btype=btype; + wmenu->battr=battr; + wmenu->loattr=battr; + wmenu->sbattr=battr; + wmenu->wattr=wattr; + wmenu->menutype=menutype; + wmenu->open=open; + wmenu->usecurr=NO; + wmenu->item=NULL; + wmenu->title = ""; + wmenu->titlepos = -1; + wmenu->titleattr = 0; + wmenu->shadattr = -1; + wmenu->items = 0; + + // increment menu level + gwin.mlevel++; + + // return normally + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int wmenuitem(int wrow, int wcol, const char* str, char schar, int tagid, int fmask, VfvCP select, gkey hotkey, int help) { + + _item_t* witem; + + // make sure that wmenubeg() or wmenubegc() has been called + if(!gwin.mlevel) + return (gwin.werrno=W_NOMNUBEG); + + // allocate memory for new item record + witem = (_item_t*)throw_malloc(sizeof(_item_t)); + if(witem==NULL) + return (gwin.werrno=W_ALLOCERR); + + // add new menu item record to linked list + if(gwin.cmenu->item) + gwin.cmenu->item->next = witem; + witem->prev = gwin.cmenu->item; + witem->next = NULL; + gwin.cmenu->item = witem; + + // save info in item record + witem->wrow = wrow; + witem->wcol = wcol; + witem->str = str; + witem->schar = schar; + witem->tagid = tagid; + witem->fmask = fmask; + witem->select = select; + witem->hotkey = hotkey; + witem->desc = NULL; + witem->dwhdl = -1; + witem->dwrow = 0; + witem->dwcol = 0; + witem->dattr = 0; + witem->redisp = NO; + witem->help = help; + witem->child = NULL; + witem->before = NULL; + witem->after = NULL; + + gwin.cmenu->items++; + + int border = (gwin.cmenu->btype == 5) ? 0 : 1; + + int width = 1 + (gwin.cmenu->ecol-border) - (gwin.cmenu->scol+border); + size_t _titlen = gwin.cmenu->title ? strlen(gwin.cmenu->title) : 0; + int length = maximum_of_two(strlen(str), _titlen); + if(length > width) + gwin.cmenu->ecol += length - width; + + if(gwin.cmenu->menutype & M_VERT) { + int height = 1 + (gwin.cmenu->erow-border) - (gwin.cmenu->srow+border); + if(gwin.cmenu->items > height) + gwin.cmenu->erow += gwin.cmenu->items - height; + } + + // set item level == menu level + gwin.ilevel = gwin.mlevel; + + // return normally + return (gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int wmenuend(int taginit, int menutype, int barwidth, int textpos, int textattr, int scharattr, int noselattr, int barattr) { + + _item_t* item; + int w_width, border, found; + + // make sure at least 1 menu item has been defined + if(!gwin.mlevel||gwin.mlevel>gwin.ilevel) + return(gwin.werrno=W_NOITMDEF); + + // make sure that the specified initial tagid matches the + // tagid of one of the defined menu items in this menu + for(found=NO,item=gwin.cmenu->item;item!=NULL;item=item->prev) { + if(item->tagid==taginit) { + found=YES; + break; + } + } + if(!found) return(gwin.werrno=W_INVTAGID); + + // if bar width > window width, then bar width = window width + border=(gwin.cmenu->btype==5)?0:1; + w_width=(gwin.cmenu->ecol-border)-(gwin.cmenu->scol+border)+1; + if(barwidth>w_width) barwidth=w_width; + + // add rest of menu information to menu record + gwin.cmenu->citem = NULL; + gwin.cmenu->tagcurr = taginit; + gwin.cmenu->menutype |= menutype; + gwin.cmenu->barwidth = barwidth; + gwin.cmenu->textpos = barwidth?textpos:0; + gwin.cmenu->textattr = textattr; + gwin.cmenu->scharattr = scharattr; + gwin.cmenu->noselattr = noselattr; + gwin.cmenu->barattr = barattr; + + // set current menu pointer to parent menu + if((gwin.cmenu=gwin.cmenu->parent)==NULL) gwin.cmenu=gwin.menu; + + // decrement menu and item levels + gwin.mlevel--; + gwin.ilevel--; + + // return with no error + return(gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int wmenuget() { + + int valid, pulldown=NO, menuerr, winerr, err; + _item_t* citem; + _item_t* item; + int w = -1; + gkey xch; + char ch; + static int _depth = 0; + + if(_depth == 0) + _finaltagid = -1; + + // make sure we have a defined menu + if(gwin.cmenu==NULL) { + gwin.werrno=W_NOMNUDEF; + return(-1); + } + + // make sure that wmenuend() was called + if(gwin.mlevel||gwin.ilevel) { + gwin.werrno=W_NOMNUEND; + return(-1); + } + + // open menu's window (unless menu is to use current window) + if(!gwin.cmenu->usecurr) { + w=whandle(); + hide_mouse_cursor_mnu(); + if(!wopen(gwin.cmenu->srow,gwin.cmenu->scol,gwin.cmenu->erow,gwin.cmenu->ecol,gwin.cmenu->btype,gwin.cmenu->battr,gwin.cmenu->wattr,gwin.cmenu->sbattr,gwin.cmenu->loattr)) + return -1; + if(gwin.cmenu->shadattr != -1) + wshadow((int)gwin.cmenu->shadattr); + if(gwin.cmenu->title and *gwin.cmenu->title) + wtitle(gwin.cmenu->title, gwin.cmenu->titlepos, gwin.cmenu->titleattr); + show_mouse_cursor_mnu(); + + // save environment info, call menu open + // function, then restore environment info + if(gwin.cmenu->open!=NULL) + mnu_call_func(gwin.cmenu->open); + } + + // if mouse cursor mode is on, show cursor + show_mouse_cursor_mnu(); + + // find first item in linked list + if((item=gwin.cmenu->item)!=NULL) for(;item->prev!=NULL;item=item->prev); + + // display all menu items + dispdesc=NO; + valid=NO; + while(item!=NULL) { + disp_item(item,0); + if(!(item->fmask&M_NOSEL)) valid=YES; + item=item->next; + } + dispdesc=YES; + + // make sure there is at least 1 selectable menu item + if(!valid) { + pre_exit(w,YES); + gwin.werrno=W_NOSELECT; + return(-1); + } + + // search linked list of item records for the item matching + // the last item. If there was no last item, search for + // the initial tag ID position. If no initial tag ID position + // was specified, then find the upper-leftmost menu item. + citem=NULL; + if(gwin.cmenu->menutype&M_SAVE) { + for(citem=gwin.cmenu->item;citem!=NULL;citem=citem->prev) { + if((gwin.cmenu->citem==citem)&& + (!(citem->fmask&M_NOSEL))) + break; + } + } + if(citem==NULL) { + citem=wmenuifind(gwin.cmenu->tagcurr); + if((citem==NULL)||(citem->fmask&M_NOSEL)) citem=first_item(); + } + + // call the current menu item's 'before' + // function and display current menu item + post_move(citem); + + // main process of function + + for(;;) { + + // update current menu item and help category + gwin.cmenu->citem=citem; + gwin.help=citem->help; + + // read mouse/keyboard for keypress, then test the keypress + gkbd.inmenu=true; + xch = read_mouse(citem); + citem=gwin.cmenu->citem; + if(!xch) { + xch = getxch(); + } + gkbd.inmenu=false; + switch(xch) { + + case Key_Esc: + + // if Esc checking is on, erase selection bar, + // free menu records and return to caller + if(gwin.esc||(gwin.cmenu!=gwin.menu)) { + ESCAPE_KEY: + pre_move(citem); + pre_exit(w,YES); + gwin.werrno=W_ESCPRESS; + return(-1); + } + break; + + case Key_Home: + + // hide selection bar and find upper-leftmost menu item + citem=goto_item(citem,ITM_FR); + break; + + case Key_Lft: + + // if current menu is a pull-down menu, + // then erase selection bar, free menu records, + // and return special code to caller + if(gwin.cmenu->menutype&M_PD) { + pre_move(citem); + pre_exit(w,YES); + gwin.werrno=W_NOERROR; + return(M_PREVPD); + } + + // if current menu is a horizontal menu, then hide + // selection bar and find menu item to the left + if(gwin.cmenu->menutype&M_HORZ) + citem=goto_item(citem,ITM_LT); + + // if pull-down menu flag is set, select this item + if(pulldown&&citem->child!=NULL) goto ENTER; + break; + + case Key_Up: + + // if current menu is a vertical menu, then hide + // selection bar and find menu item upwards + if(gwin.cmenu->menutype&(M_VERT|M_PD)) + citem=goto_item(citem,ITM_UP); + break; + + case Key_Rgt: + + // if current menu is a pull-down menu, + // then erase selection bar, free menu records, + // and return special code to caller + if(gwin.cmenu->menutype&M_PD) { + pre_move(citem); + pre_exit(w,YES); + gwin.werrno=W_NOERROR; + return(M_NEXTPD); + } + + // if current menu is a horizontal menu, then hide + // selection bar and find menu item to the right + if(gwin.cmenu->menutype&M_HORZ) + citem=goto_item(citem,ITM_RT); + + // if pulldown flag is set, then select this item + if(pulldown&&citem->child!=NULL) goto ENTER; + break; + + case Key_Dwn: + + // if current item has a pull-down menu, select it + if(citem->fmask&M_HASPD) goto ENTER; + + // if current menu is a vertical menu, then hide + // selection bar and find menu item downwards + if(gwin.cmenu->menutype&(M_VERT|M_PD)) + citem=goto_item(citem,ITM_DN); + break; + + case Key_End: + + // hide selection bar and find + // lower-rightmost menu item + citem=goto_item(citem,ITM_LS); + break; + + case Key_Ent: + + ENTER: + + // if current menu item has a pull-down menu + // attached, then set the pulldown flag + if(citem->fmask&M_HASPD) pulldown=YES; + + // display menu item with selection bar + disp_item(citem,1); + + menuerr=0; + + // if current menu item has a child menu + if(citem->child!=NULL) { + + // save environment info, process child + // menu, then restore environment info + gwin.cmenu=(_menu_t*)citem->child; + hide_mouse_cursor_mnu(); + err=whelpush(); + _depth++; + menuerr=wmenuget(); + _depth--; + winerr=gwin.werrno; + if(!err) whelpop(); + show_mouse_cursor_mnu(); + gwin.cmenu=gwin.cmenu->parent; + + // if an error was returned by + // child menu, free menu records + // and pass error code to caller + if(menuerr==-1&&winerr!=W_ESCPRESS) { + call_after(citem); + menuerr=winerr; + pre_exit(w,YES); + gwin.werrno=menuerr; + return(-1); + } + } + + // if the M_CLOSB feature is on, then close the menu's + // window before the selection function is called. + if(citem->fmask&M_CLOSB) close_window(w); + + // this is used as a flag to see if the selection bar's + // position has been changed by the select function. + gwin.cmenu->tagcurr=-1; + + // if current menu item has a select function, call it + if(citem->select!=NULL) + mnu_call_func(citem->select); + + // if the M_CLOSB feature is on, then free the current + // menu a before the selection function is called. + if(citem->fmask&M_CLOSB) { + call_after(citem); + _finaltagid = citem->tagid; + pre_exit(w,NO); + gwin.werrno=W_NOERROR; + return _finaltagid; + } + + // check all menu items in current menu to + // see if their redisplay flag has been set + for(item=gwin.cmenu->item;item!=NULL;item=item->prev) { + if(item->redisp) { + disp_item(item,(item==citem)); + item->redisp=NO; + } + } + + // see if selection bar position was changed by select + // function. if so, then move selection bar to new item + if(gwin.cmenu->tagcurr!=-1) { + item=wmenuifind(gwin.cmenu->tagcurr); + if(item!=NULL&&(!(item->fmask&M_NOSEL))) { + pre_move(citem); + post_move(gwin.cmenu->citem=citem=item); + break; + } + } + + // if current menu item has a pull-down attached + if(citem->fmask&M_HASPD) { + + // if child menu returned previous pull-down menu + // flag, find menu item to the left and select it + if(menuerr==M_PREVPD) { + citem=goto_item(citem,ITM_LT); + if(citem->fmask&M_HASPD) goto ENTER; + break; + } + + // if child menu returned next pull-down menu + // flag, find menu item to the right and select it + if(menuerr==M_NEXTPD) { + citem=goto_item(citem,ITM_RT); + if(citem->fmask&M_HASPD) goto ENTER; + break; + } + } + + // turn off pulldown flag + pulldown=NO; + + // if child menu returned an exit-all-menus flag, + // then free menu records and pass exit-all-menus + // flag onto caller + if((menuerr==M_EXITALL)||(citem->fmask&M_CLALL)) { + disp_item(citem,1); + call_after(citem); + if(citem->fmask&M_CLALL) + if(_finaltagid == -1) + _finaltagid = citem->tagid; + pre_exit(w,YES); + gwin.werrno=W_NOERROR; + return M_EXITALL; + } + + // unless an exit-this-menu flag was returned by the + // child menu, or current item has close-menu + // specified, free menu records, and return tag + // identifier of current menu item + if(citem->child!=NULL||citem->select!=NULL) + if((menuerr!=M_EXIT)&&(!(citem->fmask&M_CLOSE))) + break; + call_after(citem); + _finaltagid = citem->tagid; + pre_exit(w,YES); + gwin.werrno=W_NOERROR; + return _finaltagid; + + default: + + // separate ASCII code from keypress code, if ASCII + // code is zero, then it must be an extended key + ch=(char)xch; + if(!ch and gmnudropthrough) { + if((xch != Key_PgDn) and (xch != Key_PgUp)) + kbput(xch); + goto ESCAPE_KEY; + } + + // scan through list of items for one that + // has a tag identifier matching keypress + valid=YES; + item=citem->next; + for(;;) { + while(item!=NULL) { + if((toupper(ch)==toupper(item->schar))&&(!(item->fmask + &M_NOSEL))) goto FARBREAK; + if(citem==item) { + valid=NO; + goto FARBREAK; + } + item=item->next; + } + for(item=gwin.cmenu->item;item->prev!=NULL; + item=item->prev); + } + + FARBREAK: + + // if a matching tag identifier was found, + // then hide selection bar, and if quick-key + // selection is allowed, select the found menu item + if(valid) { + if(item!=citem) { + pre_move(citem); + post_move(gwin.cmenu->citem=citem=item); + } + if(!(gwin.cmenu->menutype&M_NOQS)) goto ENTER; + } + } + } +} + + +// ------------------------------------------------------------------ +// Starts a menu definition in active window + +int wmenubegc() { + + // call wmenubeg() using current window parameters + if(wmenubeg(gwin.active->srow, + gwin.active->scol, + gwin.active->erow, + gwin.active->ecol, + gwin.active->btype, + gwin.active->battr, + gwin.active->wattr, + NULL)) { + return gwin.werrno; + } + + // turn on use-current-window flag + gwin.cmenu->usecurr=YES; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +static _item_t* search_menu(_menu_t* menu, int tagid) { + + _item_t *witem, *item; + + // do while more items in this menu + for(witem=menu->item; witem!=NULL; witem=witem->prev) { + + // if tagid of found item matches item we're + // searching for, then return that item's address + if(witem->tagid==tagid) + return witem; + + // if current item has a child menu, search it + if(witem->child!=NULL) { + item = search_menu((_menu_t*)witem->child,tagid); + if(item!=NULL) + return item; + } + } + + // return address of item found + return witem; +} + + +// ------------------------------------------------------------------ +// Finds item record in a menu structure + +_item_t* wmenuifind(int tagid) { + + _item_t* item; + + // check for existance of a menu + if(gwin.cmenu==NULL) { + gwin.werrno=W_NOMNUDEF; + return NULL; + } + + // start search process at root of menu structure + item = search_menu(gwin.menu,tagid); + + // return to caller + gwin.werrno = (item==NULL) ? W_NOTFOUND : W_NOERROR; + return item; +} + + +// ------------------------------------------------------------------ +// Adds a text description to menu item + +int wmenuitxt(int whdl, int wrow, int wcol, int attr, const char* str) { + + // make sure at least 1 menu item has been defined + if(!gwin.mlevel or gwin.mlevel>gwin.ilevel) + return gwin.werrno=W_NOITMDEF; + + // add description info to menu record + _item_t* citem = gwin.cmenu->item; + citem->dwhdl = whdl; + citem->dwrow = wrow; + citem->dwcol = wcol; + citem->dattr = (int)attr; + citem->desc = str; + + // return normally + return gwin.werrno=W_NOERROR; +} + + +// ------------------------------------------------------------------ + +int wmenuiba(VfvCP before, VfvCP after) { + + // make sure at least 1 menu item has been defined + if(!gwin.mlevel or gwin.mlevel > gwin.ilevel) + return(gwin.werrno=W_NOITMDEF); + + // update menu item record + gwin.cmenu->item->before = before; + gwin.cmenu->item->after = after; + + // return normally + return (gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int wmenuidsab(int tagid) { + + struct _item_t *item; + + // check for existance of a menu + if(gwin.cmenu==NULL) + return (gwin.werrno=W_NOMNUDEF); + + // find address of requested menu item + if((item=wmenuifind(tagid))==NULL) + return gwin.werrno; + + // disable menu item by making it nonselectable + item->fmask |= M_NOSEL; + + // set menu item's redisplay flag + item->redisp = true; + + // return normally + return (gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int wmenuienab(int tagid) { + + struct _item_t *item; + + // check for existance of a menu + if(gwin.cmenu==NULL) + return (gwin.werrno=W_NOMNUDEF); + + // find address of requested menu item + if((item=wmenuifind(tagid))==NULL) + return gwin.werrno; + + // enable menu item by making it selectable + item->fmask &= (~M_NOSEL); + + // set menu item's redisplay flag + item->redisp = true; + + // return normally + return (gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ + +int wmenuinext(int tagid) { + + // see if tagid is valid + if(wmenuifind(tagid)==NULL) + return gwin.werrno; + + // set current menu's current tagid to input tagid + wmenumcurr()->tagcurr = tagid; + + // return normally + return (gwin.werrno=W_NOERROR); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinmnub.cpp b/goldlib/gall/gwinmnub.cpp new file mode 100644 index 0000000..20b44b8 --- /dev/null +++ b/goldlib/gall/gwinmnub.cpp @@ -0,0 +1,312 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Menu class. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +void GMnu::Init() { + + bordertype = 0; + bordercolor = 0; + + textcolor = 0; + quickcolor = 0; + noselcolor = 0; + barcolor = 0; + shadowcolor = -1; + + title = NULL; + titlepos = TCENTER; + titlecolor = 0; + + deschdl = -1; + descrow = 0; + desccolumn = 0; + desccolor = 0; + + helpnumber = -1; + + beginrow = 0; + begincolumn = 0; + + menuopen = NULL; + itemmask = 0; + + escape = YES; + finaltag = -1; + status = W_NOERROR; + + depth = -1; + memset(stack, 0, sizeof(stack)); +} + + +// ------------------------------------------------------------------ + +void GMnu::SetBorder(int type, int color) { + + bordertype = type; + bordercolor = color; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetColor(int text, int quick, int nosel, int bar, int shadow) { + + textcolor = text; + quickcolor = quick; + noselcolor = nosel; + barcolor = bar; + shadowcolor = shadow; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetTitle(const char* text, int color, int pos) { + + title = text; + titlepos = pos; + titlecolor = color; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetTitle(const char* text) { + + title = text; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetDesc(int hdl, int row, int col, int color) { + + deschdl = hdl; + descrow = row; + desccolumn = col; + desccolor = color; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetPos(int row, int col, int width, int height) { + + beginrow = row; + begincolumn = col; + beginwidth = width; + beginheight = height; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetEsc(int option) { + + escape = option; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetHelp(int help) { + + helpnumber = help; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetMask(int mask) { + + itemmask = mask; +} + + +// ------------------------------------------------------------------ + +void GMnu::SetTag(int tag) { + + stack[depth].tag = tag; +} + + +// ------------------------------------------------------------------ + +void GMnu::Begin(int type) { + + int was_horz = (stack[depth].type&M_HORZ) ? true : false; + depth++; + stack[depth].tag = -1; + stack[depth].type = type | M_SAVE; + stack[depth].winrow = (beginrow != -1) ? beginrow : (was_horz ? stack[depth-1].winrow+1 : stack[depth-1].winrow+stack[depth-1].itemrow); + stack[depth].wincolumn = (begincolumn != -1) ? begincolumn : (stack[depth-1].wincolumn+(was_horz?0:1)); + stack[depth].itemrow = stack[depth].itemcolumn = 0; + status = wmenubeg_( + stack[depth].winrow, + stack[depth].wincolumn, + beginheight, + beginwidth, + bordertype, + bordercolor, + textcolor, + menuopen, + stack[depth].type + ); + wmenutitshad(title, titlepos, titlecolor, shadowcolor); + beginwidth = beginheight = 0; + beginrow = begincolumn = -1; +} + + +// ------------------------------------------------------------------ + +void GMnu::End() { + + status = wmenuend(stack[depth].tag, stack[depth].type, (stack[depth].type&M_VERT)?255:0, 0, textcolor, quickcolor, noselcolor, barcolor); + depth--; + if((depth >= 0) and (stack[depth].type & M_HORZ)) + stack[depth].wincolumn += stack[depth].winwidth; + title = NULL; +} + + +// ------------------------------------------------------------------ + +extern int _finaltagid; + +void GMnu::Start() { + + int _prev_escape = wsetesc(escape); + wmenuget(); + finaltag = _finaltagid; + wsetesc(_prev_escape); +} + + +// ------------------------------------------------------------------ + +void GMnu::Item(int tag, const char* text) { + + Item(tag, text, itemmask, NULL, 0); +} + + +// ------------------------------------------------------------------ + +void GMnu::Item(int tag, const char* text, int fmask) { + + Item(tag, text, fmask, NULL, 0); +} + + +// ------------------------------------------------------------------ + +void GMnu::Item(int tag, const char* text, VfvCP select, int fmask) { + + Item(tag, text, fmask, select, 0); +} + + +// ------------------------------------------------------------------ + +void GMnu::Item(int tag, const char* text, int fmask, VfvCP select, gkey hotkey) { + + if(stack[depth].tag == -1) + stack[depth].tag = tag; + + char shortcut = *text; + + for(_item_t* p = gwin.cmenu->item; p; p = p->prev) { + if(p->schar == shortcut) + shortcut = NUL; + } + + status = wmenuitem(stack[depth].itemrow, stack[depth].itemcolumn, text+1, shortcut, tag, fmask, select, hotkey, helpnumber); + stack[depth].winwidth = strlen(text+1); + if(stack[depth].type & M_HORZ) + stack[depth].itemcolumn += stack[depth].winwidth; + else + stack[depth].itemrow++; +} + + +// ------------------------------------------------------------------ + +void GMnu::ItemDesc(const char* text) { + + status = wmenuitxt(deschdl, descrow, desccolumn, desccolor, text); +} + + +// ------------------------------------------------------------------ + +void GMnu::ItemFuncs(VfvCP before, VfvCP after) { + + status = wmenuiba(before, after); +} + + +// ------------------------------------------------------------------ + +void GMnu::SetNextItem(int tag) { + + status = wmenuinext(tag); +} + + +// ------------------------------------------------------------------ + +void GMnu::DisableItem(int tag) { + + status = wmenuidsab(tag); +} + + +// ------------------------------------------------------------------ + +void GMnu::EnableItem(int tag) { + + status = wmenuienab(tag); +} + + +// ------------------------------------------------------------------ + +GMnuItm* GMnu::FindItem(int tag) { + + return wmenuifind(tag); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinpckf.cpp b/goldlib/gall/gwinpckf.cpp new file mode 100644 index 0000000..19d5be3 --- /dev/null +++ b/goldlib/gall/gwinpckf.cpp @@ -0,0 +1,257 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Allows user to select a file name. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +static bool path_in_title, case_sensitive; +static VfvCP open_function = NULL; +static char* cwdp; +static char* tcwdp; +static char* namextp; + + +// ------------------------------------------------------------------ +// this function is the compare function for qsort() + +static int compare(const char** str1, const char** str2) { + + // Sort with directories first + bool dir1 = !!strchr(*str1, GOLD_SLASH_CHR); + bool dir2 = !!strchr(*str2, GOLD_SLASH_CHR); + int cmp = compare_two(dir2, dir1); + if(cmp != 0) + return cmp; + + Path p1, p2; + strcpy(p1, *str1); if(dir1) { p1[strlen(p1)-1] = NUL; } + strcpy(p2, *str2); if(dir2) { p2[strlen(p2)-1] = NUL; } + + if(case_sensitive) + return strcmp(p1, p2); + else { + cmp = stricmp(p1, p2); + if(cmp == 0) + cmp = strcmp(p1, p2); + } + + return cmp; +} + + +// ------------------------------------------------------------------ +// this function displays the title on the pick window border + +static void disp_title() { + + if(path_in_title) { + char buf[sizeof(Path)+2]; + strcpy(buf, " "); + PathCopy(buf+1, cwdp); + strcat(buf, namextp); + strcat(buf, " "); + + wtitle(buf, TCENTER, gwin.active->battr); + } + + if(open_function) + (*open_function)(); +} + + +// ------------------------------------------------------------------ +// this function frees all allocated strings in the array of pointers + +static void free_strings(char** p, int numelems) { + + for(int i=0;iis_directory()) { + if(de->name != ".") { + strcpy(stpcpy(path, de->name.c_str()), GOLD_SLASH_STR); + name = path; + } + } + else if(de->is_file()) { + if(case_sensitive ? gwildmat(de->name.c_str(), namext) : gwildmati(de->name.c_str(), namext)) + name = de->name.c_str(); + } + if(name) { + p[files] = throw_xstrdup(name); + files++; + if(files == allocated-1) { + allocated *= 2; + p = (char**)throw_xrealloc(p, allocated*sizeof(char*)); + } + } + } + } + p[files] = NULL; + + // sort files in array by swapping their pointers + qsort(p, files, sizeof(char*), (StdCmpCP)compare); + + // let user pick file + if(files) + picked = wpickstr(srow, scol, erow, ecol, btype, bordattr, winattr, barattr, p, 0, disp_title); + if(picked == -1 or files == 0) { + pre_exit(p, files); + return NULL; + } + + // see if a directory was selected. if so save + // directory name, otherwise build whole path name + q = strchr(p[picked], GOLD_SLASH_CHR); + if(q) { + finished = false; + strcpy(dir, p[picked]); + r = strrchr(dir, GOLD_SLASH_CHR); + if(r) + *r = NUL; + *q = NUL; + } + else { + finished = true; + PathCopy(path, cwd); + strcat(path, p[picked]); + } + + // free allocated strings + free_strings(p, files); + + // if a directory was selected, go back and do again + } while(not finished); + + // change back to current drive and directory + gchdir(tcwd); + + // free allocated char pointers + throw_xfree(p); + + // return normally + strcpy(selectedfile, path); + return selectedfile; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gwinpcks.cpp b/goldlib/gall/gwinpcks.cpp new file mode 100644 index 0000000..aab5ecc --- /dev/null +++ b/goldlib/gall/gwinpcks.cpp @@ -0,0 +1,701 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on CXL by Mike Smedley. +// ------------------------------------------------------------------ +// Lets user pick from an array of strings. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +int wpickstr_tag = false; + + +// ------------------------------------------------------------------ +// define record that will hold pick window info + +struct r_t { + int numelems; + int lastelem; + int curr; + int first; + int last; + int strsperline; + int strsperwin; + int maxstrlen; + int wwidth; + int wheight; + int fillspaces; + int gapspaces; + int xtraspaces; + int winattr; + int barattr; + int scrollbar; +}; + + +// ------------------------------------------------------------------ +// this function will display the mouse +// cursor if mouse cursor mode is on + +static void show_mouse_cursor_pck() { + + #ifdef GOLD_MOUSE + if(gmou.FreeCursor()) { + gmou.ShowCursor(); + gmou.SetCursor(0,0xFFFF,((LGREY|_LGREY)<<8)); + } + #endif +} + + +// ------------------------------------------------------------------ +// this function will hide the mouse +// cursor if mouse cursor mode is on + +static void hide_mouse_cursor_pck() { + + #ifdef GOLD_MOUSE + if(gmou.FreeCursor()) + gmou.HideCursor(); + #endif +} + + +// ------------------------------------------------------------------ +// this function updates the current item by either +// displaying or erasing the selection bar on it + +static void update_curr(char* strarr[], r_t* r, int bar) { + + // calculate row and column string will be displayed + // at, then print out the string character-by-character + + int crow = (r->curr-r->first)/r->strsperline; + int temp = r->curr-((crow*r->strsperline)+r->first); + int ccol = (temp*r->maxstrlen)+((temp+1)*(r->gapspaces))+r->xtraspaces; + + wgotoxy(crow,ccol); + + hide_mouse_cursor_pck(); + + wprintns(crow, ccol, bar ? r->barattr : r->winattr, strarr[r->curr], r->maxstrlen); + + show_mouse_cursor_pck(); +} + + +// ------------------------------------------------------------------ + +static void update_line(char* strarr[], r_t* r, int wrow, int upcurr) { + + int nomore = false; + int ccol = r->gapspaces + r->xtraspaces; + int celem = (wrow*r->strsperline) + r->first; + + if(celem >= r->numelems) + nomore = true; + + for(int j=0; jstrsperline; j++) { + int ccolbeg = ccol; + wprintns(wrow, ccolbeg, (upcurr and r->curr==celem) ? r->barattr : r->winattr, nomore ? "" : strarr[celem], r->maxstrlen); + ccol += r->maxstrlen; + if(++celem >= r->numelems) + nomore = true; + ccol += r->gapspaces; + } +} + + +// ------------------------------------------------------------------ +// this function will update all items in the window + +static void update_window(char* strarr[], r_t* r) { + + hide_mouse_cursor_pck(); + for(int crow=0; crowwheight; crow++) + update_line(strarr, r, crow, 1); + show_mouse_cursor_pck(); +} + + +// ------------------------------------------------------------------ +// this function will find the element number of the +// first element on the same line as the given element + +static int e_begline(r_t* r, int elem) { + + return (elem/r->strsperline) * r->strsperline; +} + + +// ------------------------------------------------------------------ +// this function will find the first element in a +// window, using a given last element as input + +static int e_begwin(r_t* r, int lelem) { + + int beg = e_begline(r,lelem) + r->strsperline - r->strsperwin; + if(beg < 0) + beg = 0; + + return beg; +} + + +// ------------------------------------------------------------------ +// this function will find the element number of the +// last element on the same line as the given element + +static int e_endline(r_t* r, int elem) { + + int end = (((elem/r->strsperline)+1)*r->strsperline)-1; + if(end>=r->numelems) + end = r->lastelem; + + return end; +} + + +// ------------------------------------------------------------------ +// this function will find the last element in a +// window, using a given first element as input + +static int e_endwin(r_t* r, int felem) { + + int end = felem + r->strsperwin - 1; + if(end > (r->lastelem)) + end = r->lastelem; + + return end; +} + + +// ------------------------------------------------------------------ + +static void goto_item(r_t* r, char* strarr[], int elem) { + + if(elem<0 or elem>r->lastelem) + elem = 0; + int outside = (elemfirst or elem>r->last) ? YES : NO; + if(outside == NO) + update_curr(strarr,r,0); + r->curr = elem; + if(outside) { + r->first = e_begwin(r,r->last = e_endwin(r,e_begline(r,r->curr))); + update_window(strarr,r); + } + else { + update_curr(strarr,r,1); + } +} + + +// ------------------------------------------------------------------ +// this function determines if the mouse cursor is on a item + +#ifdef GOLD_MOUSE +static int mouse_on_item(r_t* r, int mcrow, int mccol) { + + int found = -1; + int srow = gwin.active->srow; + int scol = gwin.active->scol; + int border = gwin.active->border; + + for(int i=r->first; i<=r->last; i++) { + if(mcrow==(srow+border+((i-r->first)/r->strsperline))) { + int start = scol+border+r->xtraspaces+r->gapspaces+((i%r->strsperline)*(r->maxstrlen+r->gapspaces)); + int end = start+r->maxstrlen-1; + if(mccol>=start and mccol<=end) { + found = i; + break; + } + } + } + if(found==-1 and r->scrollbar and mccol==gwin.active->ecol) { + if(mcrow==srow+1) + found=-2; + else { + if(mcrow==gwin.active->erow-1) + found=-3; + } + } + + return found; +} +#endif + + +// ------------------------------------------------------------------ + +static void page_down(char* strarr[], r_t* r) { + + if(r->curr != r->last) { + r->curr = r->last; + update_window(strarr, r); + } + else if(r->last != (r->lastelem)) { + int i = r->curr-r->first; + r->last = e_endwin(r,r->last+1); + r->first = e_begwin(r, r->last); + if((r->curr = r->first+i) > (r->lastelem)) + r->curr -= r->strsperline; + update_window(strarr, r); + } +} + + +// ------------------------------------------------------------------ + +static void page_up(char* strarr[], r_t* r) { + + if(r->curr != r->first) { + r->curr = r->first; + update_window(strarr, r); + } + else if(r->first) { + int i = r->curr-r->first; + r->first = e_begwin(r,r->first-1); + r->last = e_endwin(r, r->first); + r->curr = r->first+i; + update_window(strarr,r); + } +} + + +// ------------------------------------------------------------------ + +static void scroll_down(char* strarr[], r_t* r, int upcurr) { + + if(r->first) { + hide_mouse_cursor_pck(); + if(upcurr) + update_curr(strarr,r,0); + r->first -= r->strsperline; + r->last = e_endline(r,r->last-r->strsperline); + if(upcurr>1) + r->curr -= r->strsperline; + if(r->first != e_begline(r,r->last)) + wscroll(1,SDOWN); + update_line(strarr, r, 0, (upcurr>2) ? 0 : upcurr); + show_mouse_cursor_pck(); + } +} + + +// ------------------------------------------------------------------ + +static void scroll_up(char* strarr[], r_t* r, int upcurr) { + + if(r->last!=(r->lastelem)) { + hide_mouse_cursor_pck(); + if(upcurr) + update_curr(strarr,r,0); + r->first+=r->strsperline; + r->last=e_endline(r,r->last+1); + if(upcurr>1) + if((r->curr+r->strsperline)<=r->last) + r->curr+=r->strsperline; + if(r->first!=e_begline(r,r->last)) + wscroll(1,SUP); + update_line(strarr,r,r->wheight-1,(upcurr>2)?0:upcurr); + show_mouse_cursor_pck(); + } +} + + +// ------------------------------------------------------------------ +// this function reads the mouse for input + +static gkey read_mouse(char* strarr[], r_t* r) { + + #ifdef GOLD_MOUSE + // if free-floating mouse cursor support is on + if(gmou.FreeCursor()) { + + // clear mouse button queue + gmou.ClearEvents(); + + // loop until a key is pressed + while(!kbxhit() and gkbd.kbuf==NULL) { + + // call the keyboard loop function, if defined + //if(gkbd.kbloop!=NULL) + //(*gkbd.kbloop)(); + + // see if the right button (Esc) was pressed + gmou.GetRightRelease(); + if(gmou.Count()) + return Key_Esc; + + // see where mouse cursor is at - if it is on a scroll bar + // or menu item, and the left button is pressed, then scroll + // menu or select item + gmou.GetStatus(); + int i = mouse_on_item(r,gmou.Row(),gmou.Column()); + switch(i) { + case -1: + gmou.ClearEvents(); + break; + case -2: + if(gmou.LeftButton()) { + scroll_down(strarr,r,3); + if(gvid->isbios()) + usleep(50); + gmou.ClearEvents(); + } + break; + case -3: + if(gmou.LeftButton()) { + scroll_up(strarr,r,3); + if(gvid->isbios()) + usleep(50); + gmou.ClearEvents(); + } + break; + default: + gmou.GetLeftRelease(); + if(gmou.Count()) { + r->curr = i; + return Key_Ent; + } + } + } + } + #endif + + // return zero - it means a key was pressed + return 0; +} + + +// ------------------------------------------------------------------ + +int wpickstr(int srow, int scol, int erow, int ecol, int btype, int bordattr, int winattr, int barattr, char* strarr[], int initelem, VfvCP open) { + + int i, j, maxlen, outside; + gkey xch; + char ch; + char* p; + r_t r; + + int quickpos = (strarr[0][0] == ' ') ? 1 : 0; + + // go through input array and determine the longest + // string, and count the number of elements in the array + + for(i=maxlen=0; strarr[i]!=NULL; i++) + if((j=strlen(strarr[i]))>maxlen) + maxlen = j; + + r.maxstrlen = maxlen; + r.lastelem = ((r.numelems=i)-1); + r.winattr = winattr; + r.barattr = barattr; + + // see if window is to have a border + int border = (btype==5) ? NO : YES; + + // if ecol == -1 then adjust it to conform to length of longest string + if(ecol==-1) + ecol = scol+border+r.maxstrlen+border-1; + + // calculate window area width and height + r.wwidth = (ecol-border)-(scol+border)+1; + r.wheight = (erow-border)-(srow+border)+1; + + // make sure longest string can fit in window + if(r.maxstrlen > r.wwidth) { + gwin.werrno=W_STRLONG; + return -1; + } + + // open window which strings will reside in + hide_mouse_cursor_pck(); + if(!wopen(srow,scol,erow,ecol,btype,bordattr,winattr,bordattr)) + return -1; + + // if mouse cursor mode is on and window has a border, + // display scroll indicator arrows on right window border + #ifdef GOLD_MOUSE + if(gmou.FreeCursor() and (btype!=5) and ((srow+2) < erow)) { + vputc(srow+1,ecol,bordattr,(char) 24); + vputc(erow-1,ecol,bordattr,(char) 25); + r.scrollbar=true; + } + else { + #endif + r.scrollbar=false; + #ifdef GOLD_MOUSE + } + #endif + show_mouse_cursor_pck(); + + // if an open function has been specified, then call it + if(open!=NULL) + open(); + + // if mouse cursor mode is on, then turn on mouse cursor + show_mouse_cursor_pck(); + + // calculate how many strings can fit into 1 window line, number of + // filler spaces needed per window line, number of spaces per gap in + // between strings, number of extra spaces to add to first gap, and + // number of strings that can fit inside the window + r.strsperline = (r.wwidth-2)/(r.maxstrlen+2); + if(!r.strsperline) + r.strsperline++; + r.fillspaces = r.wwidth-(r.strsperline*r.maxstrlen); + r.gapspaces = r.fillspaces/(r.strsperline+1); + r.xtraspaces = (r.fillspaces%(r.strsperline+1))/2; + r.strsperwin = r.strsperline*r.wheight; + + // initialize first, last, and current elements + r.curr = r.first = 0; + r.last = (r.numelemsr.last) + scroll_up(strarr,&r,((r.curr+r.strsperline)>r.lastelem) ? 0 : 2); + else { + update_curr(strarr,&r,0); + r.curr+=r.strsperline; + update_curr(strarr,&r,1); + } + break; + + case Key_PgUp: + + // move up 1 page. adjust position if at 1st element + page_up(strarr,&r); + break; + + case Key_PgDn: + + // move down 1 page. adjust position if at last element + page_down(strarr,&r); + break; + + case Key_Home: + + // set position to 1st element + if(r.curr) { + if((outside=r.first)==NO) + update_curr(strarr,&r,0); + r.first=r.curr=0; + if(outside) { + r.last=e_endwin(&r,r.first); + update_window(strarr,&r); + } + else { + update_curr(strarr,&r,1); + } + } + break; + + case Key_End: + + // set position to last element + if(r.curr!=r.lastelem) { + if((outside=(r.last<(r.lastelem))?YES:NO)==NO) + update_curr(strarr,&r,0); + r.last=r.curr=r.lastelem; + if(outside) { + r.first=e_begwin(&r,r.last); + update_window(strarr,&r); + } + else { + update_curr(strarr,&r,1); + } + } + break; + + default: + + // if not an extended keypress, then search from current + // position for the item that begins with the same ASCII + // character as the keypress. If not found after current + // position, search from the beginning for a match + ch = (char)toupper((char)xch); + if(!ch) + break; + for(i=r.curr+1; i +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +int Picker(PInf* p, Pick* pick) { + + int keyok; + gkey keycode, newkey; + + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + + // Open and initialize + + if(pick->open) + pick->open(p); + if(p->helpcat) + whelppcat(p->helpcat); + + do { + + // Display selection bar + + wgotoxy(p->pos, 0); + p->type = PICK_BAR; + pick->disp(p); + p->type = PICK_DISP; + + // Handle keyboard and delay function + + if(pick->dodelayed) + pick->dodelayed(p); + + #ifdef GOLD_MOUSE + gmou.ShowCursor(); + #endif + + keyok = YES; + + do { + newkey = keycode = getxchtick(); + if(newkey == Key_Tick) + pick->dokey(p, &keycode); + } while(newkey == Key_Tick); + + do { + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + newkey = 0; + switch(keycode) { + case Key_Up: + case Key_Dwn: + case Key_PgUp: + case Key_PgDn: + case Key_Home: + case Key_End: + if(pick->precursor) + pick->precursor(p); + break; + } + switch(keycode) { + case Key_Up: + p->direction = -1; + if(p->pos) { + pick->disp(p); + p->pos--; + p->idx--; + } + else if(p->idx > p->minidx) { + pick->disp(p); + p->idx--; + pick->scroll(p, SDOWN); + } + else if(p->listwrap) + newkey = Key_End; + break; + + case Key_Dwn: + p->direction = 1; + if(p->pos < p->maxpos) { + if(p->idx < p->maxidx) { + pick->disp(p); + p->pos++; + p->idx++; + } + else if(p->listwrap) + newkey = Key_Home; + } + else if(p->idx < p->maxidx) { + pick->disp(p); + p->idx++; + pick->scroll(p, SUP); + } + else if(p->listwrap) + newkey = Key_Home; + break; + + case Key_PgUp: + p->direction = -1; + if(p->pos) { + pick->disp(p); + p->idx -= p->pos; + p->pos = 0; + } + else if(p->idx > p->minidx) { + p->idx -= (p->idx >= p->maxpos) ? p->maxpos : p->idx; + pick->page(p); + } + break; + + case Key_PgDn: + p->direction = 1; + if(p->pos < p->maxpos) { + if(p->idx == p->maxidx) { + if(p->maxpos < p->maxidx) { + p->pos = p->maxpos; + p->idx = p->maxidx; + pick->page(p); + } + } + else if(p->idx + (p->maxpos-p->pos) >= p->maxidx) { + pick->disp(p); + p->pos += p->maxidx-p->idx; + p->idx = p->maxidx; + } + else if(p->pos != p->maxpos) { + pick->disp(p); + p->idx += p->maxpos-p->pos; + p->pos = p->maxpos; + } + } + else if(p->idx < p->maxidx) { + if(p->idx+p->maxpos > p->maxidx) { + p->pos = p->maxidx-p->idx; + p->idx = p->maxidx; + pick->page(p); + } + else { + p->idx += p->maxpos; + p->pos = p->maxpos; + pick->page(p); + } + } + break; + + case Key_Home: + p->direction = -1; + if(p->idx > p->minidx) { + if((p->idx - p->pos) <= p->minidx) { + pick->disp(p); + p->idx = p->minidx; + p->pos = 0; + } + else { + p->pos = 0; + p->idx = p->minidx; + pick->page(p); + } + } + break; + + case Key_End: + p->direction = 1; + if(p->idx < p->maxidx) { + if(p->idx + (p->maxpos-p->pos) >= p->maxidx) { + pick->disp(p); + p->pos += p->maxidx-p->idx; + p->idx = p->maxidx; + } + else { + p->pos = (p->maxidx-p->idx) < p->maxpos ? p->maxidx-p->idx : p->maxpos; + p->idx = p->maxidx; + pick->page(p); + } + } + else if(p->pos < p->maxpos) { + if(p->maxpos < p->maxidx) { + p->pos = p->maxpos; + p->idx = p->maxidx; + pick->page(p); + } + } + break; + + case Key_C_Up: + p->direction = -1; + if(p->idx - p->pos) { + p->idx--; + pick->page(p); + } + break; + + case Key_C_Dwn: + p->direction = 1; + if(p->idx < p->maxidx) { + p->idx++; + pick->page(p); + } + break; + + default: + keyok = pick->dokey(p, &keycode); + newkey = keycode; + } + if(newkey) + keycode = newkey; + } while(newkey); + } while(keyok); + + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + + // Close and clean + if(p->helpcat) + whelpop(); + if(pick->close) + pick->close(p); + + #ifdef GOLD_MOUSE + gmou.ShowCursor(); + #endif + + return p->retval; +} + + +// ------------------------------------------------------------------ + +gwinpick::gwinpick() { + + // memset(this, 0, sizeof(gwinpick)); WHAT!?!?! ARE YOU NUTS? + + key = 0; + keyok = false; + ypos = xpos = ylen = xlen = 0; + btype = battr = wattr = tattr = sattr = hattr = loattr = sbattr = 0; + title = NULL; + helpcat = 0; + maximum_index = minimum_index = maximum_position = index = position = 0; + aborted = listwrap = false; + direction = 0; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_up() { + + bool done; + + do { + if(index > minimum_index) { + display_line(); + if(position) + position--; + else + scroll(SDOWN); + index--; + if((done = is_selectable(index))==true) + update_cursor(); + } + else { + if(listwrap) + cursor_last(); + else if(not is_selectable(index)) + cursor_down(); + done = true; + } + } while(not done); + direction = -1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_down() { + + bool done; + + do { + if(index < maximum_index) { + display_line(); + index++; + if(position < maximum_position) + position++; + else + scroll(SUP); + + if((done = is_selectable(index))!=false) + update_cursor(); + } + else { + if(listwrap) + cursor_first(); + else if(not is_selectable(index)) + cursor_up(); + done = true; + } + } while(not done); + direction = 1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_pageup() { + + uint i = index - position; + + while(not is_selectable(i)) i++; + + uint min = i + position - index; + + if(position > min) { + display_line(); + index = i; + position = min; + update_cursor(); + } + else if(index > min) { + i = maximum_position - min + position; + index -= (index >= i) ? i : index; + position = 0; + display_page(); + if(not is_selectable(index)) + cursor_down(); + } + + direction = -1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_pagedown() { + + uint max_index = index + maximum_position - position; + + if(max_index > maximum_index) max_index = maximum_index; + while(not is_selectable(max_index)) --max_index; + + uint max_position = max_index - index + position; + + if(position < max_position) { + if(index == max_index) { + if(maximum_position < maximum_index) { + position = maximum_position; + index = maximum_index; + display_page(); + update_cursor(); + } + } + else if(max_index >= max_position) { + display_line(); + position = max_position; + index = max_index; + update_cursor(); + } + else if(position != maximum_position) { + display_line(); + index += maximum_position-position; + position = maximum_position; + update_cursor(); + } + } + else if(index < maximum_index) { + if(index+maximum_position+(maximum_position - max_position)> maximum_index) { + position = maximum_index - index; + index = maximum_index; + } + else { + index += maximum_position + (maximum_position - max_position); + position = maximum_position; + } + display_page(); + } + + if(not is_selectable(index)) + cursor_up(); + + direction = 1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_first() { + + uint min_select = minimum_index; + + while(not is_selectable(min_select)) + min_select++; + + if(index > min_select) { + if(index <= position) { + display_line(); + index = position = min_select; + update_cursor(); + } + else { + index = position = min_select; + display_page(); + } + } + + direction = -1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_last() { + + uint max_select = maximum_index; + + while(not is_selectable(max_select)) + max_select--; + + if(index < max_select) { + if(index + (maximum_position-position) >= maximum_index) { + display_line(); + position += max_select - index; + index = max_select; + update_cursor(); + } + else { + position = (maximum_index-index) < maximum_position ? maximum_index-index : maximum_position; + position -= maximum_index - max_select; + index = max_select; + display_page(); + } + } + else if(position < maximum_position) { + if(maximum_position < maximum_index) { + position = maximum_position + max_select - maximum_index; + index = max_select; + display_page(); + } + } + + direction = 1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_scroll_up() { + + uint oldidx = index; + do { + if(index - position) + index--; + else + while((not is_selectable(index)) and (index < maximum_index)) + index++; + } while(not is_selectable(index)); + if(index != oldidx) + display_page(); + + direction = -1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::cursor_scroll_down() { + + uint oldidx = index; + do { + if(index < maximum_index) + index++; + else + while((not is_selectable(--index)) and (index > minimum_index)) + ; + } while(not is_selectable(index)); + if(index!=oldidx) + display_page(); + + direction = 1; +} + + +// ------------------------------------------------------------------ + +void gwinpick::display_line(bool bar) { + + print_line(index, position, bar); +} + + +// ------------------------------------------------------------------ + +void gwinpick::display_page() { + + if(index > position) + index -= position; + else + index = 0; + + register uint m = maximum_index-index; + + uint n; + + for(n=0; n<=maximum_position and n<=m; n++) + print_line(index+n, n, (position == n)); + + if(n < ylen) + wputx(n, 0, battr|ACSET, _box_table(btype,1), xlen); + + for(++n; n maximum_position) ? 0 : (maximum_position - botroom); + break; + case LIST_NEARTOP: + { + uint room; + uint toproom = index; + if(toproom > (maximum_position/4)) { + if(botroom > (maximum_position/4)) + room = maximum_position/4; + else if(botroom) + room = maximum_position - botroom; + else + room = maximum_position; + } + else + room = toproom; + position = room; + } + break; + case LIST_MIDDLE: + { + uint room; + uint toproom = index; + if(toproom > (maximum_position/2)) { + if(botroom > (maximum_position/2)) + room = maximum_position/2; + else if(botroom) + room = maximum_position - botroom; + else + room = maximum_position; + } + else + room = toproom; + position = room; + } + break; + case LIST_NEARBOTTOM: + { + uint room; + uint toproom = index; + if(toproom > 3*(maximum_position/4)) { + if(botroom > 3*(maximum_position/4)) + room = 3*(maximum_position/4); + else if(botroom) + room = maximum_position - botroom; + else + room = maximum_position; + } + else + room = toproom; + position = room; + } + break; + case LIST_BOTTOM: + position = maximum_position; + break; + } + update(); +} + + +// ------------------------------------------------------------------ + +int gwinpick::run_picker() { + + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + + // Open and initialize + + open(); + if(helpcat) + whelppcat(helpcat); + + if(not is_selectable(index)) + cursor_down(); + + do { + + do_delayed(); + + #ifdef GOLD_MOUSE + gmou.ShowCursor(); + #endif + + keyok = true; + + do { + key = getxchtick(); + if(key == Key_Tick) + handle_key(); + } while(key == Key_Tick); + + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + + keyok = default_handle_key(); + + } while(keyok); + + #ifdef GOLD_MOUSE + gmou.HideCursor(); + #endif + + // Close and clean + if(helpcat) + whelpop(); + close(); + + #ifdef GOLD_MOUSE + gmou.ShowCursor(); + #endif + + return 0; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gall/gwinpick.h b/goldlib/gall/gwinpick.h new file mode 100644 index 0000000..0f10214 --- /dev/null +++ b/goldlib/gall/gwinpick.h @@ -0,0 +1,185 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Pick engine. +// ------------------------------------------------------------------ + +#ifndef __gwinpick_h +#define __gwinpick_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// Constants + +const int PICK_DISP = 0; +const int PICK_BAR = 1; + +const int LIST_BOTTOM = -2; +const int LIST_NEARBOTTOM = -1; +const int LIST_MIDDLE = 0; +const int LIST_NEARTOP = 1; +const int LIST_TOP = 2; + + +// ------------------------------------------------------------------ +// Picker info + +struct PInf { + + PInf() : ypos(row), xpos(column), ylen(height), xlen(width) {} + + uint& ypos; + uint& xpos; + uint& ylen; + uint& xlen; + uint row; //ypos; // Window Starting Row + uint column; //xpos; // Window Starting Column + uint height; //ylen; // Window Height + uint width; //xlen; // Window Width + int btype; // Window Border Type + int battr; // Window Border Color + int wattr; // Window Color + int tattr; // Window Title Color + int sattr; // Window Selection Bar Color + int hattr; // Window Highlight Color + int loattr; // Window LoAttr Color + int sbattr; // Window Scrollbar Color + char* title; // Window Title + int helpcat; // Window Help Category + uint maxidx; // List Entries - 1 + uint minidx; // Minimum index in the list + uint maxpos; // Display Pos + uint idx; // List Index + uint pos; // Display Pos + long delay; // Ticks until delay + int type; // Bar or Disp + int retval; // Return value + bool aborted; // True if aborted + bool listwrap; // True if wrap-around is supported + int direction; // 1 if next, -1 if previous +}; + + +// ------------------------------------------------------------------ +// Picker definable functions + +struct Pick { + void (*open) (PInf*); // Called after window is opened + void (*close) (PInf*); // Called after window is closed + void (*precursor)(PInf*); // Called before any cursor movement + void (*dodelayed)(PInf*); // Called after a delay + void (*disp) (PInf*); // Display line + void (*page) (PInf*); // Display page + void (*scroll) (PInf*, int); // Scroll list (direction) + int (*dokey) (PInf*, gkey*); // Called with key (&keycode) +}; + + +// ------------------------------------------------------------------ +// Prototypes + +int Picker(PInf* p, Pick* pick); + + +// ------------------------------------------------------------------ + +class gwinpick { + +private: + +protected: + + gkey key; + bool keyok; + + void cursor_up(); + void cursor_down(); + void cursor_pageup(); + void cursor_pagedown(); + void cursor_first(); + void cursor_last(); + void cursor_scroll_up(); + void cursor_scroll_down(); + + void update_cursor(); + + void display_line(bool bar=false); + void display_page(); + bool default_handle_key(); + + inline void update() { display_page(); }; + +public: + + uint ypos; // Window Starting Row + uint xpos; // Window Starting Column + uint ylen; // Window Height + uint xlen; // Window Width + int btype; // Window Border Type + int battr; // Window Border Color + int wattr; // Window Color + int tattr; // Window Title Color + int sattr; // Window Selection Bar Color + int hattr; // Window Highlight Color + int loattr; // Window LoAttr Color + int sbattr; // Window Scrollbar Color + const char* title; // Window Title + int helpcat; // Window Help Category + uint maximum_index; // List Entries - 1 + uint minimum_index; // Minimum index in the list + uint maximum_position; // Display Pos + uint index; // List Index + uint position; // Display Pos + bool aborted; // True if aborted + bool listwrap; // True if wrap-around is supported + int direction; // 1 if next, -1 if previous + + virtual void open(); // Called after window is opened + virtual void close(); // Called after window is closed + virtual void precursor(); // Called before any cursor movement + virtual void do_delayed(); // Called after a delay + virtual void print_line(uint idx, uint pos, bool isbar) = 0; + virtual void scroll(int where); // Scroll page + virtual bool handle_key(); // Handles keypress + virtual bool is_selectable(uint idx); // returns true if selectable + + void display_bar() { display_line(true); } + void center(int listmode); + + int run_picker(); + + gwinpick(); + virtual ~gwinpick() { }; +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinput.h b/goldlib/gall/gwinput.h new file mode 100644 index 0000000..7a63f1a --- /dev/null +++ b/goldlib/gall/gwinput.h @@ -0,0 +1,226 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Input form and field editing. +// ------------------------------------------------------------------ + +#ifndef __gwinput_h +#define __gwinput_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +class gwinput { + +public: + + class field { + + public: + + gwinput* form; + + int pos; + int max_pos; + int attr; + bool fill_acs; + vchar fill; + int entry; + + char* buf; + int buf_left_pos; + int buf_end_pos; + int buf_pos; + int buf_len; + + string& destination; + + int id; + int row; + int column; + int max_column; + int conversion; + int entry_mode; + + field* prev; + field* next; + + field(gwinput* iform, int idnum, int wrow, int wcol, int field_width, string& dest, int dest_size, int cvt, int mode); + ~field(); + + bool visible(); + + void move_left(); + void move_right(); + + bool left(); + bool right(); + bool left_word(); + bool right_word(); + bool delete_left(); + bool delete_char(); + bool delete_word(bool left); + bool insert_char(char ch); + bool overwrite_char(char ch); + bool home(); + bool end(); + + void update(); + void activate(); + void deactivate(); + + void restore(); + void commit(); + + void convert(); + bool adjust_mode(); + void conditional(); + + void move_cursor(); + void draw(int from_pos=0); + }; + + field* first_field; + field* current; + + enum { + entry_new, + entry_update, + entry_conditional, + entry_noedit + }; + + enum { + cvt_none, + cvt_lowercase, + cvt_uppercase, + cvt_mixedcase + }; + + int idle_attr; + int active_attr; + int edit_attr; + bool fill_acs; + + vchar idle_fill; + vchar active_fill; + vchar edit_fill; + + int insert_mode; + + int done; + int dropped; + + int start_id; + + bool cursor_was_hidden; + + gwindow &window; + + gwinput(gwindow &w); + virtual ~gwinput(); + + void setup(int i_attr, int a_attr, int e_attr, vchar fill, bool fill_acs); + + void add_field(int idnum, int wrow, int wcol, int field_width, string& dest, int dest_size, int cvt=gwinput::cvt_none, int mode=gwinput::entry_conditional); + + bool first(int id=0); + bool next(); + bool previous(); + bool last(); + + bool first_visible(); + bool next_visible(); + bool previous_visible(); + bool last_visible(); + + bool move_to(int wrow, int wcol); + + field* field_at(int wrow, int wcol); + field* get_field(int id); + + void draw_all(); + void reload_all(); + void show_cursor(); + + void drop_form(); + void form_complete(); + void field_complete(); + void go_next_field(); + void go_previous_field(); + void go_up(); + void go_down(); + void go_left(); + void go_right(); + void delete_left(); + void delete_char(); + void go_field_begin(); + void go_field_end(); + void go_form_begin(); + void go_form_end(); + void toggle_insert(); + void restore_field(); + void delete_left_word(); + void delete_right_word(); + void clear_to_end_field(); + void clear_to_end_form(); + void go_left_word(); + void go_right_word(); + void enter_char(char ch); + + void prepare_form(); + void finish_form(); + + bool handle_key(uint key); + + // These are supposed to be overridden by the inheriting class + virtual bool handle_other_keys(uint& key); + virtual bool validate(); + virtual void before(); + virtual void after(); +}; + + +// ------------------------------------------------------------------ + +class gwinput2 : public gwinput { + +public: + + gwinput2(gwindow &w) : gwinput(w) { } + + bool run(int helpcat); +}; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gall/gwinput2.cpp b/goldlib/gall/gwinput2.cpp new file mode 100644 index 0000000..7cc14e5 --- /dev/null +++ b/goldlib/gall/gwinput2.cpp @@ -0,0 +1,1170 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Input form and field editing. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +gwinput::gwinput(gwindow &w) : window(w) { + + first_field = current = NULL; + fill_acs = false; + idle_attr = active_attr = edit_attr = 7; + idle_fill = active_fill = edit_fill = ' '; + insert_mode = true; + done = dropped = false; + start_id = 0; +} + + +// ------------------------------------------------------------------ + +gwinput::~gwinput() { + + field* current = first_field; + if(current) { + do { + field* junk = current; + current = current->next; + delete junk; + } while(current); + } +} + + +// ------------------------------------------------------------------ + +void gwinput::setup(int i_attr, int a_attr, int e_attr, vchar fill, bool f_acs) { + + idle_attr = i_attr; + active_attr = a_attr; + edit_attr = e_attr; + fill_acs = f_acs; + active_fill = edit_fill = fill; +} + + +// ------------------------------------------------------------------ + +bool gwinput::validate() { + + return true; +} + + +// ------------------------------------------------------------------ + +void gwinput::before() { + + current->activate(); +} + + +// ------------------------------------------------------------------ + +void gwinput::after() { + + current->deactivate(); +} + + +// ------------------------------------------------------------------ + +void gwinput::add_field(int idnum, int wrow, int wcol, int field_width, string& dest, int dest_size, int cvt, int mode) { + + field* fld = new field(this, idnum, wrow, wcol, field_width, dest, dest_size, cvt, mode); + throw_new(fld); + if(current) { + current->next = fld; + fld->prev = current; + current = fld; + } + else { + first_field = current = fld; + } +} + + +// ------------------------------------------------------------------ + +bool gwinput::move_to(int wrow, int wcol) { + + field* f = field_at(wrow, wcol); + if(f) { + after(); + current = f; + before(); + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +gwinput::field* gwinput::field_at(int wrow, int wcol) { + + field* here = first_field; + do { + if(here->row == wrow) + if(in_range(wcol, here->column, here->max_column)) + return here; + here = here->next; + } while(here); + return NULL; +} + + +// ------------------------------------------------------------------ + +gwinput::field* gwinput::get_field(int id) { + + field* here = first_field; + do { + if(here->id == id) + return here; + here = here->next; + } while(here); + return NULL; +} + + +// ------------------------------------------------------------------ + +void gwinput::draw_all() { + + first(); + do { + current->draw(); + } while(next()); +} + + +// ------------------------------------------------------------------ + +void gwinput::reload_all() { + + first(); + do { + if(current->entry == gwinput::entry_new) + *current->buf = NUL; + else + strxcpy(current->buf, current->destination.c_str(), current->buf_len+1); + current->convert(); + current->buf_end_pos = strlen(current->buf); + current->draw(); + } while(next()); +} + + +// ------------------------------------------------------------------ + +bool gwinput::first_visible() { + + if(first()) { + if(not current->visible()) + if(next_visible()) + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::next_visible() { + + field* here = current; + while(here->next) { + here = here->next; + if(here->visible()) { + current = here; + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::previous_visible() { + + field* here = current; + while(here->prev) { + here = here->prev; + if(here->visible()) { + current = here; + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::last_visible() { + + if(last()) { + if(not current->visible()) + if(previous_visible()) + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::first(int id) { + + if(first_field) { + current = first_field; + if(id) + while(current->id != id) + next(); + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::next() { + + if(current->next) { + current = current->next; + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::previous() { + + if(current->prev) { + current = current->prev; + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::last() { + + if(first_field) { + current = first_field; + while(next()) + ; + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +void gwinput::show_cursor() { + + if(insert_mode) + vcursmall(); + else + vcurlarge(); +} + + +// ------------------------------------------------------------------ + +void gwinput::drop_form() { + + after(); + done = true; + dropped = true; +} + + +// ------------------------------------------------------------------ + +void gwinput::form_complete() { + + after(); + done = true; +} + + +// ------------------------------------------------------------------ + +void gwinput::field_complete() { + + if(validate()) { + after(); + if(not next_visible()) { + done = true; + return; + } + before(); + } +} + + +// ------------------------------------------------------------------ + +void gwinput::go_next_field() { + + after(); + if(not next_visible()) + first_visible(); + before(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_previous_field() { + + after(); + if(not previous_visible()) + last_visible(); + before(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_up() { + + int min_column = current->column; + int max_column = current->max_column; + int check_row = current->row - 1; + int check_column = current->column + current->pos; + for(int r=check_row; r>=0; r--) { + int c; + for(c=check_column; c<=max_column; c++) { + if(move_to(r, c)) + return; + } + for(c=check_column-1; c>=min_column; c--) { + if(move_to(r, c)) + return; + } + } +} + + +// ------------------------------------------------------------------ + +void gwinput::go_down() { + + int max_row = window.height() - (window.has_border() ? 2 : 0) - 1; + int min_column = current->column; + int max_column = current->max_column; + int check_row = current->row + 1; + int check_column = current->column + current->pos; + for(int r=check_row; r<=max_row; r++) { + int c; + for(c=check_column; c<=max_column; c++) { + if(move_to(r, c)) + return; + } + for(c=check_column-1; c>=min_column; c--) { + if(move_to(r, c)) + return; + } + } +} + + +// ------------------------------------------------------------------ + +void gwinput::go_left() { + + if(not current->left()) + go_previous_field(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_right() { + + if(not current->right()) + go_next_field(); +} + + +// ------------------------------------------------------------------ + +void gwinput::delete_left() { + + current->delete_left(); +} + + +// ------------------------------------------------------------------ + +void gwinput::delete_char() { + + current->delete_char(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_field_begin() { + + current->home(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_field_end() { + + current->end(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_form_begin() { + + after(); + first_visible(); + before(); + current->home(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_form_end() { + + after(); + last_visible(); + before(); + current->end(); +} + + +// ------------------------------------------------------------------ + +void gwinput::toggle_insert() { + + insert_mode ^= true; + show_cursor(); +} + + +// ------------------------------------------------------------------ + +void gwinput::restore_field() { + + current->restore(); +} + + +// ------------------------------------------------------------------ + +void gwinput::delete_left_word() { + + current->delete_word(true); +} + + +// ------------------------------------------------------------------ + +void gwinput::delete_right_word() { + + current->delete_word(false); +} + + +// ------------------------------------------------------------------ + +void gwinput::clear_to_end_field() { + +} + + +// ------------------------------------------------------------------ + +void gwinput::clear_to_end_form() { + +} + + +// ------------------------------------------------------------------ + +void gwinput::go_left_word() { + + current->left_word(); +} + + +// ------------------------------------------------------------------ + +void gwinput::go_right_word() { + + current->right_word(); +} + + +// ------------------------------------------------------------------ + +void gwinput::enter_char(char ch) { + + if(ch) { + if(insert_mode) + current->insert_char(ch); + else + current->overwrite_char(ch); + } +} + + +// ------------------------------------------------------------------ + +void gwinput::prepare_form() { + + cursor_was_hidden = vcurhidden(); + draw_all(); + first(start_id); + before(); + show_cursor(); +} + + +// ------------------------------------------------------------------ + +void gwinput::finish_form() { + + if(not dropped) { + first(); + do { + current->commit(); + } while(next()); + } + + if(cursor_was_hidden) + vcurhide(); +} + + +// ------------------------------------------------------------------ + +bool gwinput::handle_other_keys(uint&) { + + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::handle_key(uint key) { + + switch(key) { + case Key_Esc: drop_form(); break; + case Key_C_Ent: form_complete(); break; + case Key_Ent: field_complete(); break; + case Key_Tab: go_next_field(); break; + case Key_S_Tab: go_previous_field(); break; + case Key_Up: go_up(); break; + case Key_Dwn: go_down(); break; + case Key_Lft: go_left(); break; + case Key_Rgt: go_right(); break; + case Key_BS: delete_left(); break; + case Key_Del: delete_char(); break; + case Key_Home: go_field_begin(); break; + case Key_End: go_field_end(); break; + case Key_C_Home: go_form_begin(); break; + case Key_C_End: go_form_end(); break; + case Key_Ins: toggle_insert(); break; + case Key_C_R: restore_field(); break; + case Key_C_BS: delete_left_word(); break; + case Key_C_T: delete_right_word(); break; + case Key_C_U: clear_to_end_field(); break; + case Key_C_Y: clear_to_end_form(); break; + case Key_C_Lft: go_left_word(); break; + case Key_C_Rgt: go_right_word(); break; + default: + if(not handle_other_keys(key)) + enter_char(KCodAsc(key)); + } + + return not done; +} + + +// ------------------------------------------------------------------ + +gwinput::field::field(gwinput* iform, int idnum, int wrow, int wcol, int field_width, string& dest, int dest_size, int cvt, int mode) + + : destination(dest) + +{ + prev = next = NULL; + pos = buf_pos = buf_left_pos = 0; + + form = iform; + id = idnum; + row = wrow; + column = wcol; + max_pos = field_width - 1; + max_column = wcol + max_pos; + buf_len = dest_size - 1; + buf = new char[dest_size]; throw_new(buf); + conversion = cvt; + entry = entry_mode = mode; + attr = form->idle_attr; + fill = form->idle_fill; + fill_acs = form->fill_acs; + + if(entry == gwinput::entry_new) + *buf = NUL; + else + strxcpy(buf, dest.c_str(), dest_size); + convert(); + buf_end_pos = strlen(buf); +} + + +// ------------------------------------------------------------------ + +gwinput::field::~field() { + + delete[] buf; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::visible() { + + return max_pos != -1; +} + + +// ------------------------------------------------------------------ + +void gwinput::field::convert() { + + switch(conversion) { + case gwinput::cvt_lowercase: + strlwr(buf); + break; + case gwinput::cvt_uppercase: + strupr(buf); + break; + case gwinput::cvt_mixedcase: + struplow(buf); + break; + } +} + + +// ------------------------------------------------------------------ + +void gwinput::field::update() { + + buf_end_pos = strlen(buf); + end(); +} + + +// ------------------------------------------------------------------ + +void gwinput::field::activate() { + + buf_end_pos = strlen(buf); + entry = entry_mode; + if(entry == gwinput::entry_conditional or entry == gwinput::entry_noedit) { + attr = form->active_attr; + fill = form->active_fill; + int entry_bak = entry; + entry = gwinput::entry_update; // cheat adjust_mode() in end() + end(); + entry = entry_bak; + } + else { + // 0 == entry_new, 1 == entry_update + entry ? end() : home(); + } +} + + +// ------------------------------------------------------------------ + +void gwinput::field::deactivate() { + + fill = form->idle_fill; + attr = form->idle_attr; + draw(); +} + + +// ------------------------------------------------------------------ + +void gwinput::field::restore() { + + strxcpy(buf, destination.c_str(), buf_len+1); + convert(); + buf_end_pos = strlen(buf); + activate(); +} + + +// ------------------------------------------------------------------ + +void gwinput::field::commit() { + + destination = buf; +} + + +// ------------------------------------------------------------------ + +void gwinput::field::move_cursor() { + + form->window.move_cursor(row, column+pos); +} + + +// ------------------------------------------------------------------ + +void gwinput::field::draw(int from_pos) { + + if(visible()) + form->window.printns(row, column+from_pos, attr, buf+buf_left_pos+from_pos, 1+max_pos-from_pos, fill, attr | (fill_acs ? ACSET : 0)); +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::adjust_mode() { + + if(entry != gwinput::entry_update and entry != gwinput::entry_noedit) { + entry = gwinput::entry_update; + attr = form->edit_attr; + fill = form->edit_fill; + return true; + } + return false; +} + + +// ------------------------------------------------------------------ + +void gwinput::field::conditional() { + + if(entry == gwinput::entry_conditional) { + pos = buf_pos = buf_left_pos = buf_end_pos = 0; + *buf = NUL; + adjust_mode(); + draw(); + } +} + + +// ------------------------------------------------------------------ + +void gwinput::field::move_left() { + + buf_pos--; + if(pos > 0) { + pos--; + move_cursor(); + } + else { + buf_left_pos--; + draw(); + } +} + + +// ------------------------------------------------------------------ + +void gwinput::field::move_right() { + + buf_pos++; + if(pos < max_pos) { + pos++; + move_cursor(); + } + else { + buf_left_pos++; + draw(); + } +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::left() { + + if(adjust_mode()) + draw(); + + if(entry != gwinput::entry_noedit) { + if(buf_pos > 0) { + move_left(); + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::right() { + + if(adjust_mode()) { + draw(); + return true; + } + + if(entry != gwinput::entry_noedit) { + if(buf_pos < buf_end_pos) { + move_right(); + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::left_word() { + + if(adjust_mode()) + draw(); + + if(entry != gwinput::entry_noedit) { + if(buf_pos > 0) { + move_left(); + if(not isxalnum(buf[buf_pos])) { + while(not isxalnum(buf[buf_pos]) and (buf_pos > 0)) + move_left(); + while(isxalnum(buf[buf_pos]) and (buf_pos > 0)) + move_left(); + } + else { + while(isxalnum(buf[buf_pos]) and (buf_pos > 0)) + move_left(); + } + + if(buf_pos != 0) + move_right(); + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::right_word() { + + if(adjust_mode()) + draw(); + + if(entry != gwinput::entry_noedit) { + if(buf_pos < buf_end_pos) { + move_right(); + if(not isxalnum(buf[buf_pos])) { + while(not isxalnum(buf[buf_pos]) and ((buf_pos+1) <= buf_end_pos)) + move_right(); + } + else { + while(isxalnum(buf[buf_pos]) and ((buf_pos+1) <= buf_end_pos)) + move_right(); + while(not isxalnum(buf[buf_pos]) and ((buf_pos+1) <= buf_end_pos)) + move_right(); + } + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::delete_left() { + + if(adjust_mode()) + draw(); + + if(entry != gwinput::entry_noedit) { + if(buf_pos > 0) { + left(); + return delete_char(); + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::delete_char() { + + if(adjust_mode()) + draw(); + + if(entry != gwinput::entry_noedit) { + if(buf_pos < buf_end_pos) { + buf_end_pos--; + memmove(buf+buf_pos, buf+buf_pos+1, buf_len-buf_pos); + draw(pos); + return true; + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::delete_word(bool left) { + + if(adjust_mode()) + draw(); + + if(entry != gwinput::entry_noedit) { + + bool state = isspace(buf[buf_pos-((int) left)]); + + while(left ? buf_pos > 0 : buf_pos < buf_end_pos) { + left ? delete_left() : delete_char(); + + if(isspace(buf[buf_pos-((int) left)]) != state) + break; + } + return true; + + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::insert_char(char ch) { + + if(entry != gwinput::entry_noedit) { + + conditional(); + + if(buf_end_pos < buf_len) { + int len = buf_end_pos - buf_pos; + memmove(buf+buf_pos+1, buf+buf_pos, len+1); + buf_end_pos++; + return overwrite_char(ch); + } + } + return false; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::overwrite_char(char ch) { + + if(entry != gwinput::entry_noedit) { + + conditional(); + + switch(conversion) { + case gwinput::cvt_lowercase: + ch = (char)tolower(ch); + break; + case gwinput::cvt_uppercase: + ch = (char)toupper(ch); + break; + } + + buf[buf_pos] = ch; + if(buf_pos == buf_end_pos) { + buf_end_pos++; + buf[buf_end_pos] = NUL; + } + + if(conversion == gwinput::cvt_mixedcase) { + struplow(buf); + draw(); + } + else { + draw(pos); + } + + right(); + } + + return true; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::home() { + + adjust_mode(); + + pos = buf_pos = buf_left_pos = 0; + draw(); + move_cursor(); + return true; +} + + +// ------------------------------------------------------------------ + +bool gwinput::field::end() { + + adjust_mode(); + + buf_pos = buf_end_pos; + if(buf_pos == buf_len) + buf_pos--; + pos = minimum_of_two(max_pos, buf_pos); + buf_left_pos = buf_pos - pos; + draw(); + move_cursor(); + return true; +} + + +// ------------------------------------------------------------------ + +bool gwinput2::run(int helpcat) { + + prepare_form(); + whelppcat(helpcat); + + while(handle_key(getxch())); + + whelpop(); + finish_form(); + + return not dropped; +} + + +// ------------------------------------------------------------------ + +#if defined(TESTMAIN) + +void main() { + + enum { + FIELD_A, + FIELD_B, + FIELD_C, + FIELD_D, + FIELD_E + }; + + gwindow w; + + w.open(0, 0, gvid->numrows-1, gvid->numcols-1, 5, YELLOW|_LGREY, BLUE|_LGREY); + + w.horizontal_line(0, 0, w.width(), 0, YELLOW|_LGREY); + w.horizontal_line(5, 0, w.width(), 0, YELLOW|_LGREY); + + w.prints(1, 0, BLUE|_LGREY, " Msg : 117 of 123"); + w.prints(2, 0, BLUE|_LGREY, " From : "); + w.prints(3, 0, BLUE|_LGREY, " To : "); + w.prints(4, 0, BLUE|_LGREY, " Subj : "); + + gwinput* i = new gwinput(w); + + char str_a[128] = { "Odinn Sorensen" }; + char str_b[128] = { "2:236/77" }; + char str_c[128] = { "Who Knows" }; + char str_d[128] = { "2:236/77.123" }; + char str_e[128] = { "Testing my new input class" }; + + i->idle_attr = BLUE|_LGREY; + i->active_attr = BLACK|_LGREY; + i->edit_attr = RED|_LGREY; + + i->active_fill = '\xB0'; + i->edit_fill = '\xB0'; + i->fill_acs = true; + + i->add_field(FIELD_A, 2, 8, 35, str_a, 127); + i->add_field(FIELD_B, 2, 44, 16, str_b, 127); + i->add_field(FIELD_C, 3, 8, 35, str_c, 127); + i->add_field(FIELD_D, 3, 44, 16, str_d, 127); + i->add_field(FIELD_E, 4, 8, 71, str_e, 127); + + i->start_id = FIELD_E; + + i->prepare_form(); + + gkey key = 0; + do { + + { + // DEBUG + char buf[256]; + sprintf(buf, "bp:%i blp:%i", i->current->buf_pos, i->current->buf_left_pos); + wprintfs(gvid->numrows-1, 0, WHITE|_BLUE, " %-*s ", gvid->numcols-2, buf); + } + + key = getxch(); + } while(i->handle_key(key)); + + i->finish_form(); + + delete i; + + window.close(); + + gvid->restore_cursor(); +} + +#endif + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/Makefile b/goldlib/gcfg/Makefile new file mode 100644 index 0000000..c3b9436 --- /dev/null +++ b/goldlib/gcfg/Makefile @@ -0,0 +1,8 @@ +# -*- makefile -*- + +TOP=../.. +TARGET=gcfg +INCS=-I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg + +include $(TOP)/GNUmakef.inc +include $(TOP)/GNUmakef.lib diff --git a/goldlib/gcfg/gcfg.all b/goldlib/gcfg/gcfg.all new file mode 100644 index 0000000..ca851c8 --- /dev/null +++ b/goldlib/gcfg/gcfg.all @@ -0,0 +1,133 @@ + +// ------------------------------------------------------------------ +// The Goldware Library. Copyright (C) Odinn Sorensen. +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free +// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Master build file. +// ------------------------------------------------------------------ + + +// Msgbase area configuration. +gedacfg cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +// AREAFILE readers. +gxareas cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxcrash cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxdb cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxdutch cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxezy102 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxezy110 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxfd cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxfecho6 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxfidpcb cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxfm092 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxfm100 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxfm116 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxgecho cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxhpt cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gximail4 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gximail5 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gximail6 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxinter cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxlora cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxmax3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxme2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxopus cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxpcb cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxportal cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxprobrd cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxqfront cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxqecho cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxquick cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxra cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxraecho cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxsquish cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxsuper cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxtimed cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxtmail cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxts cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxwmail cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxwtr cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxxbbs cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gxxmail cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg + +// Msgbase area configuration. +gedacfg h all + +// AREAFILE structures. +gs_db h all +gs_ez102 h all +gs_ez110 h all +gs_fd h all +gs_fech1 h all +gs_fech2 h all +gs_fech4 h all +gs_fech5 h all +gs_fech6 h all +gs_fm092 h all +gs_fm098 h all +gs_fm10g h all +gs_fm116 h all +gs_ge100 h all +gs_ge102 h all +gs_ge110 h all +gs_ge120 h all +gs_im100 h all +gs_im120 h all +gs_im130 h all +gs_im140 h all +gs_im143 h all +gs_im150 h all +gs_im160 h all +gs_im171 h all +gs_im175 h all +gs_im185 h all +gs_im187 h all +gs_inter h all +gs_lo233 h all +gs_lo240 h all +gs_max h all +gs_max3 h all +gs_opus h all +gs_pb200 h all +gs_pcb h all +gs_pop h all +gs_qbbs h all +gs_qfrnt h all +gs_qwk h all +gs_ra h all +gs_ra2 h all +gs_recho h all +gs_sbbs h all +gs_ts h all +gs_wmail h all +gs_wtr h all +gs_xbbs h all +gs_xmail h all + +// Makefiles etc. +Makefile . all +bldbcc mak all +bldgnu mak all +bldwcc mak all +gcfg all all +ChangeLog . all + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gedacfg.cpp b/goldlib/gcfg/gedacfg.cpp new file mode 100644 index 0000000..36cb524 --- /dev/null +++ b/goldlib/gcfg/gedacfg.cpp @@ -0,0 +1,417 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// GoldED areafile helper classes. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +gareafile::gareafile() { + + *pathprefix = NUL; + + quiet = true; + + sharemode = 0; + fidomsgtype = 0; + ra2usersbbs = 0; + squishuserno = 0; + + areapath = NULL; + adeptxbbspath = NULL; + jampath = NULL; + squishuserpath = NULL; + hudsonpath = NULL; + goldbasepath = NULL; + pcboardpath = NULL; + ezycom_msgbasepath = NULL; + ezycom_userbasepath = NULL; + fidolastread = NULL; +} + + +// ------------------------------------------------------------------ + +void gareafile::adjustpath(char* path) { + + Path tmp; + if(path[1] != ':') { + strcpy(tmp, path); + strcpy(stpcpy(path, pathprefix), tmp); + } +} + + +// ------------------------------------------------------------------ + +int AreaCfg::autoid = 0; + + +// ------------------------------------------------------------------ +// Set area origin + +const char* AreaCfg::setorigin(const char* s) { + + origin = s; + AreaCfgBase::setorigin(origin); + return origin.c_str(); +} + + +// ------------------------------------------------------------------ + +EchoListClass::EchoListClass() { + + echos = 0; + descs = 0; + echolist = NULL; + desclist = NULL; +} + + +// ------------------------------------------------------------------ + +EchoListClass::~EchoListClass() { + + FreeAll(); +} + + +// ------------------------------------------------------------------ + +void EchoListClass::FreeAll() { + + int n; + + for(n=0; npath, (*b)->path)) != 0) + return(cmp); + + return(0); +} + + +// ------------------------------------------------------------------ + +void EchoListClass::SortEchos() { + + if(echolist) + qsort(echolist, echos, sizeof(EchoList*), (StdCmpCP)CmpEchos); +} + + +// ------------------------------------------------------------------ + +void EchoListClass::AddDesc(char* echoid, char* desc) { + + desclist = (DescList**)throw_reallox(desclist, (descs+1), sizeof(DescList*), 50); + desclist[descs] = (DescList*)throw_calloc(1, sizeof(DescList)); + strxcpy(desclist[descs]->echoid, echoid, sizeof(Echo)); + strxcpy(desclist[descs]->desc, desc, sizeof(Desc)); + descs++; +} + + +// ------------------------------------------------------------------ + +int EchoListClass::FindDesc(char* echoid, char** desc) { + + if(desclist) { + for(int n=0; nechoid, echoid)) { + *desc = desclist[n]->desc; + return 1; + } + } + } + return 0; +} + + +// ------------------------------------------------------------------ + +void EchoListClass::AddEcho(char* echoid, char* path, char* desc) { + + echolist = (EchoList**)throw_reallox(echolist, (echos+1), sizeof(EchoList*), 50); + echolist[echos] = (EchoList*)throw_calloc(1, sizeof(EchoList)); + strxcpy(echolist[echos]->echoid, echoid, sizeof(Echo)); + if(atoi(path)) // QBBS + sprintf(echolist[echos]->path, "%u", atoi(path)); + else if(*path == '$') // Squish + MapPath(StripBackslash(strxcpy(echolist[echos]->path, path, sizeof(Path)))+1); + else if(*path == '!') // JAM + MapPath(StripBackslash(strxcpy(echolist[echos]->path, path, sizeof(Path)))+1); + else // *.MSG + MapPath(AddBackslash(strxcpy(echolist[echos]->path, path, sizeof(Path)))); + if(desc) { + desc = strskip_wht(desc); + if(strlen(desc) >= sizeof(Desc)) { + desc[sizeof(Desc)-1] = NUL; + strtrim(desc); + } + } + else + FindDesc(echoid, &desc); + if(desc) + strxcpy(echolist[echos]->desc, desc, sizeof(Desc)); + echos++; +} + + +// ------------------------------------------------------------------ + +int EchoListClass::FindEcho(char* echoid, char* path, char* desc) { + + EchoList echokey; + EchoList* eptr; + EchoList* iptr=&echokey; + + if(echos) { + memset(iptr, 0, sizeof(EchoList)); + strxcpy(echokey.path, path, sizeof(Path)); + for(int n=0; nechoid); + if(strblank(desc)) + strcpy(desc, eptr->desc); + return(1); + } + } + } + return 0; +} + + +// ------------------------------------------------------------------ + +int EchoListClass::GetEcho(int n, char** echoid, char** path, char** desc) { + + if(echos) { + *echoid = echolist[n]->echoid; + *path = echolist[n]->path; + *desc = echolist[n]->desc; + return(1); + } + return(0); +} + + +// ------------------------------------------------------------------ +// Read AREAS.BBS (any flavor!) and store echoid, path and desc. + +void gareafile::GetAreasBBS(char* name, char* origin, char* options) { + + FILE* fp; + char buf[256]; + Path areafile; + char* ptr; + char* echoid; + char* path; + char* desc; + char* orig; + + strcpy(areafile, name); + MakePathname(areafile, areapath, areafile); + + fp = fsopen(areafile, "rt", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << areafile << endl; + + bool firstline = true; + + while(fgets(buf, 255, fp)) { + ptr = strskip_wht(buf); + if(*ptr != ';' and *ptr != '%' and *ptr != '-' and *ptr != '#' and *ptr != '@' and strnicmp(ptr, "P ", 2) and strnicmp(ptr, "PASSTHRU", 8) and *ptr) { + + // Check for comment + desc = strchr(ptr, ';'); + if(desc) { + *desc++ = NUL; + strbtrim(desc); + } + + if (firstline) { + // Check for origin + orig = strchr(ptr+1, '!'); + if(orig) { + *orig = NUL; + strcpy(origin, ptr); + continue; + } + } + + firstline = false; + + // Get echoid and path/boardno + path = ptr; + ptr = strskip_txt(ptr); + if(*ptr) { + *ptr++ = NUL; + ptr = strskip_wht(ptr); + if(*ptr) { + echoid = ptr; + ptr = strskip_txt(ptr); + *ptr++ = NUL; + ptr = strskip_wht(ptr); + if(strnieql(ptr, "JAM", 3)) + strins("!", path, 0); + echolist.AddEcho(echoid, path, desc); + } + } + } + } + fclose(fp); + } +} + + +// ------------------------------------------------------------------ + +bool gareafile::ReadAreafile(word crc, char* parameters) { + + const word CRC_ADEPTXBBS = 0x61F5; + const word CRC_AREAS_BBS = 0xBCEC; + const word CRC_AREASBBS = 0xF77C; + const word CRC_CRASHMAIL = 0x7551; + const word CRC_DBRIDGE = 0xD365; + const word CRC_DUTCHIE = 0x0B08; + const word CRC_D_BRIDGE = 0x48DA; + const word CRC_EZYCOM = 0xC81B; + const word CRC_FASTECHO = 0xF2F0; + const word CRC_FE_ABS = 0x8007; + const word CRC_FIDOCONFIG = 0x1341; + const word CRC_FIDOPCB = 0x842E; + const word CRC_FMAIL = 0xC534; + const word CRC_FRONTDOOR = 0x8A35; + const word CRC_GECHO = 0x5AEC; + const word CRC_IMAIL = 0xE905; + const word CRC_INTERMAIL = 0x08E9; + const word CRC_LORABBS = 0x04B7; + const word CRC_MAXIMUS = 0xA43B; + const word CRC_ME2 = 0xDC5B; + const word CRC_OPUS = 0x1254; + const word CRC_PARTOSS = 0x15B7; + const word CRC_PCBOARD = 0x84EC; + const word CRC_PORTAL = 0x7747; + const word CRC_PROBOARD = 0xFFC9; + const word CRC_QECHO = 0xAB2F; + const word CRC_QFRONT = 0x3320; + const word CRC_QUICKBBS = 0x21A4; + const word CRC_RAECHO = 0x701F; + const word CRC_RA_ECHO = 0x4FDF; + const word CRC_REMOTEACCESS = 0xECD0; + const word CRC_SQUISH = 0xFCF6; + const word CRC_SUPERBBS = 0x497F; + const word CRC_TERMAIL = 0x147A; + const word CRC_TIMED = 0xE977; + const word CRC_TMAIL = 0xE837; + const word CRC_TOSSCAN = 0x43DD; + const word CRC_WATERGATE = 0x3ADB; + const word CRC_WMAIL = 0xB167; + const word CRC_XMAIL = 0x9D56; + + switch(crc) { + case CRC_ADEPTXBBS: ReadAdeptXBBS(parameters); break; + case CRC_AREAS_BBS: + case CRC_AREASBBS: ReadAreasBBS(parameters); break; + case CRC_CRASHMAIL: ReadCrashmail(parameters); break; + case CRC_D_BRIDGE: + case CRC_DBRIDGE: ReadDBridge(parameters); break; + case CRC_DUTCHIE: ReadDutchie(parameters); break; + case CRC_EZYCOM: ReadEzycom(parameters); break; + case CRC_FE_ABS: + case CRC_FASTECHO: ReadFastecho(parameters); break; + case CRC_FIDOCONFIG: ReadHPT(parameters); break; + case CRC_FIDOPCB: ReadFidoPCB(parameters); break; + case CRC_FMAIL: ReadFMail(parameters); break; + case CRC_FRONTDOOR: ReadFrontDoor(parameters); break; + case CRC_GECHO: ReadGEcho(parameters); break; + case CRC_IMAIL: ReadIMail(parameters); break; + case CRC_INTERMAIL: ReadInterMail(parameters); break; + case CRC_LORABBS: ReadLoraBBS(parameters); break; + case CRC_MAXIMUS: ReadMaximus(parameters); break; + case CRC_ME2: ReadME2(parameters); break; + case CRC_OPUS: ReadOpus(parameters); break; + case CRC_PCBOARD: ReadPCBoard(parameters); break; + case CRC_PORTAL: ReadPortal(parameters); break; + case CRC_PROBOARD: ReadProBoard(parameters); break; + case CRC_QECHO: ReadQEcho(parameters); break; + case CRC_QFRONT: ReadQFront(parameters); break; + case CRC_QUICKBBS: ReadQuickBBS(parameters); break; + case CRC_RA_ECHO: + case CRC_RAECHO: ReadRaEcho(parameters); break; + case CRC_REMOTEACCESS: ReadRemoteAccess(parameters); break; + case CRC_PARTOSS: + case CRC_SQUISH: ReadSquish(parameters); break; + case CRC_SUPERBBS: ReadSuperBBS(parameters); break; + case CRC_TMAIL: + case CRC_TERMAIL: ReadTmail(parameters); break; + case CRC_TIMED: ReadTimed(parameters); break; + case CRC_TOSSCAN: ReadTosScan(parameters); break; + case CRC_WATERGATE: ReadWtrGte(parameters); break; + case CRC_WMAIL: ReadWMail(parameters); break; + case CRC_XMAIL: ReadXMail(parameters); break; + default: return false; + } + + return true; +} + + +// ------------------------------------------------------------------ + +AreaCfg& AreaCfg::operator=(const AreaCfg&) { + + return *this; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gedacfg.h b/goldlib/gcfg/gedacfg.h new file mode 100644 index 0000000..b724652 --- /dev/null +++ b/goldlib/gcfg/gedacfg.h @@ -0,0 +1,382 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AREAFILE processor. +// ------------------------------------------------------------------ + +#ifndef __gedacfg_h +#define __gedacfg_h + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +const int MAX_DESC = 45; // Area descriptions +const int MAX_ECHO = 81; // Echoids + + +// ------------------------------------------------------------------ +// Echoid typedefs + +typedef char Echo[MAX_ECHO]; + + +// ------------------------------------------------------------------ +// Description typedefs + +typedef char Desc[MAX_DESC]; + + +// ------------------------------------------------------------------ +// Area types + +const uint GMB_NET = 0x0001; +const uint GMB_EMAIL = 0x0002; +const uint GMB_ECHO = 0x0004; +const uint GMB_NEWSGROUP = 0x0008; +const uint GMB_LOCAL = 0x0010; +const uint GMB_QWK = 0x1000; +const uint GMB_SOUP = 0x2000; + + +// ------------------------------------------------------------------ +// Msgbase types + +const uint GMB_HUDSON = 0x0001; +const uint GMB_GOLDBASE = 0x0002; +const uint GMB_JAM = 0x0004; +const uint GMB_SQUISH = 0x0008; +const uint GMB_OPUS = 0x0010; +const uint GMB_FTS1 = 0x0020; +const uint GMB_FIDO = 0x0030; +const uint GMB_EZYCOM = 0x0040; +const uint GMB_PCBOARD = 0x0080; +const uint GMB_WILDCAT = 0x0100; +const uint GMB_ADEPTXBBS = 0x0200; +const uint GMB_MAILBOX = 0x1000; +const uint GMB_NEWSSPOOL = 0x2000; +const uint GMB_SEPARATOR = 0x8000; +const uint GMB_SMB = 0x10000; + + +// ------------------------------------------------------------------ + +class AreaCfgBase { + +public: + + int areaid; // Unique internal area number + int groupid; // Group id (A-Z) + int originno; // Origin number + uint board; // Board number (Hudson/Goldbase/Ezycom/PCBoard fmts) + uint type; // Type of msgarea (GMB_xxx) + uint msgbase; // Type of msgbase (GMB_xxx) + ftn_addr aka; // The AKA to use in the area + ftn_attr attr; // Default attributes + byte scan : 1; // TRUE if listed with AREASCAN + byte scanexcl : 1; // TRUE if listed with AREASCANEXCL + byte scanincl : 1; // TRUE if listed with AREASCANINCL + byte pmscan : 1; // TRUE if listed with AREAPMSCAN + byte pmscanexcl : 1; // TRUE if listed with AREAPMSCANEXCL + byte pmscanincl : 1; // TRUE if listed with AREAPMSCANINCL + + int setorigin(string& origin); + + bool isfts1() const { return !!(msgbase & GMB_FTS1); } + bool isopus() const { return !!(msgbase & GMB_OPUS); } + bool isezycom() const { return !!(msgbase & GMB_EZYCOM); } + bool isfido() const { return !!(msgbase & (GMB_FTS1|GMB_OPUS)); } + bool isgoldbase() const { return !!(msgbase & GMB_GOLDBASE); } + bool ishudson() const { return !!(msgbase & GMB_HUDSON); } + bool isjam() const { return !!(msgbase & GMB_JAM); } + bool ispcboard() const { return !!(msgbase & GMB_PCBOARD); } + bool issquish() const { return !!(msgbase & GMB_SQUISH); } + bool iswildcat() const { return !!(msgbase & GMB_WILDCAT); } + bool isadeptxbbs() const { return !!(msgbase & GMB_ADEPTXBBS); } + bool isseparator() const { return !!(msgbase & GMB_SEPARATOR); } + bool issmb() const { return !!(msgbase & GMB_SMB); } + + bool isnet() const { return !!(type & GMB_NET); } + bool isecho() const { return !!(type & GMB_ECHO); } + bool islocal() const { return !!(type & GMB_LOCAL); } + bool isemail() const { return !!(type & GMB_EMAIL); } + bool isnewsgroup() const { return !!(type & GMB_NEWSGROUP); } + bool isinternet() const { return !!(type & (GMB_EMAIL|GMB_NEWSGROUP)); } + bool isqwk() const { return !!(type & GMB_QWK); } + bool issoup() const { return !!(type & GMB_SOUP); } + +}; + + +// ------------------------------------------------------------------ + +class AreaCfg : public AreaCfgBase { + +public: + + static int autoid; + + Echo echoid; // Echo tag + Desc desc; // Area description + Path path; // Path to message area + string origin; // Origin + + AreaCfg() { reset(); } + ~AreaCfg() { } + + AreaCfg& operator=(const AreaCfg& x); + + void reset(); + + const char* setdesc(const char* s); + const char* setautoid(const char* s); + const char* setechoid(const char* s); + const char* setorigin(const char* s); + const char* setpath(const char* s); +}; + + +// ------------------------------------------------------------------ + +struct EchoList { + + Echo echoid; + Path path; + Desc desc; +}; + + +// ------------------------------------------------------------------ + +struct DescList { + + Echo echoid; + Desc desc; +}; + + +// ------------------------------------------------------------------ + +class EchoListClass { + +private: + + EchoList** echolist; + DescList** desclist; + int echos; + int descs; + +public: + + EchoListClass(); + ~EchoListClass(); + + void FreeAll(); + int Echos() { return(echos); } + void SortEchos(); + void AddDesc(char* echoid, char* desc); + int FindDesc(char* echoid, char** desc); + void AddEcho(char* echoid, char* path, char* desc); + int FindEcho(char* echoid, char* path, char* desc); + int GetEcho(int n, char** echoid, char** path, char** desc); +}; + + +// ------------------------------------------------------------------ + +class gareafile { + +protected: + + Path pathprefix; + + // Fidoconfig parser functions + void replace_slashes(char **key); + void gettok(char** key, char** val); + // Crashmail II parser function + bool jbstrcpy(char *dest, char *src, size_t maxlen, size_t *jbc); + // Timed parser function + void nullastbackslash(char* val); + // Watergate parser function + uint gettype(uint msgtype, const byte wtrtype); + // XMail parser function + char* ClipDosFilename(char* __file); + + void adjustpath(char* path); + + void ReadDB130(char* tag, char* dbpath); + void ReadDB1046(char* file, char* tag); + void ReadDB1047A22(char* file, int reclen, char* tag); + void ReadDB2011(char* file, int reclen, char* tag); + void ReadEzycom102(FILE* fp, char* path, char* file, char* options); + void ReadEzycom110(FILE* fp, char* path, char* file, char* options); + void ReadFastecho142(int fh); + void ReadFMail092(FILE* fp, char* path, char* file, char* options); + void ReadFMail098(FILE* fp, char* path, char* file, char* options); + void ReadFMail116(FILE* fp, char* path, char* file, char* options); + bool ReadHPTLine(FILE* f, string* s, bool add=false, int state=0); + void ReadHPTFile(char* path, char* file, char* options, char* origin, int group); + void ReadIMail160(char* options, char* file, char* impath); + void ReadIMail170(char* options, char* file, char* impath); + void ReadIMail185(char* options, char* file, char* impath); + void ReadMaximus3(char* mxpath, char* areafile, char* options); + void ReadQ260(char* qbpath, char* origin, char* options); + void ReadQ276(char* qbpath, char* origin, char* options); + void ReadQEchoFile(char* file, char* options, char* origin); + void ReadSquishFile(char* path, char* file, char* options, char* origin, int group); + void ReadTimedFile(char* path, char* file, char* options, char* origin); + void ReadTmailFile(char* file, char* options, char* origin); + void ReadWtrGteFile(char* options, FILE* fp); + void ReadAdeptXbbsFile(char* path, char* file, char* options); + void ReadxMailFile(char* file, char* options); + +public: + + gareafile(); + + EchoListClass echolist; + + int quiet; + + int sharemode; + int fidomsgtype; + int ra2usersbbs; + int squishuserno; + + ftn_addr primary_aka; + + ftn_attr attribsnet; + ftn_attr attribsecho; + ftn_attr attribsnews; + ftn_attr attribsemail; + ftn_attr attribslocal; + + char* areapath; + char* adeptxbbspath; + char* jampath; + char* squishuserpath; + char* hudsonpath; + char* goldbasepath; + char* pcboardpath; + char* ezycom_msgbasepath; + char* ezycom_userbasepath; + char* fidolastread; + + void GetAreasBBS(char* name, char* origin, char* options); + + void ReadAreasBBS(char* tag); + void ReadAdeptXBBS(char* tag); + void ReadCrashmail(char* tag); + void ReadDBridge(char* tag); + void ReadDutchie(char* tag); + void ReadEzycom(char* tag); + void ReadFastecho(char* tag); + void ReadFidoPCB(char* tag); + void ReadFMail(char* tag); + void ReadFrontDoor(char* tag); + void ReadGEcho(char* tag); + void ReadHPT(char* tag); + void ReadIMail(char* tag); + void ReadInterMail(char* tag); + void ReadLoraBBS(char* tag); + void ReadMaximus(char* tag); + void ReadME2(char* tag); + void ReadOpus(char* tag); + void ReadPCBoard(char* tag); + void ReadPortal(char* tag); + void ReadProBoard(char* tag); + void ReadQEcho(char* tag); + void ReadQFront(char* tag); + void ReadQuickBBS(char* tag); + void ReadRaEcho(char* tag); + void ReadRemoteAccess(char* tag); + void ReadSquish(char* tag); + void ReadSuperBBS(char* tag); + void ReadTimed(char* tag); + void ReadTmail(char* tag); + void ReadTosScan(char* tag); + void ReadWMail(char* tag); + void ReadWtrGte(char* tag); + void ReadXMail(char* tag); + + bool ReadAreafile(word crc, char* parameters); +}; + + +// ------------------------------------------------------------------ + +void AddNewArea(AreaCfg& aa); +void CfgAddress(char* value); +void CfgOrigin(const char* value); +void CfgUsername(char* value); +void ReadEcholist(char* value); +void SetAreaDesc(char* echoid, char* desc); + + +// ------------------------------------------------------------------ +// Legacy area types + +const uint AT_NET = GMB_NET; +const uint AT_EMAIL = GMB_EMAIL; +const uint AT_ECHO = GMB_ECHO; +const uint AT_NEWSGROUP = GMB_NEWSGROUP; +const uint AT_LOCAL = GMB_LOCAL; +const uint AT_QWK = GMB_QWK; +const uint AT_SOUP = GMB_SOUP; + + +// ------------------------------------------------------------------ +// Legacy msgbase types + +const uint MT_HUDSON = GMB_HUDSON; +const uint MT_GOLDBASE = GMB_GOLDBASE; +const uint MT_JAM = GMB_JAM; +const uint MT_SQUISH = GMB_SQUISH; +const uint MT_OPUS = GMB_OPUS; +const uint MT_FTS1 = GMB_FTS1; +const uint MT_FIDO = GMB_FIDO; +const uint MT_EZYCOM = GMB_EZYCOM; +const uint MT_PCBOARD = GMB_PCBOARD; +const uint MT_WILDCAT = GMB_WILDCAT; +const uint MT_ADEPTXBBS = GMB_ADEPTXBBS; +const uint MT_MAILBOX = GMB_MAILBOX; +const uint MT_NEWSSPOOL = GMB_NEWSSPOOL; +const uint MT_SEPARATOR = GMB_SEPARATOR; +const uint MT_SMB = GMB_SMB; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_db.h b/goldlib/gcfg/gs_db.h new file mode 100644 index 0000000..68cc306 --- /dev/null +++ b/goldlib/gcfg/gs_db.h @@ -0,0 +1,203 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gs_db_h +#define __gs_db_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// D'Bridge 1.30 structs + +typedef struct { + byte allocated; + char tag[17]; + char echoid[57]; +} DB130_AA1; + +typedef struct { + char desc[41]; + short group; + char msgbase; + char path[49]; + char kind; + short board; + byte ispvt; + byte tinyseenbys; + char origin[57]; + char defaultpriority; + ftn_addr addr; + short purge; + short preserve; + short security; + char archive[57]; + char forwardto[5][57]; +} DB130_AA2; + + +// ------------------------------------------------------------------ +// D'Bridge 1.30+ QBBS lastread records + +typedef struct { + char name[37]; + struct { + word msgno; + word index; + } lastread[200]; +} DB130_LRQ; + + +// ------------------------------------------------------------------ +// D'Bridge B1046 DBRIDGE.ADF struct + +typedef struct { + byte allocated; // 000 + char tag[17]; // 001 + char echoid[57]; // 018 + char desc[41]; // 075 + short group; // 116 + char msgbase; // 118 + char path[49]; // 119 + char kind; // 168 + short board; // 169 + byte ispvt; // 171 + byte tinyseenbys; // 172 + char origin[57]; // 173 + char defaultpriority; // 230 + ftn_addr addr; // 231 + short purge; + short preserve; + short security; + char archive[57]; + char forwardto[5][57]; +} DB1046_ADF; // 587 bytes + + +// ------------------------------------------------------------------ +// D'Bridge B1047.A22 DBRIDGE.ADF struct + +typedef struct { + byte allocated; // 000 + char alertflag; // 001 + char tag[17]; // 002 + char echoid[57]; // 019 + char desc[41]; // 076 + short group; // 117 + char msgbase; // 119 + char path[49]; // 120 + char kind; // 169 + short board; // 170 + byte ispvt; // 172 + char tinyseenbys; // 173 + char origin[57]; // 174 + char defaultpriority; // 231 + ftn_addr addr; // 232 + byte fill[18]; + short purge; + short preserve; + short security; + char archive[57]; + char forwardto[5][57]; +} DB1047A22_ADF; // 606 bytes + + +// ------------------------------------------------------------------ +// D'Bridge B1047.A27+ DBRIDGE.ADF struct + +typedef struct { + byte allocated; // 000 + char alertflag; // 001 + char tag[17]; // 002 + char echoid[57]; // 019 + char desc[41]; // 076 + short group; // 117 + char msgbase; // 119 + char path[49]; // 120 + char kind; // 169 + short board; // 170 + byte ispvt; // 172 + char tinyseenbys; // 173 + char origin[57]; // 174 + char defaultpriority; // 231 + ftn_addr addr; // 232 + byte fill[13]; // 240 + short purge; // 253 + short preserve; // 255 + short security; // 257 + char archive[57]; // 259 + char forwardto[5][57]; // 316 +} DB1047A27_ADF; // 601 bytes + + +// ------------------------------------------------------------------ +// D'Bridge B2011+ DBRIDGE.ADF struct + +typedef struct { + byte allocated; // 000 + char alertflag; // 001 + char tag[17]; // 002 + char echoid[57]; // 019 + char desc[41]; // 076 + short group; // 117 + char msgbase; // 119 + char path[49]; // 120 + char kind; // 169 + short board; // 170 + byte ispvt; // 172 + char tinyseenbys; // 173 + char origin[57]; // 174 + char defaultpriority; // 231 + ftn_addr addr; // 232 + byte fill[13]; // 240 + short purge; // 253 + short preserve; // 255 + short security; // 257 + char archive[57]; // 259 + char forwardto[19][77]; // 316 +} DB2011_ADF; // 1779 bytes + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_ez102.h b/goldlib/gcfg/gs_ez102.h new file mode 100644 index 0000000..28ad48d --- /dev/null +++ b/goldlib/gcfg/gs_ez102.h @@ -0,0 +1,500 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1992-1994 Peter Davies +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gs_ez102_h +#define __gs_ez102_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// EzyCom structures converted to C format V1.02 9/9/92 +// by Peter Davies and Ron Clark +// Based on original C Structures for Ezycom V1.00 by Colin Berg +// +// These structures may ONLY be used in accordance with those +// agreements laid out in the Official Ezycom Structures. +// Peter Davies or Ron Clark takes no responsibility whatsoever +// for the correctness of these structures. + +#define EZYVER "1.02" +#define VERSIONHIGH 1 +#define VERSIONLOW 2 +#define MAXFREE 685 +#define USERFREE 4 +#define CONSTANTFREESPACE 89 +#define CONSTANTFILEFREESPACE 816 +#define MAXNODES 128 +#define MAXAKA 16 +#define MAXMESS 1024 +#define MAXMESSALL 1024 +#define MAXBAUDREC 11 + +typedef char AskType; // 0=yes, 1=no, 2=ask +typedef char MsgType; // 0=localmail, 1=netmail, 2=echomail, 3=passthru, 4=waitthru, 5=allmail +typedef char MsgKindsType; // 0=public, 1=private, 2=private or public +typedef char UserString[36]; +typedef unsigned char EzFlagType[4]; + + +// ------------------------------------------------------------------ +// CONFIG. structure +// +// unknownarea = 0 - kill messages +// 1 - make a new echomail area +// 2 - make a new passthru area +// +// tossattr2 = bit 0 - [ reserved ] +// 1 - [ reserved ] +// 2 - kill bad archives +// 3 - arcmail 0.6 compat +// +// autodetect = bit 0 - Auto Detect ANSI +// 1 - Ansi Detect for New User +// 2 - Auto Detect EMSI +// 3 - Auto Detect EMSI & for newuser +// +// tossattr = bit 0 : [reserved] +// 1 : [reserved] +// 2 : [reserved] +// 3 : dupe detection +// 4 : delete netmail on import +// 5 : keep echoarea node receipts +// 6 : allow message rescan +// 7 : [reserved] +// +// multitasker = 0 = do not detect or use any multitasker +// 1 = auto-detect +// 2 = desqview (or compatiable) +// 3 = double dos +// 4 = OS.2 +// 5 = multidos plus +// 6 = Taskview +// 7 = Topview +// 8 = PC MOS +// 9..255 [reserved] +// +// printerport = 0 = LPT1 +// 1 = LPT2 +// 2 = LPT3 +// 3 = COM1 +// 4 = COM2 +// 5 = COM3 +// 6 = COM4 + +typedef struct CONFIGRECORD { + char version[9], + deflanguage[9], + freespace50[68], + logpath[61], + textpath[61], + menupath[61], + mnurampath[61], + netmailpath[61], + nodelistpath[61], + msgpath[61], + filepath[61], + freespace51[61], + bipath[61], + temppath[61], + userbasepath[61], + avatarpath[61], + ascpath[61], + asclowpath[61], + filemaint[61], + fileattachpath[61], + soundpath[61], + fastindexpath[61], + systempwd[16], // Password to Logon System + sysoppwd[16], // Password to Keyboard + newuserpwd[16], // Password for Newuser + newtopmenu[9], // NewUser TopMenu + freespace52[4], + inboundmail[61], + outboundmail[61], + uploadpath[61], + swapfile[61], + multipath[61], + brackets[3], + inactivitytime, + minmesscheck, + maxlogintime, + /* unused */ freespace53, + answerdelay; + char shellswap, + highbit, + disppass, + asklocalpass, + fastlogon, + sysopremote, + printerlog, + phone1ask, + colourask, + aliasask, + dobask, + phoneforce, + direct_video, + snow_check; + char freespace54; + char screen_blank; + char oneword; + AskType checkmail, + checkfile, + ansiask, + fullscreenask, + clearask, + moreask, + avatarask, + extendask, + usdateask; + char phone2ask, + phoneformat[15], + nameprompt[61], + pwdprompt[61], + shellprompt[61], + shell2prompt[61], + enterprompt[61], + chatprompt[61], + listprompt[61]; + char f7keylinetop[80], + f7keylinebot[80], + freespace55[84], + chat2prompt[61], + screenlengthprompt[61], + screenclearprompt[61], + locationprompt[61], + freeprompt[61], + loadprompt[61], + avatarprompt[61], + aliasprompt[61]; + word security, + logonsecurity; + EzFlagType flags; + char minpasslength, + /* constant */ dispfwind, // Status Bar Colour + /* constant */ dispbwind, // Status Bar Colour + /* constant */ disppopupf, // Popup Forground + /* constant */ disppopupborder, // Popup Border + /* constant */ disppopupb, // Popup Background + /* constant */ dispf; // Foreground Colour + char freespace56, + comport, + passlogons, + doblogon, + printerport, + passtries; + char topmenu[9]; + char freespace100[4]; + word watchmess, + /* constant */ netmailcredit, + ansiminbaud, + /* unused */ freespace57, + slowbaud, + minloginbaud, + lowsecuritystart, + lowsecurityend, + slowstart, + slowend; + char quotestring[6], + freespace58, + offhook; + word forcecrashmail, + optioncrashmail, + netmailfileattach; + char popuphighlight, + freespace59, + maxpages, + maxpagefiles, + pagelength; + word pagestart[7], + /* constant */ pagemessboard, // Message Board for Paging (0=Not In Use) + localfattachsec, + sectouploadmess, + sectoupdateusers, + readsecnewecho, + writesecnewecho, + sysopsecnewecho; + word secreplyvianetmail; + AskType netmailkillsent; + char swaponarchive; + + char freespace60[9]; + + char popuptext; + word pageend[7]; + char freespace61[22]; + word incomingcallstart, + incomingcallend, + + /* unused */ freespace62; + + char altf[10][61], + ctrlf[10][41], + /* unused */ freespace63[4]; + word fp_credit; // Newuser Filepoints + char ks_per_fp, // Number of Kilobytes per FP + fp_upload, // Filepoints Upload Credit + rego_warn_1, + rego_warn_2; + char freespace64[2]; + word min_space_1; + char swapbimodem, + modembusy, // Toggle DTR or ATH1 + scrheight, // 43/50 line mode + msgtmptype, // True = MSGTMP False = MSGTMP. + swapupload; + char phonelogon, + carrierdetect; // Carrier Detect (Default=$80) + char newfileshighlight; + char max_descrip, + min_descrip; + word requestreceipt; + char ushowdate; + char ufilesizek; + char uuploader, + udownloadcount, + /* unused */ freespace4, + ushowsecurity, + sshowdate; + char sfilesizek; + char suploader, + sdownloadcount, + /* unused */ freespace5, + sshowsecurity, + ushowtime, + ushowfp, + sshowtime, + sshowfp; + word fp_percent; // Download Filepoints Credit + char autodetect; + char dispsecurityfile, + askforpagereason, + delincompletefiles; + char freespace65; + char swaponfeditview; + char freespace6, + secfileschar, + passchar; + char localinactivity; + char conversiononmaster; + char leftbracket[2], + rightbracket[2]; + word ignorefp; // Min Security to Ignore FPs + char menuminage; // Minimum Age for Age Checks + char freespace66; + word modemeff[MAXBAUDREC], + modembaud[MAXBAUDREC]; + char modemconnect[MAXBAUDREC][16]; + char freespace67[10]; + word configattr; // bit 0: Move Local Uploads, other reserved + char usercol1_2, + usercol3_4, + usercol5_6, + usercol7_8, + userbkcol, + newusercol2, + chstatcol, + getentercol; + char usdateforsysop, + ezyovrpath[61]; + UserString sysfree3; + char ovrems; + char swapezy, + filesecpath[61]; + char freespace28; + char multitasker; + word maxbaud; // longint in 1.02 + char lockedport; + word filereqsec; + char autoanswer, + initresponse[11], + ringstring[11]; + char inittries, + initstring1[61], + initstring2[61], + busystring[21], + answerstring[21], + mailerstring[61]; + word modemstart, + modemend; + char modemdelay; + char sendbreak; + char externaleditor[61], + defaultorigin[51], + connectfax[16]; + char freespace22[16]; + word uploadcredit; + char sysfree4[36]; + char shownewfileschar; + word + /* unused */ zonea[16], + neta[16], + nodea[16], + pointa[16], + /* unused */ freespace24[16]; + char freespace9[16][21], + nocarrierstring[21]; + UserString guestaccount; + char freespace[MAXFREE]; +} CONFIGRECORD; + + +// ------------------------------------------------------------------ +// CONSTANT.EZY record structure +// +// scantossattr = bit 0 : Dupe Detection +// 1 : Kill Null Netmail +// 2 : Keep EchoArea Node Receipts +// 3 : Import Messages To Sysop +// 4 : Route Mail (Off = Direct) +// 5 : Kill Bad Archives +// 6 : ARCMail 0.6 Compatability +// 7-15 : [Reserved] +// +// constantattr = bit 0 : Sysop Alias in Chat +// 1 : Auto Log Chat +// 2 : Display Full Message To User +// 3 : Do not delete outbound mail bundles with no .MSG +// 4-15 : [Reserved] +// +// unknownarea = 0 : Kill Messages +// 1 : Make a New EchoMail Area +// 2 : Make a New PassThru Area + +typedef struct CONSTANTRECORD { + + char version[9]; + char system[41]; + UserString sysopname, + sysopalias; + char systemlocation[36]; + char multiline; + word maxmess, // maximum usable message areas + maxfile; // maximum usable file areas + word watchmess, // watchdog message board + pagemessboard, // paging message board + badpwdmsgboard; // bad pwd message board + char mintimeforcall; // minimum time to register call + char freespace2[11]; + word scantossattr, + constantattr; + word maxmsgsrescan; // maximum msgs to rescan (0=disable) + char qwkfilename[9]; + word qwkmaxmail, + qwkmsgboard; + ftn_addr netaddress[MAXAKA]; + word netmailboard[MAXAKA]; + char newareagroup[MAXAKA]; + word newareastmess[MAXAKA]; + char quotestring[6]; + char swaponezymail; + char unknownarea; + char swaponfeditview, + swaponarchive; + word minspaceupload; + char textinputcolour; + word badmsgboard; + char freespace[CONSTANTFREESPACE]; +} CONSTANTRECORD; + + +// ------------------------------------------------------------------ +// MESSAGES.EZY record structure +// +// attribute = bit 0 : allow aliases +// 1 : use alias +// 2 : use alias, ask for aliases +// 3 : test age as defined in config.xx +// 4 : combined area access +// 5 : local file attaches +// 6 : strip private bit on incoming echomail +// 7 : security +// +// attribute2 = bit 0 : show seenby lines +// 1 : forced mail check +// 2 : strip forward seenbys +// 3..4 : [reserved] +// 5 : areafix info visible +// 6 : initial combined area access +// 7 : Do Not use in Template +// +// attribute3 = [Reserved] +// +// destnode = nodes 1 to 8 - destnode[1] +// nodes 9 to 16 - destnode[2] +// nodes 17 to 24 - destnode[3] +// etc, etc, etc. + +typedef struct MESSAGERECORD { + char name[31]; + char areatag[31]; + char qwkname[13]; + MsgType typ; + MsgKindsType msgkinds; + char attribute, + attribute2, + attribute3; + char dayskill, + recvkill; + word countkill, + kilobytekill, + readsecurity; + EzFlagType readflags; + word writesecurity; + EzFlagType writeflags; + word sysopsecurity; + EzFlagType sysopflags; + char originline[51]; + char originaddress; + char seenby[MAXAKA/8]; + char areagroup, + messgroup; + char destnodes[MAXNODES/8]; + char echomailfeed; // 0=No Uplink +} MESSAGERECORD; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_ez110.h b/goldlib/gcfg/gs_ez110.h new file mode 100644 index 0000000..d8319ff --- /dev/null +++ b/goldlib/gcfg/gs_ez110.h @@ -0,0 +1,515 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1992-1994 Peter Davies +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gs_ez110_h +#define __gs_ez110_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// EzyCom structures converted to C format V1.10 6/3/94 +// by Peter Davies and Ron Clark +// +// These structures may ONLY be used in accordance with those +// agreements laid out in the Official Ezycom Structures. +// Peter Davies or Ron Clark takes no responsibility whatsoever +// for the correctness of these structures. + +#define EZYVER "1.10" +#define VERSIONHIGH 1 +#define VERSIONLOW 10 +#define MAXFREE 1238 +#define USERFREE 125 +#define CONSTANTFREESPACE 89 +#define CONSTANTFILEFREESPACE 537 +#define MAXNODES 128 +#define MAXAKA 32 +#define MAXMESS 1536 +#define MAXMESSALL 1536 +#define MAXBAUDREC 11 + +typedef byte AskType; // 0=yes,1=no,2=ask default yes,3=ask default no +typedef byte MsgType; // 0=local,1=net,2=echo,3=passthru,4=waitthru,5=allmail +typedef byte MsgKindsType; // 0=public,1=private,2=both +typedef byte ShowFileSizeType; // 0=nosize,1=bytes,2=kilobytes +typedef char UserString[36]; +typedef byte Str8[9]; +typedef byte EzFlagType[4]; + +typedef struct SECURITYTYPE { + + word security; + EzFlagType onflags, + offflags; +} SECURITYTYPE; + + +// ------------------------------------------------------------------ +// CONFIG.EZY Configuration Record +// +// printerport = +// 0 : LPT1 +// 1 : LPT2 +// 2 : LPT3 +// 3 : COM1 +// 4 : COM2 +// 5 : COM3 +// 6 : COM4 +// +// autodetect = bit +// 0 : Auto Detect ANSI +// 1 : ANSI Detect for NewUser +// 2 : Auto Detect IEMSI +// 3 : IEMSI Detect for NewUser +// 4 : Auto Detect RIP +// 5-7 : [Reserved] +// +// configattr = bit +// 0 : Move Local Uploads +// 1-15 : [Reserved] +// +// multitasker = +// 0 = Do Not Detect or Use Any MultiTasker +// 1 = Auto-Detect +// 2 = Desqview +// 3 = Double DOS +// 4 = OS/2 +// 5 = MultiDOS Plus +// 6 = Taskview +// 7 = Topview +// 8 = Windows Enhanced Mode +// 9..255 = [Reserved] +// +// shownewfileschar +// 0 - No +// 1 - ASCII Only +// 2 - Always + +typedef struct CONFIGRECORD { + Str8 version, + deflanguage; + byte nocarrierstring[21]; + UserString guestaccount; + char freespace01[11], // unused + logpath[61], + textpath[61], + menupath[61], + mnurampath[61], + netmailpath[61], + nodelistpath[61], + msgpath[61], + filepath[61], + freespace02[61], // unused + binkleyoutpath[61], + temppath[61], + userbasepath[61], + avatarpath[61], + ascpath[61], + asclowpath[61], + filemaint[61], + fileattachpath[61], + soundpath[61], + fastindexpath[61], + systempwd[16], // Password to Logon System + sysoppwd[16], // Password to Keyboard + newuserpwd[16]; // Password for Newuser + Str8 newtopmenu; // NewUser TopMenu + byte newusergroups[4], + inboundmail[61], + outboundmail[61], + uploadpath[61], + swapfile[61], + multipath[61], + brackets[3], + inactivitytime, + minmesscheck, + maxlogintime, + freespace03, // unused + answerdelay, // BOOLEAN + shellswap, // " + highbit, // " + disppass, // " + asklocalpass, // " + fastlogon, // " + sysopremote, // " + printerlog, // " + phone1ask, // " + colourask, // " + aliasask, // " + dobask, // " + phoneforce, // " + direct_video, // " + snow_check, // " + freespace04, // unused + screen_blank, + oneword; // BOOLEAN + AskType checkmail, + checkfile, + ansiask, + fullscreenask, + clearask, + moreask, + avatarask, + extendask, + usdateask; + byte phone2ask, // BOOLEAN + phoneformat[15], + freespace04a[61], + freespace04b[61], + shellprompt[61], + shell2prompt[61], + enterprompt[61], + chatprompt[61], + listprompt[61], + f7keylinetop[80], + f7keylinebot[80], + freespace05[84], // unused + chat2prompt[61], + freespace05a[61], + freespace05b[61], + freespace05c[61], + freespace05d[61], + loadprompt[61], + freespace05e[61], + freespace05f[61]; + word security, + logonsecurity; + EzFlagType flags; + byte minpasslength, + dispfwind, // Status Bar Colour constant + dispbwind, // Status Bar Colour " + disppopupf, // Popup Forground " + disppopupborder, // Popup Border " + disppopupb, // Popup Background " + dispf, // Foreground Colour " + freespace06, // Unused + comport, + passlogons, + doblogon, + printerport, + passtries, + topmenu[9], + freespace07[4]; // Unused + word watchmess, // constant + netmailcredit; // constant + long ansiminbaud; + word slowbaud, + minloginbaud, + lowsecuritystart, + lowsecurityend, + slowstart, + slowend; + byte quotestring[6], + freespace09, // Unused + offhook; // BOOLEAN + word forcecrashmail, + optioncrashmail, + netmailfileattach; + byte popuphighlight, // Popup Highlight Colour (constant) + freespace10, // Unused + maxpages, + maxpagefiles, + pagelength; + word pagestart[7], + freespace50, // Unused + localfattachsec, + sectouploadmess, + sectoupdateusers, + readsecnewecho, + writesecnewecho, + sysopsecnewecho, + secreplyvianetmail; + AskType netmailkillsent; + byte swaponarchive, + freespace11[9], // Unused + popuptext; // Popup Text Colour (constant) + word pageend[7]; + byte freespace12[22]; // Unused + word incomingcallstart, + incomingcallend, + fp_upload; // File Points Upload Credit + byte altf[10][61], + ctrlf[10][41], + freespace13[4]; + word fp_credit; // Newuser Filepoints + byte ks_per_fp, // Number of Kilobytes per FP + freespace14, // unused + rego_warn_1, + rego_warn_2, + freespace15[2]; // Unused + word min_space_1; // constant + byte swapbimodem, // boolean + modembusy, // boolean (* Toggle DTR or ATH1 *) + scrheight, // boolean (* 43/50 line mode *) + msgtmptype, // boolean (True=MSGTMP False=MSGTMP.) + swapupload, // boolean + phonelogon, + carrierdetect, // (* Carrier Detect (Default=$80) *) + newfileshighlight, // boolean; + max_descrip, + min_descrip; + word requestreceipt; + byte ushowdate; // boolean + ShowFileSizeType ufilesizek; + byte uuploader, // boolean + udownloadcount, // boolean + freespace16, // unused + ushowsecurity, // boolean + sshowdate; // boolean + ShowFileSizeType sfilesizek; + byte suploader, // boolean + sdownloadcount, // boolean + freespace17, // Unused + sshowsecurity, // boolean + ushowtime, // boolean + ushowfp, // boolean + sshowtime, // boolean + sshowfp; // boolean + word fp_percent; // Download Filepoints Credit + byte autodetect, + dispsecurityfile, // boolean + askforpagereason, // boolean + delincompletefiles, // boolean + freespace18, // unused + swaponfeditview, // constant + freespace19, // unused + secfileschar, + passchar; + byte localinactivity, // boolean + freespace20, // unused + leftbracket[2], + rightbracket[2]; + word ignorefp; // Min Security to Ignore FPs + byte menuminage, // Minimum Age for Age Checks + freespace21; // unused + word modemeff[MAXBAUDREC], + modembaud[MAXBAUDREC]; + byte modemconnect[MAXBAUDREC][16], + freespace22[10]; // unused + word configattr; + byte usercol1_2, + usercol3_4, + usercol5_6, + usercol7_8, + userbkcol, + newusercol2, + chstatcol, + getentercol, + usdateforsysop, // boolean + ezyovrpath[61], + freespace23[36], + ovrems, // boolean; + swapezy, + filesecpath[61], + freespace24, // unused + multitasker; + word oldmaxbaud; + byte lockedport; + word filereqsec; + byte autoanswer, // boolean + initresponse[11], + ringstring[11], + inittries, + initstring1[61], + initstring2[61], + busystring[21], + answerstring[21], + mailerstring[61]; + word modemstart, + modemend; + byte modemdelay, + sendbreak, // boolean; + externaleditor[61]; + char defaultorigin[51], + connectfax[16]; + long maxbaud; + byte freespace25[12]; + word uploadcredit; // Upload Credit Percentage + byte freespace26[36], + shownewfileschar; + byte freespace[MAXFREE]; +} CONFIGRECORD; + + +// ------------------------------------------------------------------ +// CONSTANT.EZY Constant Configuration Information +// +// The four following definitions +// constantrecord +// compressrecord +// domaintype +// constantfilefreespacetype +// make up the complete CONSTANT.EZY file +// As shown in "constantfilerecord" +// +// scantossattr = bit +// 0 : Dupe Detection +// 1 : Kill Null Netmail +// 2 : Keep EchoArea Node Receipts +// 3 : Import Messages to Sysop +// 4 : Binkley Support +// 5 : Kill Bad Archives +// 6 : ArcMail 0.6 Compatability +// 7 : Binkley 5D Support +// 8-15 : [Reserved] +// +// constantattr = bit +// 0 : Sysop Alias in Chat +// 1 : Auto Log Chat +// 2 : Display Full Message to User +// 3 : Do not delete outbound mail bundles with no .MSG +// 4 : On means do not use real name kludge line +// 5 : User can write messages to user of same name +// 6 : Users receive QWK messages that they posted +// 7 : Show Sysop Online +// 8 : Make Binkley Crash, Hold, etc +// 9 : Show Colour in File Areas +// 10-15 : [Reserved] +// +// unknownarea = +// 0 : Kill Messages +// 1 : Make a New EchoMail Area +// 2 : Make a New PassThru Area + +typedef struct CONSTANTRECORD { + byte version[9], + system[41]; + UserString sysopname, + sysopalias; + byte systemlocation[36], + multiline; // boolean, multiline operation + word maxmess, // maximum usable message areas + maxfile, // maximum usable file areas + watchmess, // watchdog message area + pagemessboard, // paging message board + badpwdmsgboard; // bad logon message board + byte mintimeforcall, // minimum time to register call today + freespace2[11]; + word scantossattr, // ezymail scan/toss info + constantattr, + maxmsgsrescan; // Maximum msgs to rescan (0=disable) + Str8 qwkfilename; // Unique QWK Mail filename + word qwkmaxmail, // Maximum Msgs for QWK archive + qwkmsgboard; // Bad QWK Message Board + ftn_addr oldnetaddress[16]; + word oldnetmailboard[16]; + byte oldnewareagroup[16]; + word oldnewareastmess[16]; // New area start msg board + byte quotestring[6], // quote messsage string + swaponezymail, // ezymail swapping information + unknownarea, // unknown new area tag action + swaponfeditview, // FEdit swapping information + swaponarchive; // Ezymaint swapping information + word minspaceupload; // minimum space to upload + byte textinputcolour; // default text input colour + word badmsgboard; // Bad echomail msg board + ftn_addr netaddress[MAXAKA]; + word netmailboard[MAXAKA]; + char newareagroup[MAXAKA]; + word newareastmess[MAXAKA]; // New area start msg board + byte domain[21][MAXAKA]; + byte freespace[CONSTANTFREESPACE]; +} CONSTANTRECORD; + + +// ------------------------------------------------------------------ +// MESSAGES.EZY: Used by Ezycom to store message areas +// +// attribute = bit +// 0 : Allow Aliases +// 1 : Use Alias +// 2 : Use Alias, Ask for Aliases +// 3 : Test Age (use config age) +// 4 : Combined Area Access +// 5 : Local File attaches +// 6 : Keep Private Bit on Incoming EchoMail +// 7 : Security *) +// +// attribute2 = bit +// 0 : Show Seenby Lines +// 1 : Forced Mail Check +// 2 : Tiny Seenbys +// 3-4 : [Reserved] +// 5 : Areafix Info Visible +// 6 : Initial Combined Area Access +// 7 : Do Not Use in Template *) +// +// attribute3 = bit +// 0-7 : [Reserved] + +typedef struct MESSAGERECORD { + char name[31], + areatag[76], + qwkname[13]; + MsgType typ; + MsgKindsType msgkinds; + byte attribute, + attribute2, + attribute3, + dayskill, + recvkill; + word countkill, + kilobytekill; + SECURITYTYPE readsecurity, + writesecurity, + sysopsecurity; + byte minimumage; + char originline[51]; + byte originaddress, + seenby[MAXAKA/8], + areagroup, + messgroup, + altgroups[3], + echomailfeed, // 0=No Uplink + destnodes[MAXNODES/8], // Nodes 1 to 8 - DestNode[1] + // Nodes 9 to 16 - DestNode[2] + // Nodes 17 to 24 - DestNode[3] + freespace[32]; +} MESSAGERECORD; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_fd.h b/goldlib/gcfg/gs_fd.h new file mode 100644 index 0000000..0fc596b --- /dev/null +++ b/goldlib/gcfg/gs_fd.h @@ -0,0 +1,374 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1989-1990 Joaquim H. Homrighausen +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Definitions for FrontDoor 1.99c and above +// ------------------------------------------------------------------ + +#ifndef __gs_fd_h +#define __gs_fd_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Actually only size of the following structure used + +typedef struct { + + // The logfile + + char log[71]; + word loglevel; // See --- Loglevels + + // Number manipulation + + char prefix[31]; // Always added + char hidden[10][31]; // Strip these if they are in # + char postfix[31]; // Always appended + + // Miscellaneous flags + + long flags; // See --- Miscellaneous flags + long flags_reserved; // Reserved flags + word audio; // See --- Audio flags + byte synchtimer; // Number of seconds for sync + + // Errorlevels + + byte crashexit; // Mail exit + byte bbs300; + byte bbs1200; + byte bbs1275; + byte bbs2400; + byte bbs4800; + byte bbs9600; + byte bbs19200; + byte bbs38400; + + // Modem + + word modembaud; // 30=300, 24=2400, etc. + byte modemport; // 1-255 (COM1=1, COM2=2, etc.) + byte modemdelay; // 1/10 seconds delay / line sent + + // Messages + + char b300msg[16]; + char b1200msg[16]; + char b1275msg[16]; + char b2400msg[16]; + char b4800msg[16]; + char b9600msg[16]; + char b19200msg[16]; + char b38400msg[16]; + char errormsg[16]; + char busymsg[16]; + char carriermsg[16]; + char okmsg[16]; + char ringmsg[16]; + char nodialmsg[16]; + char noanswmsg[16]; + char voicemsg[16]; + + // Commands + + char escapestr[11]; + char offhookstr[11]; + char reconnectstr[11]; + char init1[50]; + char init2[50]; + char init3[50]; + char resetstr[50]; + char downstr[50]; + char hangupstr[11]; + char dialstr[11]; + + // Manual answer stuff + + char modemanswer[11]; + byte answerdelay; + + // Limited answer start and end times + + byte begin_hour; + byte begin_minute; + byte end_hour; + byte end_minute; + + // Calling control + + byte retrybusy; + byte retryresend; + byte retrydelay; + + // File request control + + char reqlist[71]; // List to scan for reqable dirs + char reqalias[71]; // Magic filenames + char reqmessage[71]; // Appended to FAILED REQUEST message + byte reqtype; // Bit field + byte reqmaxfiles; // Max number of files to send on 1 req + word reqmaxtime; // Maximum number of minutes for req + word reqmaxsize; // Maximum size (in KB) for req + word reqminbaud; // Minimum baudrate for req + byte reqstarthr; // Start time for file requests, can be + byte reqstartmin; // combined with the reqdays field. + byte reqendhr; + byte reqendmin; + byte reqdays; + + // File to send when human callers are let thru + + char bbsname[11]; + char beforebbsbanner[71]; + + // Function keys from mailer menu + + struct { + char cmd[61]; + char title[26]; + byte behavior; + } key[24]; + + // Mailer colors + + byte color[11]; + + // Number of days to keep entries in history files + + byte keep_history; + + // FDServer password, if none given, server is INactive + + char slavepwd[21]; + + // File displayed to users when system is in event for no callers + + char ineventfile[71]; + + // File displayed when human callers are seen on mail-only system + + char mailonlyfile[71]; + + // External programs to run on certain "wake-up" strings + + struct { + char wakeupstr[40]; + byte errorlevel; + } externmail[10]; + + // RESERVED FIELD + + // Limited audio start and end times. If the below four bytes + // are all zero (0), audio is enabled all the time + + byte audio_begin_hour; + byte audio_begin_minute; + byte audio_end_hour; + byte audio_end_minute; + + // Minimum cost for system to possibly end up in undialable list + + word min_undial_cost; + + char RESERVERAT[1018]; + +} FD_Mailer; + + +// ------------------------------------------------------------------ + +// Netmail folder behavior + +#define RESTRICTED 0x00000001L +#define EXPORTOK 0x00000004L +#define USEXLATTABLES 0x00000008L +#define EDREADONLY 0x00000020L + +#define MSGPRIVATE 0x0001 +#define MSGCRASH 0x0002 +#define MSGREAD 0x0004 +#define MSGSENT 0x0008 +#define MSGFILE 0x0010 +#define MSGTRANSIT 0x0020 +#define MSGORPHAN 0x0040 +#define MSGKILL 0x0080 +#define MSGLOCAL 0x0100 +#define MSGHOLD 0x0200 +#define MSGUNUSED 0x0400 +#define MSGFREQ 0x0800 +#define MSGRRREQ 0x1000 +#define MSGISRR 0x2000 +#define MSGAREQ 0x4000 +#define MSGFUPDREQ 0x8000 + +typedef struct { + + // Macro keys + + char macrokey[24][61]; + + // Margin, default==60 + + byte margin; + + // Default message status + + word msgbits; + + // Miscellaneous settings + + long flags; + + // Origin lines + + char origin[20][61]; + + // Editor colors + + byte color[15]; + + // Netmail folder flags + + long netfolderflags; + + // Translation tables IN/OUT + + byte translate_in[256]; + byte translate_out[256]; + + // Where RemoteAccess/QuickBBS message base files are + + char qbase[71]; + + // RESERVED + + char RESERVERAT[1024]; + +} FD_Editor; + + +// ------------------------------------------------------------------ + +typedef struct { + + char systempath[71]; + char mailpath[71]; + char swap_path[71]; + char RESERVED_path_1[71]; + char RESERVED_path_2[71]; + char infilepath[71]; + char packetpath[71]; + char nodelistpath[71]; + + word countrycode; + + ftn_addr aka[11]; + + // Timeout value for screen blanker in SECONDS (0-255) + + long flags; + byte blackout_time; + + // User record + + struct { + char name[37]; + long pwdcrc; // Crc-32 of user password, -1L No pwd + dword flags; + } user[10]; + + char RESERVED[1024]; + +} FD_Shared; + + +// ------------------------------------------------------------------ + +// Constant long bit values + +#define FOLDER_RESTRICT 0x00000001L // Restricted folder +#define FOLDER_ECHOINFO 0x00000002L // Add Origin: information +#define FOLDER_EXPORTOK 0x00000004L // OK for user to export from folder +#define FOLDER_USEXLAT 0x00000008L // Use translation tables +#define FOLDER_PRIVATE 0x00000010L // Add Private message status +#define FOLDER_READONLY 0x00000020L // Folder is read-only +#define FOLDER_FORCEHARDCR 0x00000040L // Force hard CRs at linebreak (C) +#define FOLDER_JAM 0x01000000L // JAM Message Base folder +#define FOLDER_NOCHECK 0x02000000L // Exclude from new mail check (C) +#define FOLDER_NETMAIL 0x08000000L // Netmail-type folder (C) +#define FOLDER_HMB 0x10000000L // Hudson Message Base folder +#define FOLDER_DELETED 0x20000000L // Never written to disk +#define FOLDER_LOCAL 0x40000000L // Local-type folder +#define FOLDER_ECHOMAIL 0x80000000L // Conference-type folder + +// User access mask + +#define FOLDER_USER_1 0x00000001L +#define FOLDER_USER_2 0x00000002L +#define FOLDER_USER_3 0x00000004L +#define FOLDER_USER_4 0x00000008L +#define FOLDER_USER_5 0x00000010L +#define FOLDER_USER_6 0x00000020L +#define FOLDER_USER_7 0x00000040L +#define FOLDER_USER_8 0x00000080L +#define FOLDER_USER_9 0x00000100L +#define FOLDER_USER_10 0x00000200L + +typedef struct { + + char path[65], // Path if "board==0", otherwise emtpy + title[41]; // Title to appear on screen + byte origin; // Default origin line, 0-19 + long behave; // Behavior, see above + long pwdcrc; // CRC32 of password or -1L if unprotected + long userok; // Users with initial access + byte useaka; // AKA to use, 0==primary + word board; // QuickBBS/RemoteAccess board number + +} FD_Folder, *FOLDERPTR; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_fech6.h b/goldlib/gcfg/gs_fech6.h new file mode 100644 index 0000000..0ba6ee7 --- /dev/null +++ b/goldlib/gcfg/gs_fech6.h @@ -0,0 +1,251 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (c) 1994 Tobias Burchhardt +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FastEcho 1.42 beta structures +// ------------------------------------------------------------------ + +#ifndef __gs_fech6_h +#define __gs_fech6_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// FASTECHO.CFG = +// + +// + +// + + +#define REVISION 6 // current revision +#define MAX_ROUTE 15 // max # of 'vias' + +// ------------------------------------------------------------------ +// Area.board (1-200 = Hudson) + +#define NO_BOARD 0x4000u // JAM/Sq/Passthru etc. +#define AREA_DELETED 0x8000u // usually never written + + +// ------------------------------------------------------------------ +// Area.flags.storage + +#define QBBS 0 +#define FIDO 1 +#define SQUISH 2 +#define JAM 3 +#define PASSTHRU 7 + + +// ------------------------------------------------------------------ +// Area.flags.atype + +#define AREA_ECHOMAIL 0 +#define AREA_NETMAIL 1 +#define AREA_LOCAL 2 +#define AREA_BADMAILBOARD 3 +#define AREA_DUPEBOARD 4 + + +// ------------------------------------------------------------------ +// Types and other definitions + +#define _MAXPATH 56 + +typedef struct CONFIGURATION6 +{ + word revision; + dword flags; + word NodeCnt, AreaCnt, unused1; + char NetMPath[_MAXPATH], + MsgBase[_MAXPATH], + InBound[_MAXPATH], + OutBound[_MAXPATH], + Unpacker[_MAXPATH], + LogFile[_MAXPATH], + unused2[448], + StatFile[_MAXPATH], + SwapPath[_MAXPATH], + SemaphorePath[_MAXPATH], + BBSConfigPath[_MAXPATH], + DBQueuePath[_MAXPATH], + unused3[32], + RetearTo[40], + SecurePath[_MAXPATH], + ExtAfter[_MAXPATH-4], + ExtBefore[_MAXPATH-4]; + byte unused4[480]; + struct { + byte what; + char object[31]; + word conference; + } CC[10]; + byte security, + loglevel; + word def_days, + def_messages; + byte unused5[462]; + word autorenum; + word def_recvdays; + word openQQQs; + word compressafter; + word afixmaxmsglen; + word compressfree; + char TempPath[_MAXPATH]; + byte graphics, + BBSSoftware; + char AreaFixHelp[_MAXPATH]; + byte unused6[504]; + word AreaFixFlags; + byte QuietLevel, + Buffers; + byte FWACnt, // # of ForwardAreaFix records, + GDCnt; // # of Group Default records + struct { + word flags; + word days[2]; + word msgs[2]; + } rescan_def; + dword duperecords; + struct { + byte inb; + byte outb; + } arcext; + word AFixRcptLen; + word AkaCnt; // # of Aka records stored */ + word maxPKT; + byte sharing, + sorting; + struct { + char name[36]; + dword resv; + } sysops[11]; + char AreaFixLog[_MAXPATH]; + char TempInBound[_MAXPATH]; + word maxPKTmsgs; + word RouteCnt; // # of PackRoute records + word maxPACKratio; + byte PackerCnt, UnpackerCnt; // # of Packers and Unpackers records + byte GroupCnt, OriginCnt; // # of GroupNames and Origin records + word mailer; + char resv[810]; + word AreaRecSize, GrpDefRecSize; // Size of Area and GroupDefaults + // records stored in this file + word MaxAreas, MaxNodes; // Current max values for this config + word NodeRecSize; // Size of each stored Node record + dword offset; // This is the offset from the current + // file-pointer to the 1st Node +} CONFIG6; + + +// ------------------------------------------------------------------ + +typedef struct +{ + char name[52]; + word board; // 1-200 Hudson, others reserved/special + word conference; // 0 ... CONFIG.MaxAreas-1 + word read_sec, write_sec; + struct { + word aka : 8; // 0 ... CONFIG.AkaCnt + word group : 8; // 0 ... CONFIG.GroupCnt + } info; + struct { + word storage: 4; + word atype : 4; + word origin : 5; // # of origin line + word resv : 3; + } flags; + struct { + word autoadded : 1; + word tinyseen : 1; + word cpd : 1; + word passive : 1; + word keepseen : 1; + word mandatory : 1; + word keepsysop : 1; + word killread : 1; + word disablepsv : 1; + word keepmails : 1; + word hide : 1; + word nomanual : 1; + word umlaut : 1; + word resv : 3; + } advflags; + word resv1; + dword seenbys; // LSB = Aka0, MSB = Aka31 + dword resv2; + short days; + short messages; + short recvdays; + char path[_MAXPATH]; + char desc[52]; +} FeArea6; + + +// ------------------------------------------------------------------ +// Optional Extensions + +typedef struct { + word type; // EH_... + dword offset; // length of field excluding header +} ExtensionHeader; + +#define EH_AKAS 0x0007 // CONFIG.AkaCnt * + +typedef struct { + ftn_addr main; + char domain[28]; + word pointnet; + dword flags; // unused +} SysAddress; + +#define EH_ORIGINS 0x0008 // CONFIG.OriginCnt * + +typedef struct { + char line[62]; +} OriginLines; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_fm092.h b/goldlib/gcfg/gs_fm092.h new file mode 100644 index 0000000..6e44380 --- /dev/null +++ b/goldlib/gcfg/gs_fm092.h @@ -0,0 +1,285 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Structures for FMail 0.92 +// ------------------------------------------------------------------ + +#ifndef __gs_fm092_h +#define __gs_fm092_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +#define MAX_AKAS 11 + +typedef struct { + ftn_addr nodeNum; + word fakeNet; +} nodeFakeType; + +typedef char pathType[48]; +typedef char tempStrType[128]; +typedef nodeFakeType akaListType[MAX_AKAS]; +typedef char archiverInfo[48]; + +typedef struct { + word useEMS : 1; /* BIT 0 */ + word : 1; + word swap : 1; /* BIT 2 */ + word swapEMS : 1; /* BIT 3 */ + word swapXMS : 1; /* BIT 4 */ + word : 1; + word monochrome : 1; /* BIT 6 */ + word commentFFD : 1; /* BIT 7 */ + word PTAreasBBS : 1; /* BIT 8 */ + word commentFRA : 1; /* BIT 9 */ + word keepReceipt : 1; /* BIT 10 */ + word : 1; + word : 1; + word : 1; + word : 1; + word extraHandles : 1; /* BIT 15 */ +} genOptionsType; + +typedef struct { + word removeNetKludges : 1; /* Bit 0 */ + word : 1; + word checkPktDest : 1; /* Bit 2 */ + word areaMgrPwdChange : 1; /* Bit 3 */ + word packetPwdChange : 1; /* Bit 4 */ + word : 1; + word : 1; + word : 1; + word dupDetection : 1; /* Bit 8 */ + word /*strictGroups*/ : 1; /* Bit 9 */ + word : 1; /* Bit 10 */ + word : 1; + word persNetmail : 1; /* Bit 12 */ + word : 1; + word : 1; + word : 1; /* Bit 15 */ +} mailOptionsType; + +typedef struct { + word sortNew : 1; /* bit 0 */ + word sortSubject : 1; /* bit 1 */ + word updateChains : 1; /* bit 2 */ + word : 1; /* bit 3 */ + word _importSeenBy: 1; /* bit 4 */ + word _removePID : 1; /* bit 5 not USED */ + word removeRe : 1; /* bit 6 */ + word removeLfSr : 1; /* bit 7 */ + word scanAlways : 1; /* bit 8 */ + word scanUpdate : 1; /* bit 9 */ + word multiLine : 1; /* bit 10 */ + word : 1; /* bit 11 */ + word quickToss : 1; /* bit 12 */ + word : 1; /* bit 13-14 */ + word : 1; /* bit 13-14 */ + word sysopImport : 1; /* bit 15 */ +} mbOptionsType; + +typedef struct { + word active : 1; /* Bit 0 */ + word tinySeenBy : 1; /* Bit 1 */ + word security : 1; /* Bit 2 */ + word : 1; /* Bit 3 */ + word Private : 1; /* Bit 4 */ + word impSeenBy : 1; /* Bit 5 */ + word checkSeenBy : 1; /* Bit 6 */ + word /*compChar*/: 1; /* Bit 7 */ + word local : 1; /* Bit 8 */ + word : 1; /* Bit 9 */ + word passThrough : 1; /* Bit 10 */ + word : 1; /* Bit 11-13 */ + word : 1; /* Bit 11-13 */ + word : 1; /* Bit 11-13 */ + word arrivalDate : 1; /* Bit 14 */ + word sysopRead : 1; /* Bit 15 */ +} defaultOptionsType; + +typedef struct { + char versionMajor; + char versionMinor; + long creationDate; + unsigned long key; + unsigned long reservedKey; + char sysopNameOld[32]; + akaListType akaList; + nodeFakeType reservedAka[16-MAX_AKAS]; + word netmailBoard[MAX_AKAS]; + word reservedNet[16-MAX_AKAS]; + genOptionsType genOptions; + mbOptionsType mbOptions; + mailOptionsType mailOptions; + word maxPktSize; + word logLevel; + word mailer; + word bbsProgram; + char reserved1[86]; + char sysopName[36]; + word defaultArc; + char reserved2[98]; + word recBoard; + word badBoard; + word dupBoard; + char topic1[16]; + char topic2[16]; + pathType bbsPath; + pathType netPath; + pathType sentPath; + pathType rcvdPath; + pathType inPath; + pathType outPath; + pathType securePath; + pathType logName; + pathType swapPath; + pathType semaphorePath; + pathType pmailPath; + pathType areaMgrLogName; + pathType autoRAPath; + pathType autoFolderFdPath; + pathType autoAreasBBSPath; + pathType autoGoldEdAreasPath; + archiverInfo unArc; + archiverInfo unZip; + archiverInfo unLzh; + archiverInfo unPak; + archiverInfo unZoo; + archiverInfo unArj; + archiverInfo reservedArc1; + archiverInfo reservedArc2; + archiverInfo arc; + archiverInfo zip; + archiverInfo lzh; + archiverInfo pak; + archiverInfo zoo; + archiverInfo arj; + archiverInfo reservedArc3; + archiverInfo reservedArc4; + char defaultOriginLine[59]; + defaultOptionsType + defaultOptions; + word defaultDays; + word defaultMsgs; + word defaultReadSecRA; + char defaultReadFlagsRA[4]; + word defaultWriteSecRA; + char defaultWriteFlagsRA[4]; + word defaultSysopSecRA; + char defaultSysopFlagsRA[4]; + char defaultAttrRA; + char reserved3[428]; + char groupDescr[26][27]; + char reserved4[20]; + char attrRA[11]; + word readSecRA[11]; + char readFlagsRA[11][4]; + word writeSecRA[11]; + char writeFlagsRA[11][4]; + word sysopSecRA[11]; + char sysopFlagsRA[11][4]; + word daysAKA[11]; + word msgsAKA[11]; + char descrAKA[11][51]; +} configType; + +#define ECHONAME_LEN_OLD 25 +#define ECHONAME_LEN 51 +#define COMMENT_LEN 51 +#define ORGLINE_LEN 59 +#define MAX_FORWARD 64 + +typedef struct { + word active : 1; /* Bit 0 */ + word tinySeenBy : 1; /* Bit 1 */ + word security : 1; /* Bit 2 */ + word : 1; /* Bit 3 */ + word Private : 1; /* Bit 4 */ + word impSeenBy : 1; /* Bit 5 */ + word checkSeenBy : 1; /* Bit 6 */ + word /*compChar*/: 1; /* Bit 7 */ + word local : 1; /* Bit 8 */ + word : 1; /* Bit 9 */ + word reserved : 1; /* Bit 10 */ /* default pass-thru bit */ + word : 1; /* Bit 11-13 */ + word : 1; /* Bit 11-13 */ + word : 1; /* Bit 11-13 */ + word arrivalDate : 1; /* Bit 14 */ + word sysopRead : 1; /* Bit 15 */ +} areaOptionsType; + +typedef struct { + char areaNameOld[ECHONAME_LEN_OLD]; + char comment[COMMENT_LEN]; + long group; + word board; + word address; + word alsoSeenBy; + char reserved1[8]; + areaOptionsType options; + word outStatus; + word days; + word msgs; + char reserved2[4]; + word readSecRA; + char flagsRdRA[4]; + word writeSecRA; + char flagsWrRA[4]; + word sysopSecRA; + char flagsSysRA[4]; + char attrRA; + char msgKindsRA; + word attrSBBS; + char replyStatSBBS; + char areaName[ECHONAME_LEN]; + char reserved3[17]; + char originLine[ORGLINE_LEN]; + ftn_addr exp[MAX_FORWARD]; +} rawEchoType; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_fm10g.h b/goldlib/gcfg/gs_fm10g.h new file mode 100644 index 0000000..8336a9c --- /dev/null +++ b/goldlib/gcfg/gs_fm10g.h @@ -0,0 +1,399 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1994 Folkert J. Wijnstra +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File structures for FMail 1.0g +// ------------------------------------------------------------------ + +#ifndef __gs_fm10g_h +#define __gs_fm10g_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef struct { + char programName[46]; + word memRequired; +} archiverInfo; + +typedef char pathType[48]; + +typedef struct { + ftn_addr nodeNum; + word fakeNet; +} nodeFakeType; + + +// ------------------------------------------------------------------ + +#define DATATYPE_CF 0x0102 +#define DATATYPE_NO 0x0202 +#define DATATYPE_AD 0x0401 +#define DATATYPE_AE 0x0402 + +typedef struct { + char versionString[32]; // Always starts with 'FMail' + word revNumber; // Is now 0x0100 + word dataType; // See #defines above + word headerSize; + sdword creationDate; + sdword lastModified; + word totalRecords; + word recordSize; +} headerType; + + +// ------------------------------------------------------------------ +// The structure below is used by the Areas File and (only partly) +// by the Config File + +typedef struct { + word active : 1; /* Bit 0 */ + word tinySeenBy : 1; /* Bit 1 */ + word security : 1; /* Bit 2 */ + word : 1; /* Bit 3 */ + word allowPrivate: 1; /* Bit 4 */ + word impSeenBy : 1; /* Bit 5 */ + word checkSeenBy : 1; /* Bit 6 */ + word : 1; /* Bit 7 */ + word local : 1; /* Bit 8 */ + word disconnected: 1; /* Bit 9 */ + word reserved : 1; /* Bit 10 */ + word allowAreafix: 1; /* Bit 11 */ + word : 1; /* Bit 12-13 */ + word : 1; /* Bit 12-13 */ + word arrivalDate : 1; /* Bit 14 */ + word sysopRead : 1; /* Bit 15 */ +} areaOptionsType; + +#define MAX_AKAS 16 +#define MAX_NETAKAS 11 +#define MAX_USERS 16 +#define MAX_UPLREQ 16 +#define MAX_MATCH 16 + +typedef nodeFakeType akaListType[MAX_AKAS]; + +typedef struct { + word useEMS : 1; /* BIT 0 */ + word checkBreak : 1; /* BIT 1 */ + word swap : 1; /* BIT 2 */ + word swapEMS : 1; /* BIT 3 */ + word swapXMS : 1; /* BIT 4 */ + word : 1; + word monochrome : 1; /* BIT 6 */ + word commentFFD : 1; /* BIT 7 */ + word PTAreasBBS : 1; /* BIT 8 */ + word commentFRA : 1; /* BIT 9 */ + word : 1; /* BIT 10 */ + word incBDRRA : 1; /* BIT 11 */ + word : 1; /* BIT 12 */ + word : 1; + word : 1; + word _RA2 : 1; /* BIT 15 */ +} genOptionsType; + +typedef struct { + word removeNetKludges : 1; /* Bit 0 */ + word : 1; + word checkPktDest : 1; /* Bit 2 */ + word : 1; + word createSema : 1; /* Bit 4 */ + word : 1; + word warnNewMail : 1; /* bit 6 */ + word killBadFAtt : 1; /* Bit 7 */ + word dupDetection : 1; /* Bit 8 */ + word ignoreMSGID : 1; /* Bit 9 */ + word ARCmail060 : 1; /* Bit 10 */ + word extNames : 1; /* Bit 11 */ + word persNetmail : 1; /* Bit 12 */ + word privateImport : 1; /* Bit 13 */ + word keepExpNetmail : 1; /* Bit 14 */ + word killEmptyNetmail : 1; /* Bit 15 */ +} mailOptionsType; + +typedef struct { + word sortNew : 1; /* bit 0 */ + word sortSubject : 1; /* bit 1 */ + word updateChains : 1; /* bit 2 */ + word reTear : 1; /* bit 3 */ + word : 1; /* bit 4 */ + word : 1; /* bit 5 */ + word removeRe : 1; /* bit 6 */ + word removeLfSr : 1; /* bit 7 */ + word scanAlways : 1; /* bit 8 */ + word scanUpdate : 1; /* bit 9 */ + word multiLine : 1; /* bit 10 */ + word : 1; /* bit 11 */ + word quickToss : 1; /* bit 12 */ + word : 1; /* bit 13 */ + word : 1; /* bit 14 */ + word sysopImport : 1; /* bit 15 */ +} mbOptionsType; + +typedef struct { + word keepRequest : 1; /* Bit 0 */ + word keepReceipt : 1; /* Bit 1 */ + word : 1; /* Bit 2 */ + word : 1; /* Bit 3 */ + word autoDiscArea : 1; /* Bit 4 */ + word autoDiscDel : 1; /* Bit 5 has temp. no effect, rec is always deleted */ + word : 1; /* Bit 6 */ + word : 1; /* Bit 7 */ + word : 1; /* Bit 8 */ + word allowAddAll : 1; /* Bit 9 */ + word allowActive : 1; /* Bit 10 */ + word : 1; /* Bit 11 */ + word allowPassword: 1; /* Bit 12 */ + word allowPktPwd : 1; /* Bit 13 */ + word allowNotify : 1; /* Bit 14 */ + word allowCompr : 1; /* Bit 15 */ +} mgrOptionsType; + +typedef struct { + word addPlusPrefix : 1; /* BIT 0 */ + word : 1; + word : 1; + word : 1; + word unconditional : 1; /* BIT 4 */ + word : 11; +} uplOptType; + +typedef struct { + char userName[36]; + char reserved[28]; +} userType; + +typedef struct { + ftn_addr node; + char program[9]; + char password[17]; + char fileName[13]; + char fileType; + dword groups; + char originAka; + uplOptType options; + char reserved[9]; +} uplinkReqType; + +typedef struct { + word valid; + word zone; + word net; + word node; +} akaMatchNodeType; + +typedef struct { + akaMatchNodeType amNode; + word aka; +} akaMatchType; + +typedef struct { + char versionMajor; + char versionMinor; + sdword creationDate; + dword key; + dword reservedKey; + dword relKey1; + dword relKey2; + char reserved1[22]; + mgrOptionsType mgrOptions; + akaListType akaList; + word netmailBoard[MAX_NETAKAS]; + word reservedNet[16-MAX_NETAKAS]; + genOptionsType genOptions; + mbOptionsType mbOptions; + mailOptionsType mailOptions; + word maxPktSize; + word reserved2; + word mailer; + word bbsProgram; + word maxBundleSize; + word extraHandles; /* 0-235 */ + word autoRenumber; + word bufSize; + word ftBufSize; + word allowedNumNetmail; + word logInfo; + word logStyle; + char reserved3[68]; + word colorSet; + char sysopName[36]; + word defaultArc; + char reserved4[24]; + char tearType; + char tearLine[25]; + pathType summaryLogName; + word recBoard; + word badBoard; + word dupBoard; + char topic1[16]; + char topic2[16]; + pathType bbsPath; + pathType netPath; + pathType sentPath; + pathType rcvdPath; + pathType inPath; + pathType outPath; + pathType securePath; + pathType logName; + pathType swapPath; + pathType semaphorePath; + pathType pmailPath; + pathType areaMgrLogName; + pathType autoRAPath; + pathType autoFolderFdPath; + pathType autoAreasBBSPath; + pathType autoGoldEdAreasPath; + archiverInfo unArc; + archiverInfo unZip; + archiverInfo unLzh; + archiverInfo unPak; + archiverInfo unZoo; + archiverInfo unArj; + archiverInfo unSqz; + archiverInfo GUS; + archiverInfo arc; + archiverInfo zip; + archiverInfo lzh; + archiverInfo pak; + archiverInfo zoo; + archiverInfo arj; + archiverInfo sqz; + archiverInfo customArc; + char reserved5[83]; + areaOptionsType optionsAKA[MAX_NETAKAS]; /* 'areaOptionsType' below */ + char groupsQBBS[MAX_NETAKAS]; + word templateSecQBBS[MAX_NETAKAS]; + char templateFlagsQBBS[MAX_NETAKAS][4]; + char attr2RA[MAX_NETAKAS]; + char aliasesQBBS[MAX_NETAKAS]; + word groupRA[MAX_NETAKAS]; + word altGroupRA[MAX_NETAKAS][3]; + char qwkNameSBBS[MAX_NETAKAS][13]; + word minAgeSBBS[MAX_NETAKAS]; + word daysRcvdAKA[MAX_NETAKAS]; + char replyStatSBBS[MAX_NETAKAS]; + word attrSBBS[MAX_NETAKAS]; + char groupDescr[26][27]; + char reserved6[9]; + char msgKindsRA[MAX_NETAKAS]; + char attrRA[MAX_NETAKAS]; + word readSecRA[MAX_NETAKAS]; + char readFlagsRA[MAX_NETAKAS][4]; + word writeSecRA[MAX_NETAKAS]; + char writeFlagsRA[MAX_NETAKAS][4]; + word sysopSecRA[MAX_NETAKAS]; + char sysopFlagsRA[MAX_NETAKAS][4]; + word daysAKA[MAX_NETAKAS]; + word msgsAKA[MAX_NETAKAS]; + char descrAKA[MAX_NETAKAS][51]; + userType users[MAX_USERS]; + akaMatchType akaMatch[MAX_MATCH]; + char reserved7[2048-10*MAX_MATCH]; + uplinkReqType uplinkReq[MAX_UPLREQ]; +} configType; + +#define MAX_FORWARD 64 + +#define MB_PATH_LEN_OLD 19 +#define MB_PATH_LEN 61 +#define ECHONAME_LEN_090 25 +#define ECHONAME_LEN 51 +#define COMMENT_LEN 51 +#define ORGLINE_LEN 59 + +typedef char areaNameType[ECHONAME_LEN]; + +typedef struct { + word signature; + word writeLevel; + areaNameType areaName; + char comment[COMMENT_LEN]; + areaOptionsType options; + word boardNumRA; + char msgBaseType; + char msgBasePath[MB_PATH_LEN]; + word board; + char originLine[ORGLINE_LEN]; + word address; + dword group; + word alsoSeenBy; + word msgs; + word days; + word daysRcvd; + + ftn_addr exp[MAX_FORWARD]; + + word readSecRA; + char flagsRdNotRA[4]; + char flagsRdRA[4]; + word writeSecRA; + char flagsWrNotRA[4]; + char flagsWrRA[4]; + word sysopSecRA; + char flagsSysRA[4]; + char flagsSysNotRA[4]; + word templateSecQBBS; + char flagsTemplateQBBS[4]; + char reserved2; + word netReplyBoardRA; + char boardTypeRA; + char attrRA; + char attr2RA; + word groupRA; + word altGroupRA[3]; + char msgKindsRA; + char qwkName[13]; + word minAgeSBBS; + word attrSBBS; + char replyStatSBBS; + char groupsQBBS; + char aliasesQBBS; +} rawEchoType; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_fm116.h b/goldlib/gcfg/gs_fm116.h new file mode 100644 index 0000000..27a71c4 --- /dev/null +++ b/goldlib/gcfg/gs_fm116.h @@ -0,0 +1,482 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1996 Folkert J. Wijnstra +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File structures for FMail 1.16 +// ------------------------------------------------------------------ + +#ifndef __gs_fm116_h +#define __gs_fm116_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef struct { + char programName[46]; + word memRequired; +} archiverInfo; + +typedef char pathType[48]; + +typedef struct { + ftn_addr nodeNum; + word fakeNet; +} nodeFakeType; + + +// ------------------------------------------------------------------ +// File header structure + +#define DATATYPE_CF 0x0102 // not used yet +#define DATATYPE_NO 0x0202 // node file +#define DATATYPE_AD 0x0401 // area file for echo mail defaults +#define DATATYPE_AE 0x0402 // area file for echo mail + +typedef struct { + char versionString[32]; // Always starts with 'FMail' + word revNumber; // Is now 0x0100 + word dataType; // See #defines above + word headerSize; + sdword creationDate; + sdword lastModified; + word totalRecords; + word recordSize; +} headerType; + + +// ------------------------------------------------------------------ +// The structure below is used by the Areas File and (only partly) +// by the Config File + +typedef struct { + word active : 1; /* Bit 0 */ + word tinySeenBy : 1; /* Bit 1 */ + word security : 1; /* Bit 2 */ + word : 1; /* Bit 3 */ + word allowPrivate: 1; /* Bit 4 */ + word impSeenBy : 1; /* Bit 5 */ + word checkSeenBy : 1; /* Bit 6 */ + word : 1; /* Bit 7 */ + word local : 1; /* Bit 8 */ + word disconnected: 1; /* Bit 9 */ + word _reserved : 1; /* Bit 10 */ + word allowAreafix: 1; /* Bit 11 */ + word : 2; /* Bit 12-13 */ + word arrivalDate : 1; /* Bit 14 */ + word sysopRead : 1; /* Bit 15 */ +} areaOptionsType; + + +/* ********** FMAIL.CFG ********** */ + +#define MAX_AKAS 32 +#define MAX_AKAS_F 64 +#define MAX_AKAS_OLD 16 +#define MAX_NA_OLD 11 +#define MAX_NETAKAS 32 +#define MAX_NETAKAS_F 64 +#define MAX_USERS 16 +#define MAX_UPLREQ 32 +#define MAX_MATCH 16 // not used yet + +typedef nodeFakeType _akaListType[MAX_AKAS_OLD]; +typedef nodeFakeType akaListType[MAX_AKAS_F]; + +typedef struct { + word useEMS : 1; /* BIT 0 */ + word checkBreak : 1; /* BIT 1 */ + word swap : 1; /* BIT 2 */ + word swapEMS : 1; /* BIT 3 */ + word swapXMS : 1; /* BIT 4 */ + word : 1; + word monochrome : 1; /* BIT 6 */ + word commentFFD : 1; /* BIT 7 */ + word PTAreasBBS : 1; /* BIT 8 */ + word commentFRA : 1; /* BIT 9 */ + word : 1; /* BIT 10 */ + word incBDRRA : 1; /* BIT 11 */ + word : 1; /* BIT 12 */ + word : 2; + word _RA2 : 1; /* BIT 15 */ +} genOptionsType; + +typedef struct { + word removeNetKludges : 1; /* Bit 0 */ + word : 1; + word checkPktDest : 1; /* Bit 2 */ + word : 1; + word createSema : 1; /* Bit 4 */ + word : 1; + word warnNewMail : 1; /* bit 6 */ + word killBadFAtt : 1; /* Bit 7 */ + word dupDetection : 1; /* Bit 8 */ + word ignoreMSGID : 1; /* Bit 9 */ + word ARCmail060 : 1; /* Bit 10 */ + word extNames : 1; /* Bit 11 */ + word persNetmail : 1; /* Bit 12 */ + word privateImport : 1; /* Bit 13 */ + word keepExpNetmail : 1; /* Bit 14 */ + word killEmptyNetmail : 1; /* Bit 15 */ +} mailOptionsType; + +typedef struct { + word sortNew : 1; /* bit 0 */ + word sortSubject : 1; /* bit 1 */ + word updateChains : 1; /* bit 2 */ + word reTear : 1; /* bit 3 */ + word : 1; /* bit 4 */ + word : 1; /* bit 5 */ + word removeRe : 1; /* bit 6 */ + word removeLfSr : 1; /* bit 7 */ + word scanAlways : 1; /* bit 8 */ + word scanUpdate : 1; /* bit 9 */ + word multiLine : 1; /* bit 10 */ + word : 1; /* bit 11 */ + word quickToss : 1; /* bit 12 */ + word : 1; /* bit 13 */ + word : 1; /* bit 14 */ + word sysopImport : 1; /* bit 15 */ +} mbOptionsType; + +typedef struct { + word keepRequest : 1; /* Bit 0 */ + word keepReceipt : 1; /* Bit 1 */ + word : 2; /* Bit 2-3 */ + word autoDiscArea : 1; /* Bit 4 */ + word autoDiscDel : 1; /* Bit 5 has temp. no effect, rec is always deleted */ + word : 3; /* Bit 6-8 */ + word allowAddAll : 1; /* Bit 9 */ + word allowActive : 1; /* Bit 10 */ + word : 1; /* Bit 11 */ + word allowPassword: 1; /* Bit 12 */ + word allowPktPwd : 1; /* Bit 13 */ + word allowNotify : 1; /* Bit 14 */ + word allowCompr : 1; /* Bit 15 */ +} mgrOptionsType; + +typedef struct { + word addPlusPrefix : 1; /* BIT 0 */ + word : 3; + word unconditional : 1; /* BIT 4 */ + word : 11; +} uplOptType; + +typedef struct { + char userName[36]; + byte reserved[28]; +} userType; + +typedef struct { + ftn_addr node; + char program[9]; + byte password[17]; + char fileName[13]; + byte fileType; + dword groups; + byte originAka; + uplOptType options; + byte reserved[9]; +} uplinkReqType; + +typedef struct { + word valid; + word zone; + word net; + word node; +} akaMatchNodeType; + +typedef struct { + akaMatchNodeType amNode; + word aka; +} akaMatchType; + +typedef struct { + byte versionMajor; + byte versionMinor; + sdword creationDate; + dword key; + dword reservedKey; + dword relKey1; + dword relKey2; + byte reserved1[22]; + mgrOptionsType mgrOptions; + _akaListType _akaList; + word _netmailBoard[MAX_NA_OLD]; + word _reservedNet[16-MAX_NA_OLD]; + genOptionsType genOptions; + mbOptionsType mbOptions; + mailOptionsType mailOptions; + word maxPktSize; + word kDupRecs; + word mailer; + word bbsProgram; + word maxBundleSize; + word extraHandles; /* 0-235 */ + word autoRenumber; + word bufSize; + word ftBufSize; + word allowedNumNetmail; + word logInfo; + word logStyle; + byte reserved2[68]; + word colorSet; + char sysopName[36]; + word defaultArc; + word _adiscDaysNode; + word _adiscDaysPoint; + word _adiscSizeNode; + word _adiscSizePoint; + byte reserved3[16]; + byte tearType; + char tearLine[25]; + pathType summaryLogName; + word recBoard; + word badBoard; + word dupBoard; + byte topic1[16]; + byte topic2[16]; + pathType bbsPath; + pathType netPath; + pathType sentPath; + pathType rcvdPath; + pathType inPath; + pathType outPath; + pathType securePath; + pathType logName; + pathType swapPath; + pathType semaphorePath; + pathType pmailPath; + pathType areaMgrLogName; + pathType autoRAPath; + pathType autoFolderFdPath; + pathType autoAreasBBSPath; + pathType autoGoldEdAreasPath; + archiverInfo unArc; + archiverInfo unZip; + archiverInfo unLzh; + archiverInfo unPak; + archiverInfo unZoo; + archiverInfo unArj; + archiverInfo unSqz; + archiverInfo GUS; + archiverInfo arc; + archiverInfo zip; + archiverInfo lzh; + archiverInfo pak; + archiverInfo zoo; + archiverInfo arj; + archiverInfo sqz; + archiverInfo customArc; + pathType autoFMail102Path; + byte reserved4[35]; + areaOptionsType _optionsAKA[MAX_NA_OLD]; + byte _groupsQBBS[MAX_NA_OLD]; + word _templateSecQBBS[MAX_NA_OLD]; + byte _templateFlagsQBBS[MAX_NA_OLD][4]; + byte _attr2RA[MAX_NA_OLD]; + byte _aliasesQBBS[MAX_NA_OLD]; + word _groupRA[MAX_NA_OLD]; + word _altGroupRA[MAX_NA_OLD][3]; + byte _qwkName[MAX_NA_OLD][13]; + word _minAgeSBBS[MAX_NA_OLD]; + word _daysRcvdAKA[MAX_NA_OLD]; + byte _replyStatSBBS[MAX_NA_OLD]; + word _attrSBBS[MAX_NA_OLD]; + byte groupDescr[26][27]; + byte reserved5[9]; + byte _msgKindsRA[MAX_NA_OLD]; + byte _attrRA[MAX_NA_OLD]; + word _readSecRA[MAX_NA_OLD]; + byte _readFlagsRA[MAX_NA_OLD][4]; + word _writeSecRA[MAX_NA_OLD]; + byte _writeFlagsRA[MAX_NA_OLD][4]; + word _sysopSecRA[MAX_NA_OLD]; + byte _sysopFlagsRA[MAX_NA_OLD][4]; + word _daysAKA[MAX_NA_OLD]; + word _msgsAKA[MAX_NA_OLD]; + byte _descrAKA[MAX_NA_OLD][51]; + userType users[MAX_USERS]; + akaMatchType akaMatch[MAX_MATCH]; // not used yet + byte reserved6[1040-10*MAX_MATCH]; + pathType sentEchoPath; + archiverInfo preUnarc; + archiverInfo postUnarc; + archiverInfo preArc; + archiverInfo postArc; + archiverInfo unUc2; + archiverInfo unRar; + archiverInfo resUnpack[6]; + archiverInfo uc2; + archiverInfo rar; + archiverInfo resPack[6]; + uplinkReqType uplinkReq[MAX_UPLREQ+32]; + archiverInfo unArc32; + archiverInfo unZip32; + archiverInfo unLzh32; + archiverInfo unPak32; + archiverInfo unZoo32; + archiverInfo unArj32; + archiverInfo unSqz32; + archiverInfo unUc232; + archiverInfo unRar32; + archiverInfo GUS32; + archiverInfo resUnpack32[6]; + archiverInfo preUnarc32; + archiverInfo postUnarc32; + archiverInfo arc32; + archiverInfo zip32; + archiverInfo lzh32; + archiverInfo pak32; + archiverInfo zoo32; + archiverInfo arj32; + archiverInfo sqz32; + archiverInfo uc232; + archiverInfo rar32; + archiverInfo customArc32; + archiverInfo resPack32[6]; + archiverInfo preArc32; + archiverInfo postArc32; + byte descrAKA[MAX_NETAKAS][51]; + byte qwkName[MAX_NETAKAS][13]; + areaOptionsType optionsAKA[MAX_NETAKAS]; + byte msgKindsRA[MAX_NETAKAS]; + word daysAKA[MAX_NETAKAS]; + word msgsAKA[MAX_NETAKAS]; + byte groupsQBBS[MAX_NETAKAS]; + byte attrRA[MAX_NETAKAS]; + byte attr2RA[MAX_NETAKAS]; + word attrSBBS[MAX_NETAKAS]; + byte aliasesQBBS[MAX_NETAKAS]; + word groupRA[MAX_NETAKAS]; + word altGroupRA[MAX_NETAKAS][3]; + word minAgeSBBS[MAX_NETAKAS]; + word daysRcvdAKA[MAX_NETAKAS]; + byte replyStatSBBS[MAX_NETAKAS]; + word readSecRA[MAX_NETAKAS]; + byte readFlagsRA[MAX_NETAKAS][8]; + word writeSecRA[MAX_NETAKAS]; + byte writeFlagsRA[MAX_NETAKAS][8]; + word sysopSecRA[MAX_NETAKAS]; + byte sysopFlagsRA[MAX_NETAKAS][8]; + word templateSecQBBS[MAX_NETAKAS]; + byte templateFlagsQBBS[MAX_NETAKAS][8]; + byte reserved7[512]; + word netmailBoard[MAX_NETAKAS_F]; + akaListType akaList; +} configType; + +#define MAX_FORWARD 64 + +#define MB_PATH_LEN_OLD 19 +#define MB_PATH_LEN 61 +#define ECHONAME_LEN_090 25 +#define ECHONAME_LEN 51 +#define COMMENT_LEN 51 +#define ORGLINE_LEN 59 + +typedef char areaNameType[ECHONAME_LEN]; + +typedef struct { + word tossedTo : 1; /* BIT 0 */ + word : 15; /* BIT 1-15 */ +} areaStatType; + +typedef struct { + + word signature; // contains "AE" for echo areas in FMAIL.AR and + // "AD" for default settings in FMAIL.ARD + word writeLevel; + areaNameType areaName; + char comment[COMMENT_LEN]; + areaOptionsType options; + word boardNumRA; + byte msgBaseType; + char msgBasePath[MB_PATH_LEN]; + word board; + char originLine[ORGLINE_LEN]; + word address; + dword group; + word _alsoSeenBy; // obsolete: see the 32-bit alsoSeenBy below + word msgs; + word days; + word daysRcvd; + + ftn_addr exp[MAX_FORWARD]; + + word readSecRA; + byte flagsRdRA[4]; + byte flagsRdNotRA[4]; + word writeSecRA; + byte flagsWrRA[4]; + byte flagsWrNotRA[4]; + word sysopSecRA; + byte flagsSysRA[4]; + byte flagsSysNotRA[4]; + word templateSecQBBS; + byte flagsTemplateQBBS[4]; + byte _internalUse; + word netReplyBoardRA; + byte boardTypeRA; + byte attrRA; + byte attr2RA; + word groupRA; + word altGroupRA[3]; + byte msgKindsRA; + byte qwkName[13]; + word minAgeSBBS; + word attrSBBS; + byte replyStatSBBS; + byte groupsQBBS; + byte aliasesQBBS; + dword lastMsgTossDat; + dword lastMsgScanDat; + dword alsoSeenBy; + areaStatType stat; + byte reserved[180]; +} rawEchoType116; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_ge120.h b/goldlib/gcfg/gs_ge120.h new file mode 100644 index 0000000..49e5d5d --- /dev/null +++ b/goldlib/gcfg/gs_ge120.h @@ -0,0 +1,469 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1991-1995 Gerard J. van der Land +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// System data file definitions for GEcho 1.20.b10+ +// ------------------------------------------------------------------ + +#ifndef __gs_ge120_h +#define __gs_ge120_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +#define GE_THISREV 0x0002 // System file revision level +#define GE_MAJOR 1 // GEcho major revision version +#define GE_MINOR 20 // GEcho minor revision version + +#define AKAS 32 // Main + AKAs +#define OLDAKAS 11 // Not used +#define OLDUPLINKS 10 // Not used +#define OLDGROUPS 26 // Not used +#define USERS 10 // User names +#define MAXAREAS 10000 // Area records +#define MAXCONNECTIONS 500 // Connections per area +#define MAXGROUPS 256 // Group records +#define MAXNODES 5000 // Node records +#define MAXVIAS 60 // Pack "Via" records +#define MAXROUTES 640 // Pack "Routed node" records + +#define GROUPBYTES ((MAXGROUPS + 7) / 8) + + +// ------------------------------------------------------------------ +// Data types + +typedef char GROUPS[GROUPBYTES]; + +/* --- Log levels */ + +#define LOG_INBOUND 0x0001 /* Inbound activities */ +#define LOG_OUTBOUND 0x0002 /* Outbound activities */ +#define LOG_PACKETS 0x0004 /* Inbound packet info */ +#define LOG_UNEXPECT 0x0008 /* Extended packet info */ +#define LOG_AREAMGR 0x0010 /* Unexpected passwords */ +#define LOG_EXTPKTINFO 0x0040 /* AreaMgr messages */ +#define LOG_NETEXPORT 0x0100 /* Exporting of netmail */ +#define LOG_NETIMPORT 0x0200 /* Importing of netmail */ +#define LOG_NETPACK 0x0400 /* Packing of netmail */ +#define LOG_NETMOVED 0x0800 /* Moving Sent/Rcvd mail */ +#define LOG_STATISTICS 0x2000 /* GEcho's statistics */ +#define LOG_MBUTIL 0x4000 /* MBUTIL's activities */ +#define LOG_DEBUG 0x8000 /* DEBUG: All of the above */ + + +/* --- Log styles */ + +#define LOG_FD 0 /* FrontDoor */ +#define LOG_BINK 1 /* BinkleyTerm */ +#define LOG_QUICK 2 /* QuickBBS */ +#define LOG_DBRIDGE 3 /* D'Bridge */ + + +/* --- Setup option bits */ + +#define NOKILLNULL 0x0001 /* Don't kill null netmail messages while tossing */ +#define RESCANOK 0x0002 /* Allow %RESCAN */ +#define KEEPREQS 0x0004 /* Keep AreaMgr requests */ +#define NONODEADD 0x0008 /* Don't automatically add NodeMgr records */ +#define USEHMBBUF 0x0020 /* Use Hudson buffers */ +#define KEEPNET 0x0040 /* Don't use Kill/Sent on exported netmail */ +#define KEEPMGR 0x0080 /* Don't use Kill/Sent on MGR receipts */ +#define NORRQS 0x0100 /* Ignore Return receipt Requests */ +#define KILLDUPES 0x0200 /* Kill duplicate messages */ +#define DOS32BIT 0x0400 /* Run 32-bit DOS version on 386+ machines */ +#define NOCRSTRIP 0x0800 /* Don't strip Soft-CRs */ +#define REMOVEJUNK 0x1000 /* Remove "Re:" junk from JAM subjects */ +#define NOAUTODISC 0x2000 /* Don't automatically disconnect empty PT areas */ +#define NOCHECKEND 0x4000 /* Don't check for valid end of archives */ +#define SETPVT 0x8000 /* Set Pvt on imported netmail messages */ + + +/* --- Extra option bits */ + +#define NOCHKDEST 0x0001 /* Don't check packet destination */ +#define AUTOCREAT 0x0002 /* Automatically create message bases */ +#define PAUSEOK 0x0004 /* Allow %PAUSE */ +#define NOTIFYOK 0x0008 /* Allow %NOTIFY OFF */ +#define ADDALLOK 0x0010 /* Allow +* */ +#define PWDOK 0x0020 /* Allow %PWD */ +#define PKTPWDOK 0x0040 /* Allow %PKTPWD */ +#define NOBADPKTS 0x0080 /* Don't notify sysop about BAD/DST/LOC packets */ +#define PKTPRGONCE 0x0100 /* Run PKT program only before the first PKT */ +#define CREATEBUSY 0x0200 /* Create busy flags */ +#define COMPRESSOK 0x0400 /* Allow %COMPRESS */ +#define FROMOK 0x0800 /* Allow %FROM */ +#define REDIR2NUL 0x1000 /* Redirect output of external utilities to NUL */ +#define NOEXPAND 0x2000 /* Don't expand filenames of file attaches */ +#define LOCALEXPT 0x4000 /* Export netmail to our own AKA */ +#define OPUSDATES 0x8000 /* Use Opus style binary date/time stamps */ + + +/* --- Compression types */ + +#define PR_ARC 0 /* Compressed mail files created by ARC or PKPAK */ +#define PR_ARJ 1 /* Compressed mail files created by ARJ */ +#define PR_LZH 2 /* Compressed mail files created by LHA */ +#define PR_PAK 3 /* Compressed mail files created by PAK */ +#define PR_ZIP 4 /* Compressed mail files created by PKZIP */ +#define PR_ZOO 5 /* Compressed mail files created by ZOO */ +#define PR_SQZ 6 /* Compressed mail files created by SQZ */ +#define PR_UC2 7 /* Compressed mail files created by UC II */ +#define PR_RAR 8 /* For compressed mail files created by RAR */ +#define PR_PKT 10 /* Uncompressed PKT files */ + + +/* --- Locking method */ + +#define LOCK_OFF 0 /* Deny Write (Exclusive) */ +#define LOCK_RA101 1 /* RemoteAccess 1.01 (SHARE) */ +#define LOCK_RA111 2 /* RemoteAccess 1.11 (SHARE) */ + + +/* --- Semaphore mode */ + +#define SEMAPHORE_OFF 0 /* Don't use semaphores */ +#define SEMAPHORE_FD 1 /* FrontDoor 2.1x */ +#define SEMAPHORE_IM 2 /* InterMail 2.2x */ +#define SEMAPHORE_DB 3 /* D'Bridge 1.5x */ +#define SEMAPHORE_BT 4 /* BinkleyTerm 2.5x */ +#define SEMAPHORE_MD 5 /* MainDoor */ + + +/* --- Check user name */ + +#define CHECK_NOT 0 /* Don't check if user name exists */ +#define CHECK_USERFILE 1 /* User file (USERS.BBS) */ +#define CHECK_USERINDEX 2 /* User index (USERSIDX.BBS / NAMEIDX.BBS) */ + + +/* --- Mailer type */ + +#define MAILER_FD 0 /* FrontDoor */ +#define MAILER_DB 1 /* D'Bridge */ +#define MAILER_BT 2 /* BinkleyTerm */ + + +/* --- BBS type */ + +#define BBS_RA111 0 /* RemoteAccess 1.1x */ +#define BBS_RA200 1 /* RemoteAccess 2.xx */ +#define BBS_QUICK275 2 /* QuickBBS 2.7x */ +#define BBS_SBBS116 3 /* SuperBBS 1.16 */ + + +/* --- Change tear line */ + +#define TEAR_NO 0 /* No */ +#define TEAR_DEFAULT 1 /* Replace default */ +#define TEAR_CUSTOM 2 /* Replace custom */ +#define TEAR_EMPTY 3 /* Replace empty */ +#define TEAR_REMOVE 4 /* Remove */ + + +/* --- PCBoard options */ + +#define PCB_145COMPAT 0x01 /* PCBoard 14.5 compatibility */ + + +/* --- Wildcat! options */ + +#define WC_NONOTIFY 0x01 /* Do not notify users of new mail */ + + +typedef struct { + ftn_addr address; /* Uplink address */ + char areafix[9]; /* AreaFix program */ + char password[17]; /* AreaFix password */ + char filename[13]; /* "Forward List" filename */ + byte unused[6]; + byte options; /* See --- Uplink options bits */ + byte filetype; /* 0 = Random, 1 = " " */ + dword groups; /* Nodes must have one of these groups */ + byte origin; /* Origin AKA */ +} OLDUPLINK; + +typedef struct { + word zone; + word net; + byte aka; +} AKAMATCH; + +typedef struct { + byte bg_char; + byte headerframe; + byte headertext; + byte background; + byte bottomline; + byte bottomtext; + byte bottomkey; + byte errorframe; + byte errortext; + byte helpframe; + byte helptitle; + byte helptext; + byte helpfound; + byte winframe; + byte wintitle; + byte winline; + byte wintext; + byte winkey; + byte windata; + byte winselect; + byte inputdata; + byte exportonly; + byte importonly; + byte lockedout; +} COLORSET; + + +/* --- SETUP.GE structure */ + +typedef struct { + word sysrev; /* Must contain GE_THISREV */ + word options; /* Options bits, see --- Setup option bits */ + word autorenum; /* Auto renumber value */ + word maxpktsize; /* Maximum packet size, 0 = unlimited */ + byte logstyle; /* See --- Log styles */ + byte oldnetmailboard; /* Netmail board, must be zero now */ + byte oldbadboard; /* Where bad echomail is stored (0 = path) */ + byte olddupboard; /* Where duplicates are stored (0 = path) */ + byte recoveryboard; /* Recovery board (1-200, 0 = delete) */ + byte filebuffer; /* Size (in KB) of MBU file I/O buffer */ + byte days; /* Days to keep old mail around */ + byte swapping; /* Swapping method */ + byte compr_default; /* Default compresion type */ + byte pmcolor[15]; /* Not used */ + ftn_addr oldaka[OLDAKAS]; /* Main address and AKAs */ + word oldpointnet[OLDAKAS];/* Pointnets for all addresses */ + dword gekey; /* GEcho registration key */ + dword mbukey; /* MBUTIL registration key */ + char geregto[51]; /* Text used to generate the GEcho key */ + char mburegto[51]; /* Text used to generate the MBUTIL key */ + char username[USERS][36]; /* User names */ + char hmbpath[53]; /* Hudson message base path */ + char mailpath[53]; /* Netmail path */ + char inbound_path[53]; /* Where incoming compressed mail is stored */ + char outbound_path[53]; /* Where outgoing compressed mail is stored */ + char echotoss_file[65]; /* The ECHOTOSS.LOG used for Squish areas */ + char nodepath[53]; /* Not used */ + char areasfile[65]; /* AREAS.BBS style file */ + char logfile[65]; /* GEcho/MBUTIL log file */ + char mgrlogfile[65]; /* AreaMgr log file */ + char swap_path[53]; /* Swap path */ + char tear_line[31]; /* Tearline to be placed by MBUTIL Export */ + char originline[20][61]; /* Origin lines */ + char compr_prog[10][13]; /* Compression program filenames */ + char compr_switches[10][20]; /* Compression program switches */ + char decompr_prog[10][13]; /* Decompression program filenames */ + char decompr_switches[10][20]; /* Decompression program switches */ + char oldgroups[26][21]; /* Descriptions of area groups */ + byte lockmode; /* See --- Locking method */ + char secure_path[53]; /* From which secure PKTs are tossed */ + char rcvdmailpath[53]; /* Not used */ + char sentmailpath[53]; /* Not used */ + char semaphorepath[53]; /* Where FD rescan files are stored */ + byte version_major; /* Major GEcho version */ + byte version_minor; /* Minor GEcho version */ + byte semaphore_mode; /* See --- Semaphore modes */ + char badecho_path[53]; /* Where sec. violating and unknown mail is stored */ + byte mailer_type; /* See --- Mailer type */ + word loglevel; /* See --- Log level */ + AKAMATCH akamatch[20]; /* AKA matching table */ + char mbulogfile[65]; /* MBUTIL log file */ + word maxqqqs; /* Max. number of QQQ info stored in memory */ + byte maxqqqopen; /* Not used */ + byte maxhandles; /* Max. number of files used by GEcho */ + word maxarcsize; /* Max. archive size, 0 = unlimited */ + word delfuture; /* Days to delete messages in the future, 0 = disable */ + word extraoptions; /* See --- Extra option bits */ + byte firstboard; /* Not used */ + word reserved1; /* Reserved */ + word copy_persmail; /* Not used */ + byte oldpersmailboard[USERS]; /* Personal mail board (0 = path) */ + dword old_public_groups; /* Public groups (bits 0-25) */ + word dupentries; /* Number of duplicate entries in ECHODUPE.GE */ + byte oldrcvdboard; /* Where Rcvd netmail is moved to (0 = path) */ + byte oldsentboard; /* Where Sent netmail is moved to (0 = path) */ + byte oldakaboard[OLDAKAS]; /* Netmail boards for AKAs */ + byte olduserboard[USERS]; /* Netmail boards for system users, 255 = use AKA board */ + byte reserved2; /* Reserved */ + OLDUPLINK uplink[OLDUPLINKS]; /* Not used */ + char persmail_path[53]; /* Not used */ + char outpkts_path[53]; /* Where outbound packets are temp. stored */ + word compr_mem[10]; /* Memory needed for compression programs */ + word decompr_mem[10]; /* Memory needed for decompression programs */ + dword pwdcrc; /* CRC-32 of access password, -1L = no password */ + word default_maxmsgs; /* Maximum number of messages (Purge) */ + word default_maxdays; /* Maximum age of non-Rcvd messages (Purge) */ + char gus_prog[13]; /* General Unpack Shell program filename */ + char gus_switches[20]; /* GUS switches */ + word gus_mem; /* Memory needed for GUS */ + word default_maxrcvddays; /* Maximum age of Rcvd messages (Purge) */ + byte checkname; /* See --- Check user name */ + byte maxareacachesize; /* Area cache size, 0 .. 64 KB */ + char inpkts_path[53]; /* Where inbound mail packets should be stored */ + char pkt_prog[13]; /* Called before each tossed mail packet */ + char pkt_switches[20]; /* Command line switches */ + word pkt_mem; /* Memory needed */ + word maxareas; /* Maximum number of areas */ + word maxconnections; /* Maximum number of connections per area */ + word maxnodes; /* Maximum number of nodes */ + word default_minmsgs; /* Minimum number of messages (Purge) */ + byte bbs_type; /* See --- BBS type */ + byte decompress_ext; /* 0 = 0-9, 1 = 0-F, 2 = 0-Z */ + byte reserved3; /* Reserved */ + byte change_tearline; /* See --- Change tear line */ + word prog_notavail; /* Bit 0-9, 1 = program not available */ + COLORSET gscolor; /* GSETUP color set, See COLORSET structure */ + byte reserved4[9]; /* Reserved */ + + ftn_addr aka[AKAS]; /* Main address and AKAs */ + word pointnet[AKAS]; /* Pointnets for all addresses */ + word akaarea[AKAS]; /* AKA netmail areas */ + word userarea[USERS]; /* Netmail areas for system users, 0 = don't import, 65535 = use AKA area */ + word persmailarea[USERS]; /* Personal mail area (0 = don't copy) */ + word rcvdarea; /* Rcvd netmail area (0 = don't move) */ + word sentarea; /* Sent netmail area (0 = don't move) */ + word badarea; /* Where bad echomail is stored (0 = path) */ + word reserved5; /* Not used */ + char jampath[53]; /* JAM message base path */ + char userbase[53]; /* User base path */ + char dos4gw_exe[65]; /* DOS4GW.EXE protected mode run time file */ + GROUPS public_groups; /* Public groups (bits 0-255) */ + word maxgroupconnections; /* Maximum number of connections per group */ + word maxmsgsize; /* Maximum message size (64-1024 kB) */ + word diskspace_threshold; /* Amount of free disk space that causes packing */ + byte pktsort; /* 0 = No, 1 = Area, 2 = Area + Date/Time */ + char wildcatpath[53]; /* Wildcat! home path */ + byte wcoptions; /* Wildcat! options */ + byte pcboptions; /* PCBoard options */ +} SETUP_GE; + +#define IMPORTSB 0x0001 /* Import SEEN-BY lines to message base */ +#define SECURITY 0x0002 /* Only accept mail from nodes in connections list */ +#define PASSTHRU 0x0004 /* Mail is not imported, only forwarded */ +#define VISIBLE 0x0008 /* Area is visible for anyone in AreaMgr's %LIST */ +#define REMOVED 0x0010 /* Area should be removed by GSETUP Pack */ +#define NOUNLINK 0x0020 /* Do not allow users to unlink this area */ +#define TINYSB 0x0040 /* Tiny SEEN-BYs with only nodes in connections list */ +#define PVT 0x0080 /* Private bits are preserved and are not stripped */ +#define CHECKSB 0x0100 /* Use SEEN-BYs for duplicate prevention */ +#define NOPAUSE 0x0200 /* Do not allow users to pause this area */ +#define SDM 0x0400 /* Area is stored in *.MSG format */ +#define HIDESB 0x0800 /* Hide imported SEEN-BY lines */ +#define NOIMPORT 0x1000 /* AreaMgr will set new nodes to Export-Only */ +#define DELFUTURE 0x2000 /* Del messages dated in the future */ +#define NOTIFIED 0x4000 /* Sysop notified that area was disconnected */ +#define UPLDISC 0x8000 /* Disconnected from uplink (only for PT areas) */ + + +#define NODUPECHK 0x01 /* Don't do duplicate checking for this area */ +#define NOLINKING 0x02 /* Don't do reply chain linking for this area */ +#define HIDDEN 0x04 /* Area is hidden for everyone */ + + +#define ECHOMAIL 0 +#define NETMAIL 1 +#define LOCAL 2 +#define BADECHO 3 +#define PERSONAL 4 +#define NUM_TYPES 5 + + +#define FORMAT_PT 0 /* Passthru */ +#define FORMAT_HMB 1 /* Hudson Message Base */ +#define FORMAT_SDM 2 /* *.MSG base */ +#define FORMAT_JAM 3 /* Joaquim-Andrew-Mats message base proposal */ +#define FORMAT_PCB 4 /* PCBoard 15.0 */ +#define FORMAT_SQUISH 5 /* Squish 2.0 */ +#define FORMAT_WC 6 /* Wildcat! 4.0 */ +#define NUM_FORMATS 7 + + +typedef struct { + word hdrsize; /* sizeof(AREAFILE_HDR) */ + word recsize; /* sizeof(AREAFILE_GE) */ + word maxconnections; /* Maximum number of entries in connections list */ +} AREAFILE_HDR; + + +typedef struct { + char name[51]; /* Area name must be uppercase, no spaces */ + char comment[61]; /* Description of the topics discussed in area */ + char path[51]; /* Path where the *.MSG files are stored */ + char originline[61]; /* Custom origin line, used if origlinenr = 0 */ + word areanumber; /* Area number (1-200 = Hudson) */ + byte group; /* Group (0-255) */ + word options; /* See --- Area option bits */ + byte originlinenr; /* Origin line (1-20, 0 = custom) */ + byte pkt_origin; /* Address for the packet/Origin line (0-31) */ + dword seenbys; /* Addresses (bits 0-31) to add to the SEEN-BY */ + word maxmsgs; /* Maximum number of messages (MBUTIL Purge) */ + word maxdays; /* Maximum age of non-Rcvd messages (MBUTIL Purge) */ + word maxrcvddays; /* Maximum age of Rcvd messages (MBUTIL Purge) */ + byte areatype; /* See --- Area type */ + byte areaformat; /* See --- Area format */ + byte extraoptions; /* See --- Extra area option bits */ +} AREAFILE_GE; + +/* --- Connection entry status bits */ + +#define CONN_NOIMPORT 0x01 /* Don't accept mail from this node */ +#define CONN_NOEXPORT 0x02 /* Don't forward mail to this node */ +#define CONN_PAUSE 0x04 /* Temporary don't send this area to this node */ +#define CONN_NOUNLINK 0x08 /* Don't allow this node to disconnect */ +#define CONN_ISUPLINK 0x10 /* Node is uplink for this area */ + +/* --- Connections list entry */ + +typedef struct { + ftn_addr address; + byte status; +} CONNECTION; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_im160.h b/goldlib/gcfg/gs_im160.h new file mode 100644 index 0000000..c9f0813 --- /dev/null +++ b/goldlib/gcfg/gs_im160.h @@ -0,0 +1,329 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1992-1994 by Andreas Klein +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// IMail Definitions and Structures +// ------------------------------------------------------------------ + +#ifndef __gs_im160_h +#define __gs_im160_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +#define IMAIL_MAJ_VERSION 1 +#define IMAIL_MIN_VERSION 60 +#define IMAIL_MAJ_VERSION_STR "1" +#define IMAIL_MIN_VERSION_STR "60" +#define STRUCT_MAJ_VERSION 4 +#define STRUCT_MIN_VERSION 01 +#define IM_PRD_CODE 0x4B + +// Data type definitions + +typedef unsigned char bit; + +// Internal limits + +#define MAXAKAS 16 /* Max # of addresses */ +#define MAXPACKERS 11 /* Max # of packer def */ +#define MAXEXPORT 200 /* Max export defs */ +#define MAXVIA 40 /* max nodes packed via */ +#define MAXGROUPS 26 /* max nodes packed via */ +#define MAXEXCEPT 10 /* max EXCEPT nodes */ +#define MAXPACK 32 /* max default pack cmd */ +#define MAXFWDLINK 15 /* max fwd link structs */ +#define MAXNOIMPT 20 /* max # names for IMPORT */ +#define MAXSYSNAME 20 /* max # names for PERSMAIL */ +#define ZONESDOM 10 /* zones per domain entry */ +#define MAXTAG 51 /* max areatag length */ +#define MAXNAME 37 /* max namefield lenght */ +#define MAXPACKNAME 50 /* max packer length */ +#define MAXORIGIN 64 /* max origin length */ + +// Message Base Types + +#ifndef MSGTYPE_SDM + #define MSGTYPE_SDM 0x01 +#endif +#ifndef MSGTYPE_SQUISH + #define MSGTYPE_SQUISH 0x02 +#endif +#ifndef MSGTYPE_HUDSON + #define MSGTYPE_HUDSON 0x03 +#endif +#ifndef MSGTYPE_JAM + #define MSGTYPE_JAM 0x04 +#endif +#ifndef MSGTYPE_PASSTH + #define MSGTYPE_PASSTH 0x0F +#endif +#ifndef MSGTYPE_ECHO + #define MSGTYPE_ECHO 0x80 +#endif +#ifndef MSGTYPE_LOCAL + #define MSGTYPE_LOCAL 0x90 +#endif +#ifndef MSGTYPE_NET + #define MSGTYPE_NET 0xA0 +#endif + +#define BASEMASK 0x0F +#define TYPEMASK 0xF0 + +// In case your compiler doesn't have these ... + +#ifndef IMAXPATH + #define IMAXPATH 80 +#endif +#ifndef IMAXDRIVE + #define IMAXDRIVE 3 +#endif +#ifndef IMAXDIR + #define IMAXDIR 66 +#endif +#ifndef IMAXFILE + #define IMAXFILE 9 +#endif +#ifndef IMAXEXT + #define IMAXEXT 5 +#endif + + +// Structs used in IMAIL Configuration files + +struct eaddress { /* used in Area Manager ... */ + ftn_addr dstn; /* node number */ + bit exp_only:1; /* export only flag */ + bit imp_only:1; /* import only flag */ + bit paused:1; /* echo mail paused */ + bit rsvd1:5; /* reserved */ +}; + +struct fwd_link { /* used for forward request nodes ... */ + char areasfile[IMAXFILE+IMAXEXT]; /* name of areas file */ + char toprogram[10]; /* name of area manager */ + char password[21]; /* area manager password */ + ftn_addr uplink; /* address of uplink */ + char accessgrp; /* accessgroup for forwarding */ + char creategrp; /* creategroup for forwarding */ + char filler[10]; /* reserved */ +}; + +struct dom { + char domain[21]; /* name of domain */ + char outbound[IMAXPATH]; /* root outbound path */ + word zones[ZONESDOM]; /* Zones in this domain */ + byte akas[MAXAKAS]; /* =my= AKAs in this domain */ +}; + +struct im_stats { + long th_day_nr; /* nr this day */ + long la_day_nr; /* nr last day */ + long th_week_nr; /* nr this week */ + long la_week_nr; /* nr last week */ + long th_month_nr; /* nr this month */ + long la_month_nr; /* nr last month */ + long th_year_nr; /* nr this year */ + long la_year_nr; /* nr last year */ + long th_day_size; /* amount this day */ + long la_day_size; /* amount last day */ + long th_week_size; /* amount this week */ + long la_week_size; /* amount last week */ + long th_month_size; /* amount this month */ + long la_month_size; /* amount last month */ + long th_year_size; /* amount this year */ + long la_year_size; /* amount last year */ +}; + + +// IMAIL.CF structure + +struct im_config_type { + byte im_ver_maj; /* Major Version */ + byte im_ver_min; /* Minor Version */ + byte struct_maj; /* reserved */ + byte struct_min; /* reserved */ + char sysop[MAXNAME]; /* name of sysop */ + ftn_addr aka[MAXAKAS]; /* the AKAs */ + struct dom domains[MAXAKAS]; /* domain names & zones */ + byte rsvd1[10]; /* reserved */ + char netmail[IMAXPATH]; /* net mail subdirectory */ + char netfile[IMAXPATH]; /* inbound files directory */ + char in_pkt[IMAXPATH]; /* Directory for inbound PKTs */ + char out_pkt[IMAXPATH]; /* Directory for outbound PKTs */ + char outbound[IMAXPATH]; /* outbound directory */ + char quickbbs[IMAXPATH]; /* QuickBBS system directory */ + char uns_netfile[IMAXPATH]; /* unsecured inbound files */ + char echotoss[IMAXPATH]; /* name of echotoss.log */ + char dupebase[IMAXPATH]; /* dupe data base directory */ + char semaphor[IMAXPATH]; /* Semaphor directory */ + char logfilename[IMAXPATH]; /* Log file name */ + char before_toss[IMAXPATH]; /* call before proc. a PKT */ + char semaphor_net[IMAXFILE+IMAXEXT]; /* Netmail rescan semaphor file */ + char alnk_help[IMAXFILE+IMAXEXT]; /* AreaLink help text */ + char maint_help[IMAXFILE+IMAXEXT]; /* Alnk Remote Maint. Helptext */ + char rsvd2[IMAXFILE+IMAXEXT]; /* reserved */ + char dflt_origin[MAXORIGIN]; /* default origin line */ + bit rtnrecpt:1; /* True if to send rtn recpt */ + bit del_empty_msg:1; /* delete empty netmails (TOSS) */ + bit ARCmail06:1; /* ARCmail 0.6 compatibility */ + bit use_crc_names:1; /* use crc-names for auto-areas */ + bit rsvd3:1; /* reserved */ + bit multi_tasking:1; /* true if multi-tasking */ + bit ignore_unknown:1; /* ALNK ignores unknown systems */ + bit singleextract:1; /* extract 1 bundle at a time */ + bit trunc_sent:1; /* 1 = Trunc 0 = Delete */ + bit keep_alnk_answ:1; /* keep arealink answer */ + bit prod_names:1; /* use the FTSC product list */ + bit swap_ems:1; /* swap to EMS */ + bit swap_ext:1; /* swap to extended memory */ + bit forward_everything:1; /* forward req. not in fwd-lists */ + bit direct_video:1; /* use direct screen writing */ + bit rsvd4:1; /* reserved */ + bit compr_after_pkt:1; /* compress after each PKT? */ + bit delete_bases:1; /* when removing an area, */ + /* delete also squish/msg-base */ + bit rsvd5:1; /* reserved */ + bit use_imcomp:1; /* call IMCOMP in case of tight */ + /* diskspace or abort at once */ + bit rsvd6:4; /* reserved */ + long last_run; /* last maintenance run */ + word rsvd7; /* reserved */ + byte rsvd8; /* reserved */ + byte rsvd9; /* reserved */ + word max_arcmail_size; /* max size of arcmail bundles */ + word pwd_expire_days; /* days before pwd expr'd */ + word max_pkt_size; /* max size of pkt to create */ + byte max_add_pkt; /* PKTs to compress in one run */ + byte pkt_not_for_us; /* how to handle PKTs not for us */ + byte environment; /* FroDo, Binkley or Intermail */ + byte max_msg_size; /* max size of netmail (split) */ + byte via_line; /* add Via Line to netmails */ + byte dupe_ring; /* Check for possible d-rings */ + byte cpd_check; /* circular path detection */ + byte pers_mail; /* use personal mail feature */ + byte unlink_req; /* Unlink areas without dlink */ + byte keep_alnk_req; /* keep arealink request */ + byte rsvd10; /* reserved */ + long max_dupes; /* max dupes kept in dbase */ + word max_files_per_dir; /* max. nr files when autocreate */ + byte deadlink_days; /* nr of days for a dealink req */ + byte rsvd11; /* reserved */ + char bbs_system; /* BBS software used */ + char new_areas[IMAXPATH]; /* name of file for new areas */ + word sp_before_unpack; /* min. diskspace required */ + word sp_before_toss; /* before decompress, toss */ + word sp_before_compress; /* and compress (in MB). */ + char kill_dead; /* Kill Dead Selection */ + word prod[20]; /* Type2+ product codes */ + char rsvd12[720]; /* reserved */ + struct fwd_link fwd[MAXFWDLINK]; /* forward link requests */ + char echojam[IMAXPATH]; /* path to ECHOMAIL.JAM */ + char before_toss_ii[IMAXPATH]; /* call before proc. the PKTs */ + char userbase[IMAXPATH]; /* path to the userbase */ + long stoptossmsgs; /* stop tossing after xxxxx msgs */ + long stoptossnetmsgs; /* stop tossing after xxxxx net */ + /* msgs within a PKT or at all */ + char ignorelist[IMAXPATH]; /* list of areas to suppress */ + char db_queue[IMAXPATH]; /* D'Bridge queue directory */ + long log_level; /* logging level */ + char att_status; /* Def. status of attach msg */ + char msg_status; /* Def. status of Alnk msgs */ + char filler[278]; /* reserved */ +}; + + +// IMAIL.AR structure + +struct areas_record_type { + char aname[MAXTAG]; /* area name */ + char comment[61]; /* area comment */ + char origin[MAXORIGIN]; /* origin line to use */ + char group; /* area group */ + char o_addr; /* address for origin */ + char use_akas[MAXAKAS]; /* addresses for seen-bys */ + byte msg_base_type; /* message base type */ + byte brd; /* board number */ + char msg_path[IMAXPATH]; /* MSG/Squish path */ + bit active:1; /* flag area active */ + bit zone_gate:1; /* Zone-gate stripping */ + bit tiny_seen:1; /* tiny seen-by flag */ + bit secure:1; /* secure flag */ + bit import_seen:1; /* import seen-by into base */ + bit deleted:1; /* flag deleted area */ + bit auto_added:1; /* flag auto-added record */ + bit mandatory:1; /* area is mandatory */ + bit read_only:1; /* area is read only */ + bit unlinked:1; /* area has been unlinked */ + bit ulnk_req:1; /* perform unlinked requests? */ + bit hidden:1; /* area is hidden */ + bit to_link:1; /* should by processed by LINK */ + bit check_dup:1; /* check for dupes in this area? */ + bit no_pause:1; /* %PAUSE not allowed in this echo? */ + bit hide_seen:1; /* Hide seens when importing */ + bit manual:1; /* No changes via Arealink */ + bit fwdreq_pending:1; /* Requested but yet not arrived */ + bit sqkillfly:1; /* Squish 'Kill on the fly' */ + bit dupe_msgid:1; /* Dupecheck on MSGID only? */ + bit deadlink_req:1; /* Deadlink request has been sent */ + bit rsvd:2; /* reserved */ + byte user_bits; /* 8 user-available bits */ + byte days; /* days to keep messages */ + word msgs; /* num messages to keep */ + struct im_stats stats; /* statistics */ + time_t creation; /* date/time of statistic start */ + time_t update; /* last update by midnight update */ + time_t marked; /* used by kill dead */ + byte kill_dead; /* kill echos without traffic */ + word read_sec; /* Security level for read access */ + word write_sec; /* Security level for write access */ + char filler[30]; + struct eaddress exp[MAXEXPORT]; /* export list */ +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_im175.h b/goldlib/gcfg/gs_im175.h new file mode 100644 index 0000000..acf797d --- /dev/null +++ b/goldlib/gcfg/gs_im175.h @@ -0,0 +1,349 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1992-1995 by Andreas Klein +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// IMail Definitions and Structures +// ------------------------------------------------------------------ + +#ifndef __gs_im160_h +#define __gs_im160_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +#define IMAIL_MAJ_VERSION 1 +#define IMAIL_MIN_VERSION 75 +#define IMAIL_MAJ_VERSION_STR "1" +#define IMAIL_MIN_VERSION_STR "80" +#define STRUCT_MAJ_VERSION 5 +#define STRUCT_MIN_VERSION 14 +#define IM_PRD_CODE 0x4B +#define BETA + +// Data type definitions + +typedef unsigned char bit; + +// Internal limits + +#define MAXAKAS 50 /* Max # of addresses */ +#define MAXPACKERS 11 /* Max # of packer def */ +#define MAXEXPORT 200 /* Max export defs */ +#define MAXVIA 40 /* max nodes packed via */ +#define MAXGROUPS 255 /* max nodes packed via */ +#define MAXEXCEPT 10 /* max EXCEPT nodes */ +#define MAXPACK 32 /* max default pack cmd */ +#define MAXFWDLINK 15 /* max fwd link structs */ +#define MAXNOIMPT 20 /* max # names for IMPORT */ +#define MAXSYSNAME 20 /* max # names for PERSMAIL */ +#define ZONESDOM 10 /* zones per domain entry */ +#define MAXTAG 51 /* max areatag length */ +#define MAXNAME 37 /* max namefield lenght */ +#define MAXPACKNAME 50 /* max packer length */ +#define MAXORIGIN 64 /* max origin length */ + +// Message Base Types + +#ifndef MSGTYPE_SDM + #define MSGTYPE_SDM 0x01 +#endif +#ifndef MSGTYPE_SQUISH + #define MSGTYPE_SQUISH 0x02 +#endif +#ifndef MSGTYPE_HUDSON + #define MSGTYPE_HUDSON 0x03 +#endif +#ifndef MSGTYPE_JAM + #define MSGTYPE_JAM 0x04 +#endif +#ifndef MSGTYPE_PASSTH + #define MSGTYPE_PASSTH 0x0F +#endif +#ifndef MSGTYPE_ECHO + #define MSGTYPE_ECHO 0x80 +#endif +#ifndef MSGTYPE_LOCAL + #define MSGTYPE_LOCAL 0x90 +#endif +#ifndef MSGTYPE_NET + #define MSGTYPE_NET 0xA0 +#endif + +#define BASEMASK 0x0F +#define TYPEMASK 0xF0 + +// In case your compiler doesn't have these ... + +#ifndef MAXPATH + #define MAXPATH 80 +#endif +#ifndef MAXDRIVE + #define MAXDRIVE 3 +#endif +#ifndef MAXDIR + #define MAXDIR 66 +#endif +#ifndef MAXFILE + #define MAXFILE 9 +#endif +#ifndef MAXEXT + #define MAXEXT 5 +#endif + +// Structs used in IMAIL Configuration files + +struct eaddress { /* used in Area Manager */ + ftn_addr dstn; /* node number */ + bit exp_only:1; /* export only flag */ + bit imp_only:1; /* import only flag */ + bit paused:1; /* echo mail paused */ + bit denied:1; /* access is denied */ + bit uplink:1; /* uplink */ + bit rsvd1:3; /* reserved */ +}; + +struct fwd_link { /* used in Forward Manager */ + char areasfile[MAXFILE+MAXEXT]; /* name of areas file */ + char toprogram[10]; /* name of area manager */ + char password[21]; /* area manager password */ + ftn_addr uplink; /* address of uplink */ + byte accessgroup; /* accessgroup for forwarding */ + byte creategroup; /* creategroup for forwarding */ + char filler[10]; /* reserved */ +}; + +struct dom { + char domain[21]; /* name of domain */ + char outbound[MAXPATH]; /* root outbound path */ + word zones[ZONESDOM]; /* Zones in this domain */ + byte akas[MAXAKAS]; /* =my= AKAs in this domain */ +}; + +struct im_stats { + unsigned long th_day_nr; /* nr this day */ + unsigned long la_day_nr; /* nr last day */ + unsigned long th_week_nr; /* nr this week */ + unsigned long la_week_nr; /* nr last week */ + unsigned long th_month_nr; /* nr this month */ + unsigned long la_month_nr; /* nr last month */ + unsigned long th_year_nr; /* nr this year */ + unsigned long la_year_nr; /* nr last year */ + unsigned long th_day_size; /* amount this day */ + unsigned long la_day_size; /* amount last day */ + unsigned long th_week_size; /* amount this week */ + unsigned long la_week_size; /* amount last week */ + unsigned long th_month_size; /* amount this month */ + unsigned long la_month_size; /* amount last month */ + unsigned long th_year_size; /* amount this year */ + unsigned long la_year_size; /* amount last year */ +}; + + +/* + * + * IMAIL.CF structure + * + */ + +struct im_config_type { + byte im_ver_maj; /* Major Version */ + byte im_ver_min; /* Minor Version */ + byte struct_maj; /* reserved */ + byte struct_min; /* reserved */ + char sysop[MAXNAME]; /* name of sysop */ + ftn_addr aka[MAXAKAS]; /* the AKAs */ + struct dom domains[MAXAKAS]; /* domain names & zones */ + byte rsvd1[10]; /* reserved */ + char netmail[MAXPATH]; /* net mail subdirectory */ + char sec_inbound[MAXPATH]; /* secure inbound files */ + char in_pkt[MAXPATH]; /* Directory for inbound PKTs */ + char out_pkt[MAXPATH]; /* Directory for outbound PKTs */ + char outbound[MAXPATH]; /* outbound directory */ + char quickbbs[MAXPATH]; /* QuickBBS system directory */ + char unsec_inbound[MAXPATH]; /* Unsecure inbound files */ + char echotoss[MAXPATH]; /* name of echotoss.log */ + char dupebase[MAXPATH]; /* dupe data base directory */ + char semaphor[MAXPATH]; /* Semaphor directory */ + char logfilename[MAXPATH]; /* Log file name */ + char before_toss[MAXPATH]; /* call before proc. a PKT */ + char semaphor_net[MAXFILE+MAXEXT]; /* Netmail rescan semaphor file */ + char alnk_help[MAXFILE+MAXEXT]; /* AreaLink help text */ + char maint_help[MAXFILE+MAXEXT]; /* Alnk Remote Maint. Helptext */ + char rsvd2[MAXFILE+MAXEXT]; /* reserved */ + char dflt_origin[MAXORIGIN]; /* default origin line */ + bit rtnrecpt:1; /* True if to send rtn recpt */ + bit del_empty_msg:1; /* delete empty netmails (TOSS) */ + bit ARCmail06:1; /* ARCmail 0.6 compatibility */ + bit use_crc_names:1; /* use crc-names for auto-areas */ + bit req_all_allowed:1; /* allow arealink +* command */ + bit multi_tasking:1; /* true if multi-tasking */ + bit ignore_unknown:1; /* ALNK ignores unknown systems */ + bit singleextract:1; /* extract 1 bundle at a time */ + bit trunc_sent:1; /* 1 = Trunc 0 = Delete */ + bit keep_alnk_answ:1; /* keep arealink answer */ + bit prod_names:1; /* use the FTSC product list */ + bit swap_ems:1; /* swap to EMS */ + bit swap_ext:1; /* swap to extended memory */ + bit forward_everything:1; /* forward req. not in fwd-lists */ + bit direct_video:1; /* use direct screen writing */ + bit close_at_end:1; /* close graphic window at end */ + bit compr_after_pkt:1; /* compress after each PKT? */ + bit delete_bases:1; /* when removing an area, */ + /* delete also squish/msg-base */ + bit quiet_packers:1; /* send packer output >NUL */ + bit use_imcomp:1; /* call IMCOMP in case of tight */ + /* diskspace or abort at once */ + bit sort_alnk_lists:1; /* sort ALNK lists by areatag */ + bit ulnk_hudson_passth:1; /* unlinked Hudson areas passth */ + bit compr_before_unpack:1; /* compress before unpacking */ + bit rsvd3:1; /* reserved */ + time_t last_run; /* last maintenance run */ + word rsvd4; /* reserved */ + byte rsvd5; /* reserved */ + byte rsvd6; /* reserved */ + word max_arcmail_size; /* max size of arcmail bundles */ + word pwd_expire_days; /* days before pwd expr'd */ + word max_pkt_size; /* max size of pkt to create */ + byte max_add_pkt; /* PKTs to compress in one run */ + byte pkt_not_for_us; /* how to handle PKTs not for us */ + byte environment; /* FroDo, Binkley or Intermail */ + byte max_msg_size; /* max size of netmail (split) */ + byte via_line; /* add Via Line to netmails */ + byte dupe_ring; /* Check for possible d-rings */ + byte cpd_check; /* circular path detection */ + byte pers_mail; /* use personal mail feature */ + byte unlink_req; /* Unlink areas without dlink */ + byte keep_alnk_req; /* keep arealink request */ + byte rsvd7; /* reserved */ + unsigned long max_dupes; /* max dupes kept in dbase */ + word max_files_per_dir; /* max. nr files when autocreate */ + byte deadlink_days; /* nr of days for a dealink req */ + byte rsvd8; /* reserved */ + char bbs_system; /* BBS software used */ + char new_areas[MAXPATH]; /* name of file for new areas */ + word sp_before_unpack; /* min. diskspace required */ + word sp_before_toss; /* before decompress, toss */ + word sp_before_compress; /* and compress (in MB). */ + char kill_dead; /* Kill Dead Selection */ + word prod[20]; /* Type2+ product codes */ + long setup_pwd_crc; /* Setup password (CRC) */ + char rule_path[MAXPATH]; /* path to the rule-files */ + char local_inbound[MAXPATH]; /* path to local PKTs (protected) */ + char rsvd9[556]; /* reserved */ + struct fwd_link fwd[MAXFWDLINK]; /* forward link requests */ + char echojam[MAXPATH]; /* path to ECHOMAIL.JAM */ + char before_toss_ii[MAXPATH]; /* call before proc. the PKTs */ + char userbase[MAXPATH]; /* path to the userbase */ + unsigned long stoptossmsgs; /* stop tossing after xxxxx msgs */ + unsigned long stoptossnetmsgs; /* stop tossing after xxxxx net */ + /* msgs within a PKT or at all */ + char ignorelist[MAXPATH]; /* list of areas to suppress */ + char db_queue[MAXPATH]; /* D'Bridge queue directory */ + long log_level; /* logging level */ + char att_status; /* Def. status of attach msg */ + char msg_status; /* Def. status of Alnk msgs */ + char filler[278]; /* reserved */ +}; + + +/* + * + * IMAIL.AR structure + * + */ + +struct areas_record_type +{ + char aname[MAXTAG]; /* area name */ + char comment[61]; /* area comment */ + char origin[MAXORIGIN]; /* origin line to use */ + byte grp; /* area group */ + char o_addr; /* address for origin */ + char use_akas[MAXAKAS]; /* addresses for seen-bys */ + byte msg_base_type; /* message base type */ + byte brd; /* board number */ + char msg_path[MAXPATH]; /* MSG/Squish path */ + bit active:1; /* flag area active */ + bit zone_gate:1; /* Zone-gate stripping */ + bit tiny_seen:1; /* tiny seen-by flag */ + bit secure:1; /* secure flag */ + bit import_seen:1; /* import seen-by into base */ + bit deleted:1; /* flag deleted area */ + bit auto_added:1; /* flag auto-added record */ + bit mandatory:1; /* area is mandatory */ + bit read_only:1; /* area is read only */ + bit unlinked:1; /* area has been unlinked */ + bit ulnk_req:1; /* perform unlinked requests? */ + bit hidden:1; /* area is hidden */ + bit to_link:1; /* should by processed by LINK */ + bit check_dup:1; /* check for dupes in this area? */ + bit no_pause:1; /* %PAUSE not allowed in this echo? */ + bit hide_seen:1; /* Hide seens when importing */ + bit manual:1; /* No changes via Arealink */ + bit fwdreq_pending:1; /* Requested but yet not arrived */ + bit sqkillfly:1; /* Squish 'Kill on the fly' */ + bit dupe_msgid:1; /* Dupecheck on MSGID only? */ + bit deadlink_req:1; /* Deadlink request has been sent */ + bit packing_pending:1; /* areas contains msgs deleted by KILL */ + bit rsvd:1; /* reserved */ + byte user_bits; /* 8 user-available bits */ + byte days; /* days to keep messages */ + word msgs; /* num messages to keep */ + struct im_stats stats; /* statistics */ + time_t creation; /* date/time of statistic start */ + time_t update; /* last update by midnight update */ + time_t marked; /* used by kill dead */ + byte kill_dead; /* kill echos without traffic */ + word read_sec; /* Security level for read access */ + word write_sec; /* Security level for write access */ + char rulename[MAXFILE+MAXEXT]; /* filename for the rule file */ + long msg_counter; /* Msg Counter only reset by PACK */ + char filler[12]; + struct eaddress exp[MAXEXPORT]; /* export list */ +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_inter.h b/goldlib/gcfg/gs_inter.h new file mode 100644 index 0000000..45cfe02 --- /dev/null +++ b/goldlib/gcfg/gs_inter.h @@ -0,0 +1,477 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1989-1994 Peter Stewart & InterZone Software, inc. +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// FD.SYS definitions for InterMail 2.2x +// ------------------------------------------------------------------ + +#ifndef __gs_inter_h +#define __gs_inter_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef struct { + + /* The logfile */ + + char log[71]; + word loglevel; /* See --- Loglevels */ + + /* Number manipulation */ + + char prefix[31]; /* Always added */ + char hidden[10][31]; /* Strip these if they are in # */ + char postfix[31]; /* Always appended */ + + /* Miscellaneous flags */ + + long flags; /* See --- Miscellaneous flags */ + long flags_reserved; /* Reserved flags */ + word audio; /* See --- Audio flags */ + byte synchtimer; /* Number of seconds for sync */ + + /* Errorlevels */ + + byte crashexit; /* Mail exit */ + byte bbs300; + byte bbs1200; + byte bbs1275; + byte bbs2400; + byte bbs4800; + byte bbs9600; + byte bbs19200; + byte bbs38400; + + /* Modem */ + + word modembaud; /* 30=300, 24=2400, etc. */ + byte modemport; /* 1-255 (COM1=1, COM2=2, etc.) */ + byte modemdelay; /* 1/10 seconds delay / line sent */ + + /* --- Messages */ + + char b300msg[16]; + char b1200msg[16]; + char b1275msg[16]; + char b2400msg[16]; + char b4800msg[16]; + char b9600msg[16]; + char b19200msg[16]; + char b38400msg[16]; + char errormsg[16]; + char busymsg[16]; + char carriermsg[16]; + char okmsg[16]; + char ringmsg[16]; + char nodialmsg[16]; + char noanswmsg[16]; + char voicemsg[16]; + + /* --- Commands */ + + char escapestr[11]; + char offhookstr[11]; + char reconnectstr[11]; + char init1[50]; + char init2[50]; + char init3[50]; + char resetstr[50]; + char downstr[50]; + char hangupstr[11]; + char dialstr[11]; + + /* --- Manual answer stuff */ + + char modemanswer[11]; + byte answerdelay; + + /* ------ Limited answer start and end times */ + + byte begin_hour; + byte begin_minute; + byte end_hour; + byte end_minute; + + /* Calling control */ + + byte retrybusy; + byte retryresend; + byte retrydelay; + + /* File request control */ + + char reqlist[71]; /* List to scan for reqable dirs */ + char reqalias[71]; /* Magic filenames */ + char reqmessage[71]; /* Appended to FAILED REQUEST message */ + byte reqtype; /* Bit field */ + byte reqmaxfiles; /* Max number of files to send on 1 req*/ + word reqmaxtime; /* Maximum number of minutes for req*/ + word reqmaxsize; /* Maximum size (in KB) for req */ + word reqminbaud; /* Minimum baudrate for req */ + byte reqstarthr; /* Start time for file requests, can be*/ + byte reqstartmin; /* combined with the reqdays field. */ + byte reqendhr; + byte reqendmin; + byte reqdays; + + /* File to send when human callers are let thru */ + + char bbsname[11]; + char beforebbsbanner[71]; + + /* Function keys from mailer menu */ + + struct { + char cmd[61]; + char title[26]; + byte behavior; /* 1-Pause, 2-Process msg base */ + } key[24]; + + /* Mailer colors */ + + byte color[11]; + + /* Number of days to keep entries in history files */ + + byte keep_history; + + /* FDServer password, if none given, server is INactive */ + + char slavepwd[21]; + + /* File displayed to users when system is in event for no callers */ + + char ineventfile[71]; + + /* File displayed when human callers are seen on mail-only system */ + + char mailonlyfile[71]; + + /* External programs to run on certain "wake-up" strings */ + + struct { + char wakeupstr[40]; + byte errorlevel; + } externmail[10]; + + /* RESERVED FIELD */ + + /* --- Limited audio start and end times. If the below four bytes + are all zero (0), audio is enabled all the time */ + + byte audio_begin_hour; + byte audio_begin_minute; + byte audio_end_hour; + byte audio_end_minute; + + /* --- Minimum cost to process undialable */ + + word min_undial_cost; + + char RESERVERAT[886]; + char extrnreq [71]; + char modem_name[61]; /* modem name, for 'modem selection' */ +} _mailer; + + +/* Netmail folder behavior */ + +#define RESTRICTED 0x00000001L +#define EXPORTOK 0x00000004L +#define USEXLATTABLES 0x00000008L +#define EDREADONLY 0x00000020L + +/* Echomail flags */ + +#define SAVEBAD 0x00000001L + +typedef struct { + char path[65]; /* Path if "board==0", otherwise empty (65) */ + byte ftype; /* Folder type */ + char areatag[39]; /* Echomail area tag */ + byte origin; /* Default origin line, 0-19 */ + char title[41]; /* Title to appear on screen */ + byte useaka; /* AKA to use, 0==primary */ + word board; /* QuickBBS/RemoteAccess/WC board number */ + word upzone; /* Uplink zone */ + word upnet; /* Uplink net */ + word upnode; /* Uplink node */ + word uppoint; /* Uplink point */ + long behave; /* Behavior, see above */ + long hiwater; /* Highwater mark for echomail */ + long pwdcrc; /* CRC32 of password or -1L if unprotected */ + long userok; /* Users with initial access */ + long accflags; /* access flags, for network environment */ + char reserved[8]; /* for future expansion */ +} _eFOLDER; + +#define MSGPRIVATE 0x0001 +#define MSGCRASH 0x0002 +#define MSGREAD 0x0004 +#define MSGSENT 0x0008 +#define MSGFILE 0x0010 +#define MSGTRANSIT 0x0020 +#define MSGORPHAN 0x0040 +#define MSGKILL 0x0080 +#define MSGLOCAL 0x0100 +#define MSGHOLD 0x0200 +#define MSGUNUSED 0x0400 +#define MSGFREQ 0x0800 +#define MSGRRREQ 0x1000 +#define MSGISRR 0x2000 +#define MSGAREQ 0x4000 +#define MSGFUPDREQ 0x8000 + +typedef struct { + + /* Macro keys */ + + char macrokey[24][61]; /* F1-F12, Shift F1-F12 */ + + /* Margin, default==60 */ + + byte margin; + + /* Default message status */ + + word msgbits; + + /* Miscellaneous settings */ + + long flags; + + /* Origin lines */ + + char origin[20][61]; + + /* Editor colors */ + + byte color[15]; + + /* Netmail folder flags */ + + long netfolderflags; + + /* Translation tables IN/OUT */ + + byte translate_in[256]; + byte translate_out[256]; + + /* Where RemoteAccess/QuickBBS message base files are */ + + char qbase[71]; + char WCmain[71]; + + /* RESERVED */ + + char RESERVERAT[255]; + long echoflags; + _eFOLDER BBSnet; + _eFOLDER dupes; + _eFOLDER badecho; + char echolog[65]; + char IMEWork[71]; + +} _editor; + +typedef struct { + char systempath[71]; + char mailpath[71]; + char swap_path[71]; + char semaphore[71]; + char secfilespath[71]; + char infilepath[71]; + char packetpath[71]; + char nodelistpath[71]; + + word countrycode; + + ftn_addr aka[11]; + + /* Timeout value for screen blanker in SECONDS (0-255) */ + + long flags; + byte blackout_time; + + /* User record */ + + struct { + char name[37]; + long pwdcrc; /* Crc-32 of user password, -1L No pwd */ + dword flags; + } user[10]; + + /* Protection of exits */ + + dword exitpwdcrc; /* Password for DOS shell, exits, etc. */ + dword exitflags; /* Which flags should be protected */ + char filler[760]; /* contains domain stuff */ + char systemname[50]; /* site_info - system name */ + char systemloc[40]; /* site_info - location */ + char systemphone[24]; /* site_info - phone */ + char fill[6]; /* 6 loose bytes :) */ + char systemflags[20]; /* site_info - nodelist flags */ + char systemcountry[26]; /* site_info - country */ + char serial[14]; /* serial number */ + char outecho[66]; /* outbound echomail packets */ + char reserved[10]; /* reserved space */ +} _shared; + +typedef struct { + char initstring[41]; /* Init string */ + word scrollsize; /* Max memory to use for buffer (in K) */ + byte emulation; /* 0=TTY, 1=ANSI, 2=VT52, 3=VT100 */ + byte protocol; /* Index in protocol list */ + char shiftkey[12][31]; /* Shift F1-F12 macro settings */ + char ctrlkey[12][31]; /* Ctrl F1-F12 macro settings */ + char downloadpath[60]; /* Default download path */ + char uploadpath[60]; /* Default upload path */ + byte translate_in[256]; /* Translation table - modem->screen */ + byte translate_out[256]; /* Translation table - screen->modem */ + byte retrywait; /* Seconds to wait before next dial.. */ + dword flags; /* Behavior, sounds, flashes.. etc. */ + dword directorypwd; /* CRC-32 of password to enter phoneDir*/ + char editor[60]; /* Invoked with Alt-I */ + char RESERVERAT[796]; /* Reserved space */ + ftn_addr newaka[21]; +} _terminal; + +typedef struct { + char port; /* 0 LPT1, 1 LPT2, 2 LPT3, 3 COM1, 4 COM2 */ + char baud; /* 0 9600, 1 4800, 2 2400, 3 1200 */ + byte stopbits; /* 0x00 - 1, 0x01 - 2 */ + byte wordlength; /* 0x00 - 7, 0x01 - 8 */ + byte parity; /* 0x00 - Even, 0x01 - Odd, 0x02 - None */ + byte pagelen; + long behavior; + char init[71]; + char reset[71]; + char bold_on[31]; + char bold_off[31]; + char pr1RESERVED[62]; + char italic_on[31]; + char italic_off[31]; + byte pagewidth; /* Width in columns of a page */ + byte leftmargin; /* Left margin, ie. start printing at column*/ + byte footer; /* Footer margin, ie. leave nn lines */ + byte header; /* Header margin, ie. skip nn lines */ + byte translate_out[256]; /* Translation table - disk->printer */ + char pr2RESERVED[100]; +} _printer; + +#define IM_THISREV 0x0100 + +struct _ctl { + char fingerprint[5]; /* Must contain "JoHo" */ + word sysrev; /* Must contain THISREV above */ + dword ctlcrc; /* CRC-32 of struct excluding the 1st 11 bytes */ + _mailer m; + _editor e; + _shared s; + _terminal t; + _printer p; + dword ctlcrc2; /* CRC-32 of all the above */ +}; + +// Constant long bit values + +#define RESTRICT 0x00000001L +#define ECHO_INFO 0x00000002L +#define EXPORT_OK 0x00000004L +#define USE_XLAT 0x00000008L +#define PRIVATE 0x00000010L +#define READONLY 0x00000020L +#define F_NETMAIL 0x08000000L +#define BOARDTYPE 0x10000000L +#define DELETED 0x20000000L /* Never written to disk */ +#define LOCAL 0x40000000L +#define ECHOMAIL 0x80000000L + +#define F_MSG 0 +#define F_HUDSON 1 +#define F_WC35 2 +#define F_PCB15 3 +#define F_JAM 4 + +// Folder structure + +typedef struct { + char path[65]; /* Path if "board==0", otherwise empty (65) */ + byte ftype; /* Folder type */ + char areatag[39]; /* Echomail area tag */ + byte origin; /* Default origin line, 0-19 */ + char title[41]; /* Title to appear on screen */ + byte useaka; /* AKA to use, 0==primary */ + word board; /* QuickBBS/RemoteAccess/WC conf number */ + word upzone; /* Uplink zone */ + word upnet; /* Uplink net */ + word upnode; /* Uplink node */ + word uppoint; /* Uplink point */ + long behave; /* Behavior, see above */ + long hiwater; /* Highwater mark for echomail */ + long pwdcrc; /* CRC32 of password or -1L if unprotected */ + long userok; /* Users with initial access */ + long accflags; /* access flags, for network environment */ + long timestamp; /* Time stamp for detecting msg base updates*/ + char reserved[4]; /* for future expansion */ +} FOLDER; + +// The following struct was used in IM 2.00-2.25, file name FOLDER.CFG. + +typedef struct { + char path[65]; /* Path if "board==0", otherwise empty (65) */ + char title[41]; /* Title to appear on screen */ + byte origin; /* Default origin line, 0-19 */ + long behave; /* Behavior, see above */ + long pwdcrc; /* CRC32 of password or -1L if unprotected */ + long userok; /* Users with initial access */ + byte useaka; /* AKA to use, 0==primary */ + word board; /* QuickBBS/RemoteAccess/WC board number */ +} OLDFOLDER; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_lo240.h b/goldlib/gcfg/gs_lo240.h new file mode 100644 index 0000000..aadb546 --- /dev/null +++ b/goldlib/gcfg/gs_lo240.h @@ -0,0 +1,526 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (c) 1989-1994 by Marco Maccaferri +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// LoraBBS Ver. 2.40 structures +// ------------------------------------------------------------------ + +#ifndef __gs_lora240_h +#define __gs_lora240_h + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef unsigned char bits; + +#define MAXFLAGS 4 + +#define SIZEOF_MSGAREA 512 +#define SIZEOF_FILEAREA 640 + +struct _sysmsg { /* Structure for the internal system records. + The files SYSMSG.DAT and SYSFILE.DAT + are composed by the respective portions of this + structure */ + + char msg_name[70]; /* Message area name */ + short msg_num; /* Message area number */ + char msg_path[40]; /* Message area path */ + char origin[56]; /* Echomail origin line */ + bits echomail :1; /* 1=Echomail area */ + bits netmail :1; /* 1=Netmail area */ + bits dopublic :1; /* 1=Public message allowed */ + bits doprivate :1; /* 1=Private message allowed */ + bits anon_ok :1; /* 1=Use the user's handle in the from field */ + bits no_matrix :1; /* (**) */ + bits squish :1; /* Squish message area */ + bits kill_unlisted :1; /* (**) */ + word msg_sig; /* Message area's group */ + char echotag[32]; /* Echotag name */ + word pip_board; /* Pip-base board number */ + byte quick_board; /* QuickBBS board number */ + byte msg_priv; /* Minimum level to access this area */ + long msg_flags; /* Flags settings */ + byte write_priv; /* Minimum level to write messages */ + long write_flags; /* Flags settings */ + byte use_alias; /* Use alias # with this area */ + short max_msgs; /* Maximum number of messages in this area */ + short max_age; /* Max age of messages (days) */ + short age_rcvd; /* Max age of received messages (days) */ + char forward1[80]; /* Forward node list 1/3 */ + char forward2[80]; /* Forward node list 2/3 */ + char forward3[80]; /* Forward node list 3/3 */ + bits msg_restricted :1; /* Access restricted to message area's group */ + bits passthrough :1; /* Pass-through area */ + byte areafix; /* Areafix access level for that area */ + char qwk_name[14]; /* Short name used by the QWK mail packer */ + long afx_flags; /* Areafix flags */ + word gold_board; /* Goldbase board number */ + char filler1[27]; +}; + +/* Privilege levels definitions */ + +#define TWIT 0x10 +#define DISGRACE 0x20 +#define LIMITED 0x30 +#define NORMALx 0x40 +#define WORTHY 0x50 +#define PRIVIL 0x60 +#define FAVORED 0x70 +#define EXTRA 0x80 +#define CLERK 0x90 +#define ASSTSYSOP 0xA0 +#define SYSOP 0xB0 +#define HIDDEN 0xC0 + +#define NOCHANGE 0 +#define WFC 1 +#define LOGIN 2 +#define BROWSING 3 +#define UPLDNLD 4 +#define READWRITE 5 +#define DOOR 6 +#define CHATTING 7 +#define QUESTIONAIRE 8 +#define QWKDOOR 9 + +struct _useron { /* Structure for the USERON.BBS file */ + char name[36]; /* User's name */ + short line; /* Task number currently on */ + long baud; /* Baud rate */ + char city[26]; /* User's city */ + bits donotdisturb: 1; /* Do not disturb flag */ + bits priv_chat : 1; /* (**) */ + short line_status; /* User's status (numeric value) */ + short cb_channel; /* CB Chat System channel */ + char status[32]; /* User's status (string) */ +}; + +struct _lastcall { /* Structure for the LASTCALL.BBS file */ + + short line; /* Task number */ + char name[36]; /* User's name */ + char city[26]; /* User's city */ + word baud; /* Baud rate */ + long times; /* Times the user has called the system */ + char logon[6]; /* Logon time HH:MM */ + char logoff[6]; /* Logoff time HH:MM */ + long timestamp; /* Logout time-stamp (binary format) */ +}; + +#define MAX_ALIAS 20 +#define MAX_LANG 20 + +struct _alias { + short zone; /* Zone number */ + short net; /* Net number */ + short node; /* Node number */ + short point; /* Point number */ + word fakenet; /* Fake net number */ + char *domain; /* (**) */ +}; + +struct class_rec { + short priv; /* Access level */ + short max_time; /* Dayly time limit */ + short max_call; /* Per call time limit */ + short max_dl; /* Default download limit */ + short dl_300; /* Speed specific download limit */ + short dl_1200; /* Speed specific download limit */ + short dl_2400; /* Speed specific download limit */ + short dl_9600; /* Speed specific download limit */ + word ratio; /* Download/Upload ratio */ + word min_baud; /* Minimum login speed */ + word min_file_baud; /* Minimum file transfer speed */ + word start_ratio; /* Start ratio after some downloads */ +}; + +struct _configuration { /* Structure for the CONFIG.DAT file */ + + short version; /* Configuration file version */ + + char sys_path[40]; /* System directory */ + + char log_name[40]; /* Log file name */ + char log_style; /* Type of log: 0=Verbose, 1=Short */ + + char sched_name[40]; /* Scheduler file name */ + char user_file[40]; /* User's file base name (w/o extension) */ + + char norm_filepath[40]; /* Unknow nodes inbound */ + char know_filepath[40]; /* Know nodes inbound */ + char prot_filepath[40]; /* Protected nodes inbound */ + char outbound[40]; /* Outbound base directory */ + char netmail_dir[40]; /* Netmail directory */ + char bad_msgs[40]; /* Bad messages directory */ + char dupes[40]; /* Dupe messages directory */ + char quick_msgpath[40]; /* QuickBBS (Hudson) message base path */ + char pip_msgpath[40]; /* Pip-base path */ + char ipc_path[40]; /* Temporary files storage */ + char net_info[40]; /* Nodelist directory */ + char glob_text_path[40]; /* Text files path */ + char menu_path[40]; /* Menu/Languages path */ + char flag_dir[40]; /* Activity flags directory */ + + long keycode; /* Registration key code (<2.33) */ + + char about[40]; /* 'ABOUT' file to send */ + char files[40]; /* 'FILES' file to send */ + short norm_max_kbytes; /* Unknow nodes f/req. kbytes limit */ + short prot_max_kbytes; /* Protected nodes f/req. kbytes limit */ + short know_max_kbytes; /* Know nodes f/req. kbytes limit */ + short norm_max_requests; /* Unknow nodes f/req. files limit */ + short prot_max_requests; /* Protected nodes f/req. files limit */ + short know_max_requests; /* Know nodes f/req. files limit */ + char def_pack; /* Default packer */ + + char enterbbs[70]; /* 'Press ESC to enter the BBS' */ + char banner[70]; /* Initial mailer banner */ + char mail_only[70]; /* Mail only banner */ + + short com_port; /* Serial port (0-based) */ + short old_speed; /* Obsolete */ + char modem_busy[20]; /* Modem busy command */ + char dial[20]; /* Modem default dial command */ + char init[40]; /* Modem initialization command */ + char term_init[40]; /* Terminal mode initialization command */ + + byte mustbezero; /* Must be zero */ + + byte echomail_exit; /* (**) */ + byte netmail_exit; /* (**) */ + byte both_exit; /* (**) */ + + long speed; /* Modem initial speed */ + + byte filler[12]; /* (**) */ + + struct _altern_dial { /* Alternative dialing commands */ + char prefix[20]; /* Prefix command */ + char suffix[20]; /* Suffix command */ + } altdial[10]; + + bits lock_baud :1; /* 1=Lock serial port to speed baud */ + bits ansilogon :2; /* 0=No ansi at logon, 1=Detect, 2=Ask, 3=Yes */ + bits birthdate :1; /* 1=Ask for birthdate */ + bits voicephone :1; /* 1=Ask for voice phone */ + bits dataphone :1; /* 1=Ask for data phone */ + bits emsi :1; /* 1=EMSI sessions enabled */ + bits ibmset :1; /* 1=Ask for IBM set display */ + + bits wazoo :1; /* 1=WAZOO sessions enabled */ + bits msgtrack :1; /* (**) */ + bits keeptransit :1; /* 1=Keep in-transit netmail */ + bits hslink :1; /* 1=HS-Link enabled */ + bits puma :1; /* 1=Puma enabled */ + bits secure :1; /* 1=Check import messages */ + bits janus :1; /* 1=Janus protocol enabled */ + bits terminal :1; /* 1=Null modem connections */ + + bits fillerbug :1; /* (**) */ + bits no_direct :1; /* 1=Use BIOS screen writes */ + bits snooping :1; /* 1=Snoop user on-line */ + bits snow_check :1; /* 1=CGA snow check */ + bits unpack_norm :1; /* (**) */ + bits unpack_know :1; /* (**) */ + bits unpack_prot :1; /* (**) */ + + short blank_timer; /* Screen blanker timeout in minutes */ + + struct _language { /* Languages available for the users */ + char txt_path[30]; /* Text files directory */ + char descr[24]; /* Description */ + char basename[10]; /* Base file name */ + } language[MAX_LANG]; + + char sysop[36]; /* Sysop name */ + char system_name[50]; /* System name */ + char location[50]; /* System's location */ + char phone[32]; /* System's phone number */ + char flags[50]; /* System's flags */ + + struct _alias alias[MAX_ALIAS]; /* Network addresses */ + + char newareas_create[50]; /* Nodes that can create new areas */ + char newareas_link[50]; /* Nodes that are linked to new areas */ + + short line_offset; /* Task number */ + short min_calls; /* (**) */ + short vote_limit; /* (**) */ + short target_up; /* (**) */ + short target_down; /* (**) */ + byte vote_priv; /* (**) */ + byte max_readpriv; /* (**) */ + + word speed_graphics; /* Speed for ANSI/Avatar graphics */ + + byte aftercaller_exit; /* After caller exit errorlevel */ + byte aftermail_exit; /* After mail exit errorlevel */ + short max_connects; /* (**) */ + short max_noconnects; /* (**) */ + + byte logon_level; /* New users level */ + long logon_flags; /* New users flags */ + + char areachange_key[4]; /* Hotkeys for the change area command */ + char dateformat[20]; /* Format of the date fields */ + char timeformat[20]; /* Format fo the time fields */ + char external_editor[50]; /* External BBS message editor */ + + struct class_rec uclass[12]; /* Access level definitions */ + + char local_editor[50]; /* Local message editor */ + + char QWKDir[40]; /* QWK mail packer work directory */ + char BBSid[10]; /* QWK board name */ + word qwk_maxmsgs; /* Maximum number of messages for QWK packets */ + + char galileo[30]; /* Clocksynch phone number */ + + char norm_okfile[40]; /* Unknow request list */ + char know_okfile[40]; /* Know request list */ + char prot_okfile[40]; /* Protected request list */ + + char reg_name[36]; /* (**) */ + long betakey; /* */ + + struct _packers { /* Mail packers */ + char id[10]; /* Short name */ + char packcmd[30]; /* Pack commands */ + char unpackcmd[30]; /* unpack commands */ + } packers[10]; + + struct _nl { /* Nodelist database */ + char list_name[14]; /* Nodelist base name */ + char diff_name[14]; /* Nodediff base name */ + char arc_name[14]; /* (**) */ + } nl[10]; + + bits ansigraphics :2; /* 0=No Ansi, 1=Yes, 2=Ask */ + bits avatargraphics :2; /* 0=No Avatar, 1=Yes, 2=Ask */ + bits hotkeys :2; /* 0=No hotkeyed menu, 1=Yes, 2=Ask */ + bits screenclears :2; /* 0=No screen clears, 1=Yes, 2=Ask */ + + bits autozmodem :1; /* Terminal mode auto zmodem download */ + bits avatar :1; /* Terminal mode Avatar emulation */ + bits moreprompt :2; /* 0=No more prompt, 1=Yes, 2=Ask */ + bits mailcheck :2; /* 0=No mail check, 1=Yes, 2=Ask */ + bits fullscrnedit :2; /* 0=No full screen editor, 1=Yes, 2=Ask */ + + bits fillerbits :2; /* (**) */ + bits ask_protocol :1; /* 1=Ask default protocol */ + bits ask_packer :1; /* 1=Ask default packer */ + bits put_uploader :1; /* 1=Put uploader name in files.bbs */ + bits keep_dl_count :1; /* 1=Keep count of download times */ + bits use_areasbbs :1; /* 1=Use the areas.bbs file */ + bits write_areasbbs :1; /* 1=Keep the areas.bbs file up to date */ + + short rookie_calls; /* Number of calls for new users to be a rookie */ + + char pre_import[40]; /* Pre import batch */ + char after_import[40]; /* After import batch */ + char pre_export[40]; /* Pre export batch */ + char after_export[40]; /* After export batch */ + + byte emulation; /* (**) */ + char dl_path[40]; /* Terminal emulator download path */ + char ul_path[40]; /* terminal emulator upload path */ + + bits manual_answer :1; /* Manually answers phone */ + bits limited_hours :1; /* Answer only at certain hours */ + bits solar :1; /* (**) */ + bits areafix :1; /* 1=Use internal areafix */ + bits doflagfile :1; /* 1=Log semaphores creation/deletion */ + bits multitask :1; /* 1=Multitasking environment */ + bits ask_alias :1; /* 1=Ask for an alias name */ + bits random_birth :1; /* 1=Random birthdate check */ + + short start_time; /* Answer start time in minutes */ + short end_time; /* Answer end time in minutes */ + + char boxpath[40]; /* User's filebox base directory */ + char dial_suffix[20]; /* Dialing suffix command */ + + char galileo_dial[40]; /* Clocksynch dialing command */ + char galileo_suffix[40]; /* Clocksynch dialing suffix command */ + char galileo_init[40]; /* Clocksynch initialization command */ + + char areafix_help[40]; /* Areafix's help file name */ + char alert_nodes[50]; /* Nodes that receives a copy of all areafix response messages */ + + char automaint[40]; /* Batch to execute once a day */ + + byte min_login_level; /* Minimum login level */ + long min_login_flags; /* Minimul login flags */ + byte min_login_age; /* Minimul login age */ + + char resync_nodes[50]; /* Nodes to resynch the clock with */ + char bbs_batch[40]; /* External BBS batch file */ + byte altx_errorlevel; /* ALT-X command errorlevel */ + + char fax_response[20]; /* FAX response */ + byte fax_errorlevel; /* Fax exit errorlevel */ + + char dl_counter_limits[4]; /* Download counter delimiters */ + + char areas_bbs[40]; /* AREAS.BBS path and file name */ + byte afx_remote_maint; /* Areafix level for %FROM command */ + byte afx_change_tag; /* Areafix level for #: command */ + + bits allow_rescan :1; /* 1=Allow rescan of new areas */ + bits check_city :1; /* 1=Check user's city at logon */ + bits check_echo_zone :1; /* 1=Check zones in areafix's requests */ + bits save_my_mail :1; /* 1=Save mail directed to the Sysop */ + bits mail_method :2; /* 0=Separate netmail, 1=Net & echomail */ + /* in the same packet */ + bits replace_tear :2; /* 0=No, 1=Link unlimited, 2=Link */ + /* limited to 35 char, 3=Always */ + + char my_mail[40]; /* Path to Sysop's mail */ + + bits stripdash :1; /* 1=Strip dashes from phone numbers */ + bits use_iemsi :1; /* 1=Allows IEMSI logins */ + bits newmail_flash :1; /* 1=Flashing MAIL active */ + bits mymail_flash :1; /* 1=Flashing PERSONAL active */ + bits keep_empty :1; /* 1=Do not import empty netmail */ + bits show_missing :1; /* 1=Show missing files in file listings */ + bits random_redial :1; /* 1=Redial numbers at random time */ + + char override_pwd[20]; /* Mail only override password */ + char pre_pack[40]; /* Pre-PACK DOS command */ + char after_pack[40]; /* After-PACK DOS command */ + + byte modem_timeout; /* Modem answer timeout (seconds) */ + byte login_timeout; /* User's login timeout (minutes) */ + byte inactivity_timeout; /* User's inactivity timeout (seconds) */ + + struct _altern_prefix { + char flag[6]; /* Nodelist flag (HST,V32B,etc.) */ + char prefix[20]; /* Dialing prefix */ + } prefixdial[10]; + + char iemsi_handle[36]; /* IEMSI: User's handle name */ + char iemsi_pwd[20]; /* IEMSI: Password */ + short iemsi_infotime; /* IEMSI: Seconds to display server */ + /* informations */ + + bits iemsi_on :1; /* IEMSI: 1=Active, 0=Ignore */ + bits iemsi_hotkeys :1; /* IEMSI: 1=Use hot-keyed menu */ + bits iemsi_quiet :1; /* IEMSI: 1=Do not disturb */ + bits iemsi_pausing :1; /* IEMSI: 1=Pause at end of screen */ + bits iemsi_editor :1; /* IEMSI: 1=Use full screen editor */ + bits iemsi_news :1; /* IEMSI: 1=Display news bulletins */ + bits iemsi_newmail :1; /* IEMSI: 1=Check for new mail */ + bits iemsi_newfiles :1; /* IEMSI: 1=Check for new files */ + + bits iemsi_screenclr :1; /* IEMSI: 1=Send clearing screen codes */ + bits prot_xmodem :1; /* 1=Internal XMODEM active */ + bits prot_1kxmodem :1; /* 1=Internal 1K-XMODEM active */ + bits prot_zmodem :1; /* 1=Internal ZMODEM active */ + bits prot_sealink :1; /* 1=Internal SEALINK active */ + + char newkey_code[30]; /* Registration key code (>=2.33) */ + char tearline[36]; /* Custom tear line */ + + char uucp_gatename[20]; /* UUCP gateway name */ + short uucp_zone; /* UUCP gateway zone */ + short uucp_net; /* UUCP gateway net */ + short uucp_node; /* UUCP gateway node */ + + byte carrier_mask; /* Carrier detect bit mask */ + byte dcd_timeout; /* Timeout after drop DCD before hangup */ + + struct { + char display[20]; /* User's display packer name */ + int offset; /* Offset of the signature id */ + char ident[20]; /* Packer's signature id */ + } packid[10]; + + char quote_string[5]; /* String to put in front of quoted lines */ + char quote_header[50]; /* Quote text file header */ + + char tic_help[40]; /* Help file name for TIC processor */ + char tic_alert_nodes[50]; /* Nodes that receives a copy of all TIC response messages */ + char tic_newareas_create[50]; /* Nodes that can create new TIC areas */ + char tic_newareas_link[50]; /* Nodes that are linked to new TIC areas */ + byte tic_remote_maint; /* TIC level for %FROM command */ + byte tic_change_tag; /* TIC level for #: command */ + + int uucp_point; /* UUCP gateway point */ + + byte dial_timeout; /* */ + byte dial_pause; /* */ + + bits newfilescheck :2; /* */ + bits mono_attr :1; /* */ + bits force_intl :1; /* 1=Force ^aINTL line in matrix */ + bits inp_dateformat :2; /* Date format for input fields */ + bits single_pass :1; /* (**) */ + + int ul_free_space; /* Min. disk space for uploads */ + char hangup_string[40]; /* Modem hangup command */ + char init2[40]; /* 2nd modem init command */ + char init3[40]; /* 3th modem init command */ + + int page_start[7]; /* Sysop paging start hours */ + int page_end[7]; /* Sysop paging end hours */ + + char logbuffer; /* Size of log file buffer */ + + char newareas_path[40]; /* Where to create new areas */ + char newareas_base; /* Message base type for new areas */ + + char answer[40]; /* Modem answer command */ + + bits blanker_type :3; /* Screen blanker type */ + bits tcpip :2; /* (**) */ + + char internet_gate; /* Type of internet gate */ + /* 0=Uupc */ + /* 1=GIGO */ + + char areafix_watch[50]; /* Alternate Areafix names */ + char tic_watch[50]; /* Alternate Raid names */ +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_max3.h b/goldlib/gcfg/gs_max3.h new file mode 100644 index 0000000..8353afa --- /dev/null +++ b/goldlib/gcfg/gs_max3.h @@ -0,0 +1,604 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#ifndef __gs_max3_h +#define __gs_max3_h + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef FTime SCOMBO; // DOS-style bitmapped datestamp + +typedef struct _netaddr { + word zone; + word net; + word node; + word point; +} NETADDR; + +typedef word zstr; // Offset of string within area heap + + +// ------------------------------------------------------------------ + +#define MSGTYPE_SDM 0x01 +#define MSGTYPE_SQUISH 0x02 + +#ifdef PATHLEN +#undef PATHLEN +#endif + +#define PATHLEN 120 // Max. length of a path + + +// ------------------------------------------------------------------ +// Menu server enumerations and structures + +// Enumeration `option' -- All possible values for menu.option[x].type + +typedef enum { + nothing, + + MISC_BLOCK=100, display_menu, display_file, message, file, other, + o_press_enter, key_poke, clear_stacked, o_if, + o_menupath, o_cls, mex, link_menu, o_return, + + + XTERN_BLOCK=200, xtern_erlvl, xtern_dos, xtern_run, xtern_chain, + xtern_concur, + + MAIN_BLOCK=300, goodbye, statistics, o_yell, userlist, o_version, + user_editor, leave_comment, climax, + + MSG_BLOCK=400, same_direction, read_next, read_previous, + enter_message, msg_reply, read_nonstop, + read_original, read_reply, msg_list, msg_scan, + msg_inquir, msg_kill, msg_hurl, forward, msg_upload, + xport, read_individual, msg_checkmail, msg_change, + msg_tag, msg_browse, msg_current, msg_edit_user, + msg_upload_qwk, msg_toggle_kludges, msg_unreceive, + msg_restrict, msg_area, msg_track, msg_dload_attach, + msg_reply_area, + + FILE_BLOCK=500, locate, file_titles, file_type, upload, download, raw, + file_kill, contents, file_hurl, override_path, + newfiles, file_tag, file_area, + + // Options generally found on the Change Setup menu + + CHANGE_BLOCK=600, chg_city, chg_password, chg_help, chg_nulls, + chg_width, chg_length, chg_tabs, chg_more, + chg_video, chg_editor, chg_clear, chg_ibm, + chg_phone, chg_realname, chg_hotkeys, + chg_language, chg_userlist, chg_protocol, + chg_fsr, chg_archiver, chg_rip, + + EDIT_BLOCK=700, edit_save, edit_abort, edit_list, edit_edit, + edit_insert, edit_delete, edit_continue, edit_to, + edit_from, edit_subj, edit_handling, read_diskfile, + edit_quote, + + // Stuff that was hacked on after the original implementation + + CHAT_BLOCK=800, who_is_on, o_page, o_chat_cb, chat_toggle, o_chat_pvt, + + END_BLOCK, + + + // Everything below here is RESERVED by Maximus for future uses! + // Also, everything ABOVE is fairly stable. If changes have to be made, + // the old options above will not be re-used. For example, if the + // `edit_insert' command should become obsoleted for some reason, that + // slot would either get retired and do nothing, or perform the NEW + // edit_insert function. + + rsvd=32766 // This was stuck in to make sure that the `option' + // enumeration uses a word, instead of a byte, in case we + // really expand this structure sometime soon. + +} option __attribute__((packed)); + + +// ------------------------------------------------------------------ +// .prm file structure and definitions + +typedef word OFS; + +#ifndef MAX_DRIVES +#define MAX_DRIVES 26 // Maximum number of drives on system +#endif + +#ifndef CHAR_BITS +#define CHAR_BITS 8 // Number of bits in a 'char' +#endif + +#define CTL_VER 9 // Version number of bbs.prm + +// This macro is ONLY used for accessing *pointers* in the `prm' structure. +// This is required, due to the way Wynn has made OPUS_CTL write the strings +// out (which uses a lot less memory than some other ways). If you want +// to access an INT, or a non-pointer in the structure, then you can use +// a `prm.var_name'-style reference. + +#define PRM(s) (offsets+(prm.s)) + +#define MAX_LANG 8 // Max. number of possible languages +#define MAX_YELL 10 // Max number of yell slots +#define MAX_EXTERNP 16 // max. number of external programs +#define ALIAS_CNT 15 // number of matrix addresses +#define MAXCLASS 12 // OBSOLETE! Only used for + // compatibility with Max 2.x. + +// OBSOLETE! Only used for compatibility purposes + +struct cl_rec { + sword priv; + word max_time; // max cume time per day + word max_call; // max time for one call + word max_dl; // max dl kbytes per day + word ratio; // ul:dl ratio + word min_baud; // speed needed for logon + word min_file_baud; // speed needed for file xfer +}; + + +// Note: To read in the *.PRM structure, first read in the m_pointers +// structure, which is always contained at the beginning of the file. +// Then, seek to the offset prm.heap_offset, and read in everything +// from there to EOF into heap[]. All of the 'OFS' type variables +// are simply offsets into the variable-length heap which started at +// heap_offset. To obtain a string from the .PRM heap, simply +// add the offset in the m_pointers structure to the address of the +// heap[] variable that the heap was read into. For example, to access +// the string for 'system_name', you'd use '(heap+prm.system_name)'. +// Alternatively, you can declare a macro to do this, such as the +// PRM() macro shown above. (Maximus itself uses the variable +// 'strings' instead of 'heap' to hold the varible-length strings, +// but the concept is the same.) When using the PRM() macro to +// access the string for 'system_name', you'd simply write: +// 'PRM(system_name)', which is a lot clearer. Also, please note that +// NON-OFS variables should be accessed normally! That means that +// 'task_num', 'auto_kill', can be access with 'prm.task_num', +// 'prm.auto_kill', etc. The special heap manipulation is only needed +// for strings. + +struct m_pointers { + +// DATA + + byte id; /* Always equal to 'M' STABLE */ + byte version; /* for safety STABLE */ + word heap_offset; /* OFFSET OF BEGINNING OF HEAP! STABLE */ + byte task_num; /* for multi-tasking systems STABLE */ + sword com_port; /* Com1=0, Com2=1, etc STABLE */ + byte noise_ok; /* If yell noise is currently on STABLE */ + + /* Miscellanious system information */ + + byte video; /* Mode for local video display */ + byte log_mode; /* What style of logging to use */ + word max_baud; /* fastest speed we can use */ + sbyte multitasker; /* flag for DoubleDos (see below) */ + byte nlver; /* Which nodelist version we use (NLVER_XXX) */ + + sword min_ulist; /* OBSOLETE! Only used for compatibility */ + sword max_ulist; /* with Maximus 2.x! */ + + /* Information about errorlevels */ + + byte exit_val; /* Erl to use after caller if none of below */ + byte edit_exit; /* erl to use after matrix mail written */ + byte echo_exit; /* ERRORLEVEL for after inbound echomail */ + byte local_exit; /* Errorlevel after entering local msgs */ + + /* Modem information */ + + sword carrier_mask; + sword handshake_mask; + + /* Log-on information */ + + word logon_priv; /* Access level for new users */ + word logon_time; /* time to give for logons */ + word min_baud; /* minimum baud to get on-line */ + word speed_graphics; /* min baud for graphics */ + + /* Information about message areas */ + + byte auto_kill; /* RECD PVT msgs. 0=no 1=ask 2=yes */ + + word ctla_priv; /* Priv to see CONTROL-A lines in messages */ + word seenby_priv; /* Min priv to see SEEN-BY line */ + word pvt_priv; /* Min priv to read pvt msgs */ + + word msg_ask[16]; /* Array of privs. for message attr ask's */ + word msg_assume[16]; /* Array of privs. for message attr assume's */ + word msg_fromfile; /* Priv. for doing message from file */ + word speed_rip; /* min baud for rip graphics */ + byte rsvd1[2]; /* used to be high_msgarea, begin_msgarea */ + word unlisted_priv; /* Priv needed to send to unlisted node */ + sword unlisted_cost; /* Charge to send to unlisted node */ + + word mc_reply_priv; /* Priv to reply to msg with mailchecker */ + word mc_kill_priv; /* Priv to kill msg with mailchecker */ + + + /* Information about file areas */ + + sword date_style; /* Used for FILES.BBS display */ + word rsvd20; /* Reserved (used to be dlall_priv) */ + word rsvd21; /* Reserved (used to be ulbbs_priv) */ + dword k_free; /* The number of disk space (in K) which * + * must be available before we let a user * + * upload. */ + word rsvd7; /* reserved - used to be upload reward */ + word ratio_threshold;/* OBSOLETE! Only used for Max 2.x compat. */ + byte rsvd2[4]; /* used to be high_filearea, begin_filearea */ + + /* Our matrix address(es) */ + + NETADDR address[ALIAS_CNT]; + + byte rsvd3[60]; /* Reserved by Maximus for future use */ + + /* About the users */ + struct cl_rec cls[MAXCLASS]; /* OBSOLETE! Only used for compatibility */ + /* with Maximus 2.x. */ + + /* Flags for external protocols */ + + sword protoexit; /* Errorlevel for protocol exit */ + char protoflag[MAX_EXTERNP]; + + /* General-purpose bit-flags (See FLAGx_xxx definitions above.) */ + + word flags; + word flags2; + word flags3; + word flags4; + + /* Bit field containing drive letters to save when going outside */ + char drives_to_save[(MAX_DRIVES/CHAR_BITS)+1]; + + byte fbbs_margin; /* Margin to use for wrapping FILES.BBS comments */ + byte kill_attach; /* Kill file attaches 0=no 1=ask 2=yes */ + + word max_ptrs; /* Maximum size of pointers of ALL *.LTFs */ + word max_heap; /* Maximus heap size of all *.LTFs */ + byte max_lang; /* Current number of languages */ + byte rsvd_lang; + + word max_glh_ptrs; + word max_glh_len; + + word max_syh_ptrs; + word max_syh_len; + + byte input_timeout; /* # of mins until Max hangs up due to no input */ + + byte charset; /* Character set support - see CHARSET_XXXX, above */ + word max_pack; /* Maximum # of msgs to pack into a .QWK packet */ + word msg_localattach; /* Priv. for doing local file attaches */ + word kill_attach_priv;/* Priv. for killing local file attaches */ + word mcp_sessions; /* Max number of MCP sessions */ + dword max_msgsize; /* Truncate uploaded messages to this size */ + + byte rsvd65[2]; /* Reserved by Maximus for future use */ + +// OFFSETS + + /* About your system */ + +#define PRM_HEAP_START sysop + + OFS sysop; /* sysop's name. MUST be first offset in prm file */ + OFS system_name; /* board's name */ + + /* Modem commands */ + + OFS m_busy; /* mdm cmd to take modem off hook */ + + /* Paths to various places */ + + OFS sys_path; /* path to SYSTEM?.BBS files */ + OFS misc_path; /* path to `F-key files' */ + OFS net_info; /* path to NODELIST files */ + OFS temppath; /* place to put temporary files */ + OFS ipc_path; /* path for inter-process communications */ + + /* General files needed by the system */ + + OFS user_file; /* path/filename of User.Bbs */ + OFS log_name; /* name of the log file */ + OFS chat_prog; /* External chat program, if any */ + OFS chat_fbegin; /* File to display instead of "CHAT: begin" */ + OFS chat_fend; /* File to display instead of "END CHAT" */ + OFS local_editor; /* Command for local editor, if any */ + OFS notfound; /* User name not found in user file */ + OFS junk; /* Don't use this for anything! */ + + /* General *.?BS files needed everywhere */ + + OFS logo; /* first file shown to a caller */ + OFS bad_logon; /* if user's last logon attempt was bad */ + OFS welcome; /* shown after logon */ + OFS quote; /* For displaying "random" quotes from */ + OFS newuser1; /* Asks user to type in password */ + OFS newuser2; /* Replaces `welcome' for a new user */ + OFS rookie; /* Replaces `welcome' for rookies */ + OFS application; /* new user questionnaire */ + OFS byebye; /* file displayed at logoff */ + OFS out_leaving; /* Bon Voyage */ + OFS out_return; /* Welcome back from O)utside */ + OFS daylimit; /* Sorry, you've been on too long... */ + OFS timewarn; /* warning about forced hangup */ + OFS tooslow; /* explains minimum logon baud rate */ + OFS barricade; /* Displayed before prompt for access code */ + OFS shelltodos; /* Displayed when Sysop hits Alt-J */ + OFS backfromdos; /* Displayed when Sysop returns from Alt-J */ + OFS areanotexist; /* File to display instead of "That area * + * doesn't exist!" */ + + /* User priv levels database */ + + OFS access; /* Database of user privilege levels */ + + /* File-area items */ + + OFS xferbaud; /* explains minimum file transfer baud rate */ + OFS file_area_list; /* dump file... used instead of Dir.Bbs */ + OFS no_space; /* File to display if trying to UL with * + * less than k_free space left on drive. */ + OFS fname_format; /* Essay on MS-DOS filenames for U)ploads */ + OFS ul_log; /* Log file for uploads */ + + OFS file_header; /* Format for file area's A)rea command */ + OFS file_format; /* Format for A)rea command entries */ + OFS file_footer; /* Format for footer for file.area menu */ + + OFS proto_dump; /* Dump file for protocol screen */ + + /* Message-area items */ + + OFS msgarea_list; /* dump file... used instead of Dir.Bbs */ + OFS echotoss_name; /* Name of your echomail tosslog */ + OFS nomail; /* Display by mailchecker if no mail wtng. */ + + OFS msg_header; /* Format for msg.area's A)rea command */ + OFS msg_format; /* Format for A)reas command entries */ + OFS msg_footer; /* Format for footer for msg.area menu */ + + /* Help files: Used to explain various things */ + + OFS hlp_editor; /* intro to msg editor for novices. */ + OFS hlp_replace; /* Explain the Msg.Editor E)dit command */ + OFS msg_inquire; /* Explain the Msg. I)nquire command */ + OFS hlp_locate; /* Explain the Files L)ocate command */ + OFS hlp_contents; /* Explain the Files C)ontents command */ + OFS oped_help; /* help file for the full-screen editor */ + OFS hlp_scan; /* help file for S)can */ + OFS hlp_list; /* help file for L)ist */ + + /* External protocols */ + + OFS protocols[MAX_EXTERNP]; /* external file protocol programs */ + OFS protoname[MAX_EXTERNP]; /* name of protocol, on menu */ + + /* Date/Time format strings */ + + OFS timeformat; + OFS dateformat; + + /* **OBSOLETE** names of the old Max 2.x area.dat/idx files */ + + OFS adat_name; + OFS aidx_name; + + /* Menu paths/names */ + + OFS menupath; /* The default place to look for the menus */ + OFS first_menu; /* The name of the first menu to display */ + OFS edit_menu; /* Name of the EDIT menu */ + + /* Miscellaneous */ + + OFS achg_keys; /* Characters used to change area -/+ */ + OFS tune_file; /* Path to TUNES.MAX */ + OFS lang_path; /* Path to *.LTF files */ + + OFS lang_file[MAX_LANG]; /* Array of all *.LTF names */ + + OFS m_init; /* Modem initialization string */ + OFS m_ring; /* Command modem sends when phone ringing */ + OFS m_answer; /* Cmd to send to modem when ring detect */ + OFS m_connect; /* Connect string, as returned by modem */ + + OFS high_msgarea; + OFS begin_msgarea; /* Msg area to put new users in */ + + OFS high_filearea; + OFS begin_filearea; /* File area to put new users in */ + + OFS fidouser; /* Name of FIDOUSER.LST file to use */ + OFS cmtarea; /* Message area to put comments in */ + + OFS arc_ctl; /* Control file for archiving programs */ + OFS olr_name; /* OLR: Filename to use for DL packets */ + OFS olr_dir; /* OLR: Directory for off-line stuff */ + OFS phone_num; + OFS viruschk; /* Name of batch file to call for virus check*/ + OFS protocol_max; /* Name of compiled protocol data file */ + OFS track_privview; /* Priv req'd to see tracking info owned by others */ + OFS track_privmod; /* Priv req'd to modify track info owned by others */ + OFS track_base; /* Base name of the tracking database files */ + OFS track_exclude; /* File containing list of names to exclude */ + OFS stagepath; /* Path for staged CD-ROM transfers */ + OFS attach_base; /* Base name of the local attach database */ + OFS attach_path; /* Default path for local file attaches */ + OFS attach_archiver;/* File attach archiver */ + OFS inbound_files; /* Inbound FTS-1 attaches for users */ + OFS rippath; /* Default icon & RIP screens path */ + + /* More help files */ + + OFS hlp_hdrentry; /* Help screen for message header entry */ + OFS hlp_msgentry; /* Help screen for start of message entry */ + OFS not_configured; /* Displayed if user is not configured */ + + /* MCP stuff */ + + OFS mcp_pipe; /* Default MCP pipe */ + + /* Paths to the new marea/farea message/file data files */ + + OFS marea_name; /* Name of message area data file */ + OFS farea_name; /* Name of file area data file */ + + /* Caller information log */ + + OFS caller_log; /* Caller information log */ + +#define PRM_HEAP_END caller_log +}; + + +// ------------------------------------------------------------------ +// General structure of MAREA.DAT and FAREA.DAT: +// MAREA_ID or FAREA_ID +// _msgarea +// _ovride ... +// zstr heap +// _msgarea +// _ovride ... +// zstr heap +// eof + + +// This key is present at the beginning of an area file. MAREA_ID is +// used for the message data file and FAREA_ID is used for the +// file data file. + +#define MAREA_ID 0x1a49023fL +#define FAREA_ID 0x1a01953aL + +struct _ovride { + + /* Only one of 'opt' or 'name' should be used. If opt==0, use name. If * + * name==0, use opt. */ + + option opt; /* Type of menu option to override ...OR... */ + byte name; /* First letter of command to override */ + byte rsvd1; /* Reserved for future use */ + zstr acs; /* New ACS required to access option */ + zstr menuname; /* Use this access level on the given menu only */ +}; + + +// ------------------------------------------------------------------ +// Bit masks for the ma.attribs field + +#define MA_PVT 0x0001 /* Private msgs allowed */ +#define MA_PUB 0x0002 /* Public msgs allowed */ +#define MA_HIBIT 0x0004 /* High bit msgs allowed */ + +#define MA_NET 0x0008 /* Netmail area */ +#define MA_ECHO 0x0010 /* Echomail area */ +#define MA_CONF 0x0020 /* Conference area */ + +#define MA_ANON 0x0040 /* Anonymous messages are OK */ +#define MA_NORNK 0x0080 /* Don't use the REALNAME kludge for this area */ +#define MA_REAL 0x0100 /* Force use of real name for this area */ +#define MA_ALIAS 0x0200 /* Force use of alias name for this area */ +#define MA_AUDIT 0x0400 /* Use auditing (msg tracking) controls in area*/ +#define MA_READONLY 0x0800 /* Area is read-only */ +#define MA_HIDDN 0x1000 /* Area does not display on normal area list */ +#define MA_ATTACH 0x2000 /* Area allows local file attaches */ +#define MA_DIVBEGIN 0x4000 /* A message area division, not a real area */ +#define MA_DIVEND 0x8000 /* End of the message area division */ + +#define MA2_NOMCHK 0x0001 /* Don't do personal mail check in this area */ + +#define MA_SHARED (MA_ECHO | MA_CONF) + + +typedef struct _msgarea { + + word cbArea; /* Length of THIS INDIVIDUAL RECORD 0*/ + word num_override; /* Number of overrides following this record 2*/ + word cbHeap; /* Length of the zstr heap following the overrides 4*/ + word division; /* Reserved for future use 6*/ + zstr name; /* String format of area's name. 8*/ + zstr acs; /* Access control string for this area 10*/ + zstr path; /* Path to messages (but for MA_DIVBEGIN only, 12* + * used instead as name of custom .bbs file). */ + zstr echo_tag; /* The 'tag' of the area, for use in ECHOTOSS.LOG 14*/ + zstr descript; /* The DIR.BBS-like description for msg section 16*/ + zstr origin; /* The ORIGIN line for this area 18*/ + zstr menuname; /* Custom menu name 20*/ + zstr menureplace; /* Replace this menu name with menuname from above22*/ + + word attribs; /* Attributes for this area 24*/ + + NETADDR primary; /* Use as primary address for this area 26*/ + NETADDR seenby; /* Use as address in seen-bys 34*/ + word attribs_2; /* More attributes 42*/ + word type; /* Message base type. MSGTYPE_SDM = *.MSG. 44* + * MSGTYPE_SQUISH = SquishMail. (Constants are * + * in MSGAPI.H) */ + word killbyage; /* Make sure msgs are less than X days old 46*/ + word killbynum; /* Make sure there are less than X msgs 48*/ + word killskip; /* Exempt the first X msgs from this processing 50*/ + zstr barricade; /* Barricade file 52*/ + zstr barricademenu; /* Apply barricade priv while using this menu 54*/ + sdword cbPrior; /* Seek offset from start of this area to get back56* + * to prior area. */ + zstr attachpath; /* Reserved for future use 58*/ + dword rsvd4; /*60*/ +}; /*64*/ + + +// ----------------------------------------------------------------- + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ----------------------------------------------------------------- + +#endif // __gs_max3_h + +// ----------------------------------------------------------------- diff --git a/goldlib/gcfg/gs_opus.h b/goldlib/gcfg/gs_opus.h new file mode 100644 index 0000000..650b563 --- /dev/null +++ b/goldlib/gcfg/gs_opus.h @@ -0,0 +1,1540 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ + +///////////////////////////////////////////////////////////////////////////// +// +// +// OPUS 1.1x +// +// +///////////////////////////////////////////////////////////////////////////// + + +/*-------------------------------------------------------------------------*/ +/* System*.DAT structure */ +/*-------------------------------------------------------------------------*/ + +typedef struct { + /*........ Common System Data ....................................*/ + + word version; /* System Record version = 110 = v1.10 */ + word menu; /* Alternate Menu file extension, 0=MNU */ + word attrib; /* Area attributes (see below) */ + byte fillc1[10]; /* Fill to 16th */ + byte barrpath[ 40 ]; /* Barricade File path. */ + byte fillc2[24]; /* Fill to 16th */ + + /*........ File System Information ...............................*/ + + char filtitle[50]; /* File Area Title (as per old Dir.Bbs) */ + char filepath[40]; /* Path to the file download sub-dir */ + char uppath[40]; /* Path to the file upload sub-directory */ + char listpath[40]; /* Path to FILES.BBS equivilent */ + byte fillf1[22]; /* Fill to 16th */ + + byte FilePriv; /* Min priv for file area */ + byte DownPriv; /* Override priv to download */ + byte UpPriv; /* Override priv to upload */ + byte FileExtPriv; /* Override priv for outside */ + byte fillf2[12]; /* Fill to 16th */ + + long FileLock; /* Locks for File Area */ + long DownLock; /* Override Locks to download */ + long UpLock; /* Override Locks to upload */ + long FileExtLock; /* Override Locks for Outside */ + byte fillf3[32]; /* Fill to 16th */ + + /*........ Message System Information ............................*/ + + char msgtitle[50]; /* Msg Area Title (as per old Dir.Bbs) */ + char msgpath[40]; /* Path to messages */ + byte fillm1[22]; /* Fill to 16th */ + + byte MsgPriv; /* Min priv for msg area */ + byte EditPriv; /* Override priv for Enter/Rep */ + byte MsgExtPriv; /* Override priv fot outside */ + byte fillm2[13]; /* Fill to 16th */ + + long MsgLock; /* Locks for Msg Area */ + long EditLock; /* Override Locks for Enter/Rep */ + long MsgExtLock; /* Override Locks for Outside */ + byte fillm3[4]; /* Fill to 16th */ + char EchoName[32]; /* If an echo area, its name */ + + /*=================================== Total Record Size = 512 ==*/ +} _systemdat; + + + + +////////////////////////////////////////////////////////////////////////////// +// +// +// OPUS 1.7x +// +// +////////////////////////////////////////////////////////////////////////////// + + +// INCLUDE OPUS.H //////////////////////////////////////////////////////////// + +/*--------------------------------------------------------------------------*/ +/* */ +/* The Opus Computer-Based Conversation System */ +/* (c) Copyright 1986-1991, Wynn Wagner III, All Rights Reserved */ +/* */ +/* */ +/* YOOHOO is a trademark of Wynn Wagner III */ +/* */ +/* YOOHOO-YOOHOO/2U2 & WaZOO are */ +/* Copyright 1987, Wynn Wagner III, All Rights Reserved */ +/* */ +/* */ +/* This material is available for use by anybody with no strings and */ +/* no guarantees. */ +/* */ +/* */ +/*--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------*/ +/* LEGIBLE SECTION. Definitions to make "C" look like a real language. */ +/*--------------------------------------------------------------------------*/ +#undef log + +#ifndef begin +# define begin { +# define end } +//# define true (-1) +# define false 0 +# define Procedure void +# define shl << +# define shr >> +# define xor ^ +# define and && +# define or || +# define not ! +# define mod % + typedef unsigned Bit; + typedef unsigned char const * const STRING; +# define fallthrough /* ... for use in switch statements for clarity. */ +#endif + + +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif + +#ifndef min +#define min(a,b) ((a)<=(b)?(a):(b)) +#endif + + + +/*--------------------------------------------------------------------------*/ +/* TIME STAMP */ +/*--------------------------------------------------------------------------*/ +struct _stamp + begin + unsigned short date; + unsigned short time; + end; + + +/*--------------------------------------------------------------------------*/ +/* FIDONET ADDRESS STRUCTURE */ +/*--------------------------------------------------------------------------*/ +typedef struct _ADDRESS + begin + short Zone; + short Net; + short Node; + short Point; + end ADDR; + + + + + +/*--------------------------------------------------------------------------*/ +/* NodeList.Sys */ +/* */ +/* NET > 0 and NODE > 0 Normal node */ +/* */ +/* NET > 0 and NODE <= 0 Host node */ +/* Net host........node== 0 */ +/* Regional host...node==-1 */ +/* Country host....node==-2 */ +/* */ +/* NET == -1 Nodelist.Sys revision */ +/* */ +/* NET == -2 Nodelist statement */ +/* */ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +/* THE NEWSTYLE NODE LIST */ +/*--------------------------------------------------------------------------*/ + struct _node + begin + short NetNumber; + short NodeNumber; + word MsgFee; /* Amount charged to user for a message */ + byte SystemName[34]; /* node name */ + byte PhoneNumber[40]; /* phone number */ + byte MiscInfo[30]; /* city and state */ + byte Password[8]; /* WARNING: not necessarily null-terminated */ + word CallCost; /* phone company's charge */ + word HubNode; /* node # of this node's hub or 0 if none */ + byte BaudRate; /* baud rate divided by 300 */ + byte ModemType; /* RESERVED for modem type */ + word NodeFlags; /* set of flags (see below) */ + word NodeFiller; + end; + + +#define B_hub 0x0001 /* node is a net hub 0000 0000 0000 0001 */ +#define B_host 0x0002 /* node is a net host 0000 0000 0000 0010 */ +#define B_region 0x0004 /* node is region coord 0000 0000 0000 0100 */ +#define B_zone 0x0008 /* is a zone gateway 0000 0000 0000 1000 */ +#define B_CM 0x0010 /* runs continuous mail 0000 0000 0001 0000 */ +#define B_res1 0x0020 /* reserved by Opus 0000 0000 0010 0000 */ +#define B_res2 0x0040 /* reserved by Opus 0000 0000 0100 0000 */ +#define B_res3 0x0080 /* reserved by Opus 0000 0000 1000 0000 */ +#define B_res4 0x0100 /* reserved by Opus 0000 0001 0000 0000 */ +#define B_res5 0x0200 /* reserved for non-Opus 0000 0010 0000 0000 */ +#define B_res6 0x0400 /* reserved for non-Opus 0000 0100 0000 0000 */ +#define B_res7 0x0800 /* reserved for non-Opus 0000 1000 0000 0000 */ +#define B_point 0x1000 /* node is a point 0001 0000 0000 0000 */ +#define B_res9 0x2000 /* reserved for non-Opus 0010 0000 0000 0000 */ +#define B_resa 0x4000 /* reserved for non-Opus 0100 0000 0000 0000 */ +#define B_resb 0x8000 /* reserved for non-Opus 1000 0000 0000 0000 */ + + + +/*--------------------------------------------------------------------------*/ +/* Nodelist.Idx */ +/* (File is terminated by EOF) */ +/*--------------------------------------------------------------------------*/ +struct _ndi + begin + short node; /* node number */ + short net; /* net number */ + end; + +#define MAXEXPAND 30 /* max download files (wildcard expansion) */ +#define CMDLEN 80 /* size of the command typeahead buffer */ +#define CARRYLEN 20 /* LORE editor's carry buffer */ +#define MAXLEN 85 /* size of primary line-input buffer */ + + + +/*--------------------------------------------------------------------------*/ +/* OPUS CONTROL FILE and PARM FILE DECLARATIONS */ +/*--------------------------------------------------------------------------*/ +//#include "prm18.h" +// SUB-INCLUDE PRM18.H /////////////////////////////////////////////////////////// + +/*--------------------------------------------------------------------------*/ +/* */ +/* The Opus Computer-Based Conversation System */ +/* (c) Copyright 1986-1991, Wynn Wagner III, All Rights Reserved */ +/* */ +/* */ +/* YOOHOO is a trademark of Wynn Wagner III */ +/* */ +/* YOOHOO-YOOHOO/2U2 & WaZOO are */ +/* Copyright 1987, Wynn Wagner III, All Rights Reserved */ +/* */ +/* */ +/* This material is available for use by anybody with no strings and */ +/* no guarantees. */ +/* */ +/* */ +/*--------------------------------------------------------------------------*/ +/* */ +/* OPUS 1.20 Message/File area database structures. */ +/* Copyright 1991 Wynn Wagner III, Doug Boone and John Valentyn. */ +/* */ +/*--------------------------------------------------------------------------*/ + +#define THIS_CTL_VERSION 18 /* PRM structure version number */ + +#if COMPILER +# define CTLSIZE 0x7fff /* Only used when compiling OPUS_CTL */ +# define OFS short +#elif UTILS +# define CTLSIZE 1 /* Only used when compiling Utilities*/ +# define OFS short +#else +# define CTLSIZE 1 +# define OFS char* +#endif + + +#define MAX_EXTERN 16 /* max. number of external programs */ +#define MAXCLASS 12 /* number of possible priv levels */ +#define ALIAS_CNT 15 /* number of matrix addresses */ + +#define _TWIT 0x10 +#define _DISGRACE 0x30 +#define _LIMITED 0x40 +#define _NORMALL 0x50 +#define _WORTHY 0x60 +#define _PRIVEL 0x70 +#define _FAVORED 0x80 +#define _EXTRA 0x90 +#define _CLERK 0xA0 +#define _ASSTSYSOP 0xB0 +#define _SYSOP 0xD0 +#define _HIDDEN 0xE0 + +#define Twit _TWIT +#define Disgrace _DISGRACE +#define Limited _LIMITED +#define Normal _NORMALL +#define Worthy _WORTHY +#define Privil _PRIVEL +#define Favored _FAVORED +#define Extra _EXTRA +#define Clerk _CLERK +#define AsstSysop _ASSTSYSOP +#define Sysop _SYSOP +#define Hidden _HIDDEN + + + +struct class_rec + begin + byte ClassPriv; + byte class_fill; + short max_time; /* max cume time per day */ + short max_call; /* max time for one call */ + word max_dl; /* max dl bytes per day */ + byte ratio_down; + byte ratio_up; + word min_baud; /* speed needed for logon */ + word min_file_baud; /* speed needed for file xfer */ + end; + +struct _FOSREGS + begin + word ax; + word bx; + word cx; + word dx; + end; + + +/*--------------------------------------------------------------------------*/ +/* The format of the PRM file, VERSION 18 */ +/* */ +/* THIS IS AN EXPLOSIVE STRUCTURE. IT IS SUBJECT TO CHANGE WITH NO NOTICE. */ +/* */ +/* Offsets to the following item(s) are guaranteed: */ +/* */ +/* byte version; OFFSET 0, all versions */ +/* byte task_num; OFFSET 1, 16+ */ +/* */ +/*--------------------------------------------------------------------------*/ +struct _PRM + begin + /*-----------------------------------------------------------*/ + /* DATA */ + /*-----------------------------------------------------------*/ + byte version; /* for safety STABLE*/ + byte task_num; /* for multi-tasking systems STABLE*/ + ADDR alias[ALIAS_CNT]; + + byte video; /* 0=Dos, 1=Fossil 2=IBM */ + byte testmode; /* input from keyboard, not modem */ + + word carrier_mask; + word handshake_mask; + word max_baud; /* fastest speed we can use */ + word com_port; /* Com1=0, Com2=1, FF=keyboard */ + + byte multitasker; /* flag for DoubleDos (see below) */ + byte mailer_type; /* 0=Opus, 1=load external, 2=call external */ + + byte ModemFlag; /* (See MODEM FLAG below) */ + byte LogFlag; /* (See LOG FLAG below) */ + + byte StyleFlag; /* (See STYLE FLAG below) */ + byte FWDflag; /* Bits to control IN TRANSIT messages */ + + byte flags; /* See "FLAGS" below */ + byte Flags2; /* See "FLAGS 2" below */ + + byte edit_exit; /* ERRORLEVEL to use if Matrix area changed */ + byte exit_val; /* ERRORLEVEL to use after caller */ + + byte crashexit; /* non-zero= ErrorLevel exit */ + byte arc_exit; /* ErrorLevel for after incomming ARCmail */ + + byte echo_exit; /* ERRORLEVEL for after inbound echomail */ + byte UDB_Flags; /* User data base flags */ + + word min_baud; /* minimum baud to get on-line */ + word color_baud; /* min baud for graphics */ + word date_style; /* Used for FILES.BBS display */ + + byte logon_priv; /* Access level for new users */ + byte seenby_priv; /* Min priv to see SEEN_BY line */ + + byte ctla_priv; /* Priv to see CONTROL-A lines in messages */ + byte Interline_Flags; /* Flags relating to interline systems */ + + byte AskPrivs[16]; /* Array of privs. for message attr ask's */ + byte AssumePrivs[16];/* Array of privs. for message attr assume's */ + + word logon_time; /* time to give for logons */ + + word matrix_mask; + + word MinNetBaud; /* minimum baud rate for remote netmail */ + byte exit_mailer; /* Exit when mailer is running */ + byte num_crashes; /* Number of tries when sending crash */ + + struct class_rec Class[MAXCLASS]; + struct _FOSREGS FosRegs[10]; + + word F_Reward; /* File upload time reward percentage */ + word last_area; /* Highest msg area presumed to exist */ + word last_farea; /* Highest file area presumed to exist */ + + byte return_secure; /* 0=ignore LASTUSER, >1 re-read LASTUSER */ + + /* New for Version 17 */ + + byte xuflags; /* ExtUser Flags: 1=Alias, 2=UserTel */ + word xlmin; /* Lead mins for expiry warning */ + char xlday; /* Lead days for expiry warning */ + byte expriv; /* Expiry privilege */ + char totlang; /* Total languages present (1-6) */ + byte sylno; /* Def Sysop Language no. (0-5) */ + byte uslno; /* Def User Language no. (0-5) */ + byte relog_exit; /* Exit after -o relog */ + word Scrn_Size; /* Local monitor's size, high byte = len */ + +/* New for version 18 */ + + word default_expire_days; /* Number of days before new users */ + word default_expire_mins; /* Number of days before new users */ + long default_keys; /* New user's default keys */ + long default_section; /* New user's default section */ + word Point_Net; /* My point net */ + word Boss_Node; /* My point net */ + byte NoPwd_Priv; /* Priv if you want to allow users without password */ + byte Local_Exit; /* Exit after local messages */ + byte Upload_Exit; /* Exit after an upload for checking */ + byte ExtMail_Exit; /* Exit for externmail */ + byte Max_Echo; /* Longest echomail message to handle 3-60k */ + byte WhoPriv; /* Priv to see who uploaded a file */ + + ADDR GUUCP; /* Where to send gated UUCP messages */ + long making_section; + byte ListSysop; /* Privilege neeeded to see sysops in net list */ + byte rawpriv; /* Privilege needed to see/download files not listed */ + byte uucp_priv; /* Privilege needed to turn off uucp addresses */ + byte Flags3; /* More flags. */ + byte Mail_Exit; /* Exit after mail connect */ + byte byte_fill; + + word PRM_FILL3[18]; + + + /*-----------------------------------------------------------*/ + /* OFFSETS */ + /*-----------------------------------------------------------*/ + + /*-------------------------------------------*/ + /* MODEM COMMAND STRINGS */ + /*-------------------------------------------*/ + OFS MDM_Init; /* modem initialization string */ + OFS MDM_PreDial; /* modem dial command sent before number */ + OFS MDM_PostDial; /* modem command sent after dialed number */ + OFS MDM_LookBusy; /* mdm cmd to take modem off hook */ + + /*-------------------------------------------*/ + /* PRIMROSE PATHS */ + /*-------------------------------------------*/ + OFS misc_path; /* path to BBS/GBS files */ + OFS sys_path; /* path to SYSTEM?.BBS files */ + OFS temppath; /* place to put temporary files */ + OFS net_info; /* path to NODELIST files */ + OFS mailpath; /* place to put received netmail bundles */ + OFS filepath; /* place to put received netmail files */ + OFS hold_area; /* path to pending outbound matrix traffic */ + + /*-------------------------------------------*/ + /* DATA FILE NAMES */ + /*-------------------------------------------*/ + OFS user_file; /* path/filename of User.Bbs */ + OFS sched_name; /* name of file with _sched array */ + OFS langdir; /* Langauge file dir. (Was Syl in v16) */ + OFS spcldir; /* Spcl Ann Text dir. (Was Usl in v16) */ + + /*-------------------------------------------*/ + /* MISCELLANEOUS TEXT */ + /*-------------------------------------------*/ + OFS system_name; /* board's name */ + OFS sysop; /* sysop's name */ + OFS timeformat; + OFS dateformat; + OFS OFS_Filler1[8]; + + /*-------------------------------------------*/ + /* BBS/GBS SUPPORT FILES */ + /*-------------------------------------------*/ + OFS logo; /* first file shown to a caller */ + OFS welcome; /* shown after logon */ + OFS newuser1; + OFS newuser2; + OFS rookie; + + OFS HLP_Editor; /* Intro to msg editor for novices. */ + OFS HLP_Replace; /* Explain the Msg.Editor E)dit command */ + OFS HLP_Inquire; /* Explain the Msg. I)nquire command */ + OFS HLP_Locate; /* Explain the Files L)ocate command */ + OFS HLP_Contents; /* Explain the Files C)ontents command */ + OFS HLP_OPed; /* help file for the full-screen editor */ + OFS OUT_Leaving; /* Bon Voyage */ + OFS OUT_Return; /* Welcome back from O)utside */ + OFS ERR_DayLimit; /* Sorry, you've been on too long... */ + OFS ERR_TimeWarn; /* warning about forced hangup */ + OFS ERR_TooSlow; /* explains minimum logon baud rate */ + OFS ERR_XferBaud; /* explains minimum file transfer baud rate */ + OFS LIST_MsgAreas; /* dump file... used instead of Dir.Bbs */ + OFS LIST_FileAreas; /* dump file... used instead of Dir.Bbs */ + + OFS FREQ_MyFiles; /* file to send when FILES is file requested */ + OFS FREQ_OKList; /* list of files approved for file requests */ + OFS FREQ_About; /* File Request: ABOUT file */ + + OFS OEC_Quotes; + OFS byebye; /* file displayed at logoff */ + OFS local_editor; /* text editor to use in keyboard mode */ + OFS barricade; + OFS STATUS_dir; /* Where to find INMAIL/ACTIVE/LASTUSER */ + OFS mailer; /* full external mailer command */ + OFS common; /* File with data common to all tasks */ + + /* New for Version 17 */ + + OFS xdwarn; /* Date Warning OEC BBS */ + OFS xtwarn; /* Time Warning OEC BBS */ + OFS xdexpd; /* Expired due-to-Date OEC BBS */ + OFS xtexpd; /* Expired due-to-Time used OEC BBS */ + OFS lang[12]; /* 12 Language File Root Name pointers */ + + OFS badpath; /* Path for unrecognized echo names */ +/*--------------------------------------------------------------------------*/ +/* New for version 18 */ +/*--------------------------------------------------------------------------*/ + OFS ConfHelp; /* Help file for newuser configure */ + OFS Mainmenu; /* ASCII menu at MAIN */ + OFS Confmenu; /* ASCII menu at Config */ + OFS Sectmenu; /* ASCII menu at Section menu */ + OFS Sysopmenu; /* ASCII menu at Sysop menu */ + OFS Echotoss; /* Where to find EchoToss.Log */ + OFS MDM_Answer; /* String to force autoanswer */ + OFS BAD_PWD; /* File shown to users who've forgottent thiers */ + OFS charset; /* File that contains character translation tables */ + OFS DL_Log; /* Who's downloaded what */ + OFS UL_Log; /* Who uploaded what */ + OFS Name_Filter; /* Old USERNAME.TXT */ + OFS Bad_Name; /* What to show user if filter catches them */ + OFS CUSTOM1_menu; /* What to show before CUSTOM1 menu */ + OFS CUSTOM2_menu; /* What to show before CUSTOM2 menu */ + OFS CUSTOM3_menu; /* What to show before CUSTOM3 menu */ + OFS CUSTOM4_menu; /* What to show before CUSTOM4 menu */ + OFS CUSTOM5_menu; /* What to show before CUSTOM5 menu */ + OFS CUSTOM6_menu; /* What to show before CUSTOM6 menu */ + OFS EXT_mail_string; /* What we see when UUCP is coming */ + OFS MaybeNew; /* File shown if didn't find user name */ + OFS Histmenu; /* ASCII menu at History */ + OFS My_Question; /* Sysop configured question */ + OFS HLP_make; /* How to make a section */ + OFS MDM_FDial[4]; /* Special dialing instructions */ + OFS Yell; /* Yell OEC */ + OFS HLP_Macro; /* Help for macro menu */ + OFS UUCP_list; /* Address list for UUCP */ + OFS HLP_IChat; /* Interline chat help */ + OFS protocols[MAX_EXTERN]; /* external file protocol programs */ + +/*v18*/ OFS OFS_Filler[7]; + + /*-----------------------------------------------------------*/ + /* Log_Name must always be the last offset in this struct */ + /* because Bbs_Init uses that symbol to flag the end of */ + /* the offsets. */ + /*-----------------------------------------------------------*/ + OFS log_name; /* name of the log file */ + + + /*-----------------------------------------------------------*/ + /* Big blob of stuff */ + /* It's a sequence of null-terminated character arrays... */ + /* pointed-to by the offsets (above). */ + /*-----------------------------------------------------------*/ + char buf[CTLSIZE]; + end; + +#define ASK_PHONE 0x01 /* Used with xuflags */ +#define ASK_ALIAS 0x02 /* Used with xuflags */ +#define ASK_REAL 0x04 /* Used with xuflags */ +#define ASK_CITY 0x08 /* Used with xuflags */ +#define CAN_ALIAS 0x10 /* Allow ALIAS' in some situations */ +#define ASK_BDAY 0x20 /* Ask user for birthday */ +#define ASK_ADDRESS 0x40 /* Ask user for street address */ + + /* Means no privilege level is set and/or applicable At LOGON, */ + /* for example, it means system is for PRE-REGISTERED users only. */ +#define NO_PRIV 0xFF + +struct _common_data { + + char Opus[16]; /* "OPUS-CBCS 1.20" */ + long QuotePosition; /* Quote file position */ + long CallerCount; /* Number of callers */ + long Caller_ID; /* ID of current newest user */ + long MSG_ID; /* Last used MSGID */ + word FILLER[15]; /* RESERVED - do not use */ + word MAX_task; /* Highest task number */ +}; + +/* Explanation of _common_data: + + Opus will EXPECT to find "OPUS-CBCS 1.20" at the beginning of this file. + If it does not find it, Opus will assume the file belongs to someone + else and will ignore the file. + + File ctl.common is optional. It should be used only by systems that + multitask. Its purpose is to allow separate schedule files for each + task. If the file does not exist, Last quote pointer and Caller count + are read from and updated in the scheduler. + + On the other hand, if this file exists the quote pointer is only updated + in this file. Caller Count is updated separately both in the scheduler + and this file, to allow separate statistics for each task, plus total + statistics. + + MAX_task is informative only and should be set by the sysop. Its purpose + is to help external intertask programs figure out how many tasks there + exist. Its purpose is defeated if task numbers are not consecutive. + + More data may be added in the future. If so, either the FILLER field + will be used, or the data will be appended. Existing definitions will + remain it their respective places. Any FILLER bytes will be set to 0. + */ + + + +/*--------------------------------------------------------------------------*/ +/* MATRIX_CHANGED flags */ +/*--------------------------------------------------------------------------*/ + +#define MATRIX_CHANGED 0x0001 /* Changed matrix area. Scan */ +#define LOCAL_CHANGED 0x0002 /* Changed Local area. */ +#define GOT_BUNDLE 0x0100 /* Received a PKT file */ +#define GOT_ARCMAIL 0x0200 /* Received an archived file */ +#define GOT_REQUESTS 0x0400 /* Got file requests to handle */ +#define GOT_ECHOMAIL 0x1000 /* Received Echomail */ + +/*--------------------------------------------------------------------------*/ +/* INTERLINE FLAGS */ +/*--------------------------------------------------------------------------*/ +#define CAN_CHAT 0x01 /* Multiline systems can do chats */ + +// END OF SUB-INCLUDE PRM18.H //////////////////////////////////////////////////// + + +/*--------------------------------------------------------------------------*/ +/* Multitaskers (possible values for `ctl.multitasker' */ +/* NOTE: 0 means no multitasker in use */ +/*--------------------------------------------------------------------------*/ +#define DoubleDOS 1 +#define DesqView 2 +#define TopView 3 +#define TaskView 3 +#define LAN 0x80 + +/*--------------------------------------------------------------------------*/ +/* Matrix mask */ +/* Undefined bits are reserved by Opus See EVENT.H */ +/*--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------*/ +/* FLAGS */ +/*--------------------------------------------------------------------------*/ +#define LOGECHO 0x01 /* log echomail areas 0000 0001 */ +#define STEADY 0x02 /* never change baud rate 0000 0010 */ +#define ECHOSCAN 0x04 /* automatically scan echo's 0000 0100 */ +#define ECHO_GUARD 0x08 /* no toss un-pwd echo arc 0000 1000 */ +#define LEAVE_ESCN 0x10 /* Leave echotoss.log after Scanning 0001 0000 */ +#define DO_MSGID 0x20 /* Put MSGID lines into echomail 0010 0000 */ +#define F_NOCRASH 0x40 /* Don't accept crash mail 0100 0000 */ +#define F_UNPK 0x80 /* Unpack incomming arcmail 1000 0000 */ + + +/*--------------------------------------------------------------------------*/ +/* FLAGS 2 */ +/*--------------------------------------------------------------------------*/ +#define NO_USRLIST 0x01 /* no user list (enter msg) 0000 0001 */ +#define WATCHDOG 0x02 /* Reboot during outside 0000 0010 */ +#define F2_TOSS 0x04 /* Toss incomming echomail 0000 0100 */ +#define F2_LASTREAD 0x08 /* Uses LASTREAD for Sysop 0000 1000 */ +#define F2_DOSFILE 0x10 /* Close stdAUX and stdPRN 0001 0000 */ +#define F2_PRIMARY 0x20 /* MultiTasker Primary task 0010 0000 */ +#define F2_SECOND 0x40 /* MultiTasker Secondary task 0100 0000 */ +#define F2_ECON 0x80 /* Econo Echo handling 1000 0000 */ + + +/*--------------------------------------------------------------------------*/ +/* FLAGS 3 */ +/*--------------------------------------------------------------------------*/ +#define F3STEADY 0x01 /* Can do ARQ steady. &B2 */ +#define F3GMENU 0x02 /* Will let users do graphics menus */ +#define F3LOGOFF 0x04 /* Collect logoff messages */ +#define F3NOALIAS 0x08 /* Don't put alias' in SEEN-BY */ +#define F3HINAMES 0x10 /* Allow users with hi-bit names */ + +/*--------------------------------------------------------------------------*/ +/* FWDflags (bits to control IN TRANSIT messages) */ +/*--------------------------------------------------------------------------*/ +#define FWD_NONE 0x01 /* No IN TRANSIT netmail 0000 0001 */ +#define FWD_PWD 0x02 /* IN TRANSIT by pwd only 0000 0010 */ +#define FWD_TONET 0x04 /* Accept IN TRANSIT only to my net 0000 0100 */ +#define FWD_NOBITS 0x08 /* No IN TRANSIT if extended bits used 0000 1000 */ +#define FWD_HOST 0x10 /* Send mail to host if can't find. */ +#define VERSION6 0x40 /* Use Version 6 nodelist */ +#define IMAPOINT 0x80 /* This is a point */ + +/*--------------------------------------------------------------------------*/ +/* LOG FLAGS */ +/*--------------------------------------------------------------------------*/ +#define LOG_TERSE 0x01 /* brief log 0000 0001 */ +#define LOG_wordY 0x02 /* wordy log 0000 0010 */ +#define LOG_TRACE 0x04 /* very wordy log 0000 0100 */ + + +/*--------------------------------------------------------------------------*/ +/* MODEM FLAGS */ +/*--------------------------------------------------------------------------*/ +#define M_SNOOP 0x01 /* sysop display on 0000 0001 */ +#define MOUSE 0x02 /* sysop mouse on 0000 0010 */ +#define M_BRKCLEAR 0x04 /* Use BREAK to clear outbound buffer 0000 0100 */ +#define SLOW_MODEM 0x08 /* Slow modem and fast computer */ + +/*--------------------------------------------------------------------------*/ +/* STYLE FLAGS */ +/*--------------------------------------------------------------------------*/ +#define SF_PATH 0x01 /* use path, not Dir.Bbs 0000 0001 */ +#define SF_KILL 0x02 /* Kill rec'd pvt messages 0000 0010 */ +#define SF_ASKKILL 0x04 /* ASK about killing msgs 0000 0100 */ +#define SF_EUROPE 0x08 /* European date strings */ +#define SF_TIME 0x10 /* Show time remaining on menu 0001 0000 */ +#define SF_NOFLAG 0x20 /* Don't allow user config at logon 0010 0000 */ +#define SF_HANDHOLD 0x40 /* Track user's errors and add help 0100 0000 */ +#define SF_NOHIGH 0x80 /* Track user's errors and add help 0100 0000 */ + + +#define SET_FLAG(x,y) ((x)|=(y)) +#define CLEAR_FLAG(x,y) ((x)&=(~(y))) +#define isFLAG(x,y) ((x)&(y)) + + + + + +/*--------------------------------------------------------------------------*/ +/* The rest of this file contains structure definitions similar to those */ +/* used by Fido version 11w. No claim is made that Opus will maintain */ +/* compatibility with these structures beyond Opus version 0. */ +/* */ +/* The original version of the following items can be found in STRUCT.H, an */ +/* include file writte (and probably copyrighted by) Tom Jennings. */ +/*--------------------------------------------------------------------------*/ + + + + +/*--------------------------------------------------------------------------*/ +/* THE USER DATABASE */ +/*--------------------------------------------------------------------------*/ + +#define MAX_USEC 80 /* Maximum number of areas in "user" section */ + + struct _usr + { + char name[36]; /* Caller's first and last names */ + char city[36]; /* Caller's location */ + char pwd[16]; /* Password */ + char usrtel[16]; /* User Tel# for ref or future callback .........*/ + char alias[32]; /* User alias if ID is not it ...................*/ +/* 136 bytes */ + word times; /* Number of previous calls to this system */ + byte ClassPriv; /* User Access Privilege */ + byte help; /* Help level (see below) */ + byte tabs; /* 0=transmit instead of */ + byte language; /* 0=english, 1=french */ + word nulls; /* Number of Nulls (delays) after */ + word msg; /* Last message area visited */ + word Bits; /* SEE BELOW */ +/* 148 bytes */ + long ClassLock; /* 32 User Keys */ + + long ludate; /* Last UNIX Date on system */ +/* 156 bytes */ + short time; /* Time on-line so-far today */ + + word flag; /* Used to hold User maintainence information */ + /* -------1 0x01 Reuse record for next new user */ + /* xxxxxxx0 ---- Reserved reserved for opus Mgr */ + + long upld; /* K-bytes uploaded, all calls */ + long dnld; /* K-bytes downloaded, all calls */ + short dnldl; /* K-bytes downloaded, today */ + word files; /* Last file area visited */ + byte width; /* Width of the caller's monitor */ + byte len; /* Height of the caller's */ + word credit; /* FidoNet usage credit in cents */ + word debit; /* FidoNet usage in cents */ + + char spcoec[8]; /* Special OECC to show after logon .............*/ + /* Good for clubs, stores, user groups ..........*/ + /* Eg, "Welcome to the dBase User Group" ........*/ + + byte saccnt[5]; /* Array of 5 special announcement cntrs ........*/ + /* If any is > 0 than the user is shown .........*/ + /* a corresponding announcement file & the ......*/ + /* counter is decremented till zero .............*/ + + byte exflag; /* Flag of expiration control bits ..............*/ + /* -------- 000 No expiry actions ...............*/ + /* -------1 001 Expire AFTER xdate ..............*/ + /* ------1- 002 Expire when dbmin GE crmin ......*/ + /* -----:-- 004 ... Reserved ... ...............*/ + /* ----:--- 008 ... Reserved ... ...............*/ + /* ---1---- 016 Demote user priv to (expriv) ....*/ + /* --1----- 032 Axe user when expired ..........*/ + /* -:------ 064 ... Reserved ... ...............*/ + /* :------- 128 ... Reserved ... ...............*/ + + + long xdate; /* Expiry date (UNIX style for math/futr)........*/ + long crmin; /* Total minutes given to user ..................*/ + long dbmin; /* Total minutes used to user ..................*/ + + char u_section[16]; /* String for user current section */ + char ulikes[16]; /* String of user interest keywords .............*/ + long fudate; /* First time user called system in seconds */ + unsigned long caller_id; /* Unique ID for this user. fudate */ + unsigned long Section; /* What "section" of the bbs the user is in. */ + word menu_mode; /* What menu the user was at last ...............*/ + word TwoBits; /* More user configuration flags */ + word After_Externs; /* Any special flags from external? */ + byte msecs; /* Number of message areas in User sections defined */ + byte fsecs; /* Number of file areas in User sections defined */ + +/* terminated!! */ +#ifdef OLD + word lastmsg[MAXLREAD]; /* All the last message read stuff .....*/ +#else +/* New for Opus 1.20 */ + char Address[32]; /* User's address */ + char My_Ans[64]; /* Reply to prm.My_Question */ + char Strfill[32]; /* Filler for more strings */ + char bday_mon; /* User's birthday/month */ + char bday_day; /* User's birthday/day */ + short bday_year; /* User's birthday/year */ + unsigned long messages_read; /* Total number of messages read */ + long messages_sent; /* Number of messages entered by user */ + + word my_section[MAX_USEC]; /* This is just a block of area */ + /* numbers in the user's Section */ + /* Message areas are first, then */ + /* file areas. The first file */ + /* area is at my_section[msecs] */ + + word big_fill[40]; /* Fill out to 512 bytes */ + word Opus_Flags; /* Stores Opus temporary configuration */ + byte byte_fill; + byte Default_Protocol; /* Default transfer protocol */ + byte User_MMacro[16]; /* Message User's keyboard Macro */ + byte User_FMacro[16]; /* File User's keyboard Macro */ + byte User_DMacro[16]; /* Default User's keyboard Macro */ + byte Sysop_Comment[80]; /* Anything you want to say about 'em */ +#endif + unsigned long OPUS_id; + + /* The next 7 sets of id and inf data are for */ + /* external programs to use for auxialliary inf. */ + /* Opus Mgr uses 1st 2 for reamrks about user. */ + + long extern_id[7]; /* LONG ID number for external programs */ + /* Must be registered with OpusInfo ....*/ + byte extern_inf[7][32]; /* 7 32-byte external util data blocks */ + + /* Total record size = 1024b .........................................*/ + }; + + +/*--------------------------------------------------------------------------*/ +/* USER OPTIONS bit weights (undefined bits are reserved) */ +/*--------------------------------------------------------------------------*/ +#define FillerBit 0x0001 /* Reserved */ +#define ASKED_LEN 0x0002 /* Asked user for screen length? */ +#define NO_IBMCHAR 0x0004 /* Cannot receive IBM textmode graphics */ +#define USE_LORE 0x0008 /* Wants LORE editor instead of OPed */ +#define MORE_PROMPT 0x0010 /* Wants the page break "MORE?" question */ +#define ANSI 0x0020 /* Can handle ANSI video */ +#define CONFIG_SET 0x0040 /* OPUS logon questions answered */ +#define FORMFEED 0x0080 /* SET=xmit clearscreen, CLEAR=eat formfeed */ +#define AVATAR 0x0100 /* Can handle AVATAR (aka "oANSI") video */ +#define TALKER 0x0200 /* Wants limited graphics for speech */ + +#define USE_PHONE 0x0400 /* Call Back User Modem */ +#define USE_ALIAS 0x0800 /* Enable ALIAS searches, message entry, etc */ + +#define NO_NAME 0x1000 /* User List Name */ +#define NO_TIME 0x2000 /* User List Time */ +#define NO_CITY 0x4000 /* User List City */ + + +#define CURSOR_CONTROL (ANSI|AVATAR) + +/*--------------------------------------------------------------------------*/ +/* 2Bits flags (More user configuration choices.... */ +/*--------------------------------------------------------------------------*/ +#define HOTKEYS 0x0001 /* Wants HotKeys at all help levels */ +#define QMENU 0x0002 /* Wants to return to last menu instead of MAIN */ +#define ASKGRAPH 0x0004 /* Wants to be asked about graphics every logon */ +#define ASCIIMENU 0x0008 /* Wants long tedious graphics menus */ +#define SHOW_TIME 0x0010 /* Show time remaining at prompts */ +#define BLOCKCHAT 0x4000 /* User doesn't want to be sociable. */ +#define INCRITAREA 0x8000 /* Opus is in critical area */ + + +/*--------------------------------------------------------------------------*/ +/* eXpiration flags */ +/*--------------------------------------------------------------------------*/ +#define BY_DATE 0x0001 /* Zap users by date */ +#define BY_TIME 0x0002 /* Zap users when they run out of credit */ +#define DEMOTE 0x0010 /* Demote user instead of deleting them */ +#define AXE 0x0020 /* Delete user */ + + +/*--------------------------------------------------------------------------*/ +/* User help levels */ +/*--------------------------------------------------------------------------*/ +#define HITECH 0x00 /* Lotus style, top-of-screen, menu bars */ +#define EXPERT 0x02 /* grizzled veteran, no menus at all */ +#define REGULAR 0x04 /* experienced user, brief menus */ +#define NOVICE 0x06 /* Full menus plus additional hand-holding */ +#define USING_FTB 0xff /* caller is using the Full-Tilt-Boogie method */ + +/*--------------------------------------------------------------------------*/ +/* Flags for After_Externs */ +/*--------------------------------------------------------------------------*/ +#define NEW_ECHOS 0x0001 /* New Echomail entered by user */ +#define NEW_MATRIX 0x0002 /* New Matrix entered by user */ +#define NEW_LOCAL 0x0004 /* New Local mail entered by user */ +#define UPLOADED 0x0008 /* User uploaded something */ +#define DUP_UPLOAD 0x0010 /* User uploaded a duplicate file */ + +/*--------------------------------------------------------------------------*/ +/* LASTUSER.BBS file structure */ +/*--------------------------------------------------------------------------*/ +/* Struct of LASTUSE#.BBS file that is written everytime a user logons on */ +/* or when Opus does an OUTSIDE exit. It contains a complete and exact */ +/* copy of the user record, following by extended data for session control. */ +/* If PRM is configured to reload user data upon return from an OUTSIDE */ +/* exit, then Opus reloads user record portion, making it the active copy. */ +/*--------------------------------------------------------------------------*/ + +#ifdef _TM_DEFINED +struct _lu_file + begin + struct _usr user; /* Copy of user record */ + word baud; /* Current user's baud (0 == keyboard!) */ + word port; /* Current port # */ + word task; /* Active task number */ + word mins; /* User's minutes remaining */ + word msgarea; /* Which message area user is in */ + word filearea; /* Which file area user is in */ + long timeoff; /* UNIX GMT of latest time user stays on till */ + struct tm tmoff; /* MS-C 'tm' struct of above but as local time */ + char laston[25]; /* Orig Last Call Date as ASCIIZ string because */ + /* same field in user rec now is curr logon time */ + end; +#endif + + +/*-------------------------------------------------------------------------*/ +/* */ +/* MESSAGE and FILE AREAS */ +/* */ +/*-------------------------------------------------------------------------*/ + +/* See SYSTEM.H */ + + + +/*--------------------------------------------------------------------------*/ +/* */ +/* MESSAGES */ +/* */ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +/* Message header */ +/*--------------------------------------------------------------------------*/ +struct opus_msg + begin + byte from[36]; + byte to[36]; + byte subj[72]; + byte date[20]; /* Obsolete/unused ASCII date information */ + word times; /* FIDO: Number of times read */ + word dest; /* Destination node */ + word orig; /* Origination node number */ + word cost; /* Unit cost charged to send the message */ + + word orig_net; /* Origination network number */ + word dest_net; /* Destination network number */ + + /* A TIMESTAMP is a 32-bit integer in the Unix */ + /* flavor (ie. the number of seconds since */ + /* January 1, 1970). Timestamps in messages are */ + /* always Greenwich Mean Time, never local time. */ + + struct _stamp date_written; /* When user wrote the msg */ + struct _stamp date_arrived; /* When msg arrived on-line */ + + word reply; /* Current msg is a reply to this msg number */ + word attr; /* Attribute (behavior) of the message */ + word up; /* Next message in the thread */ + end; + + + +/*--------------------------------------------------------------------------*/ +/* Message attributes */ +/*--------------------------------------------------------------------------*/ +#define MSGPRIVATE 0x0001 /* private message * 0000 0000 0000 0001 */ +#define MSGCRASH 0x0002 /* squirtmail * 0000 0000 0000 0010 */ +#define MSGREAD 0x0004 /* read by addressee * 0000 0000 0000 0100 */ +#define MSGSENT 0x0008 /* sent OK (remote) 0000 0000 0000 1000 */ +#define MSGFILE 0x0010 /* file attached to msg * 0000 0000 0001 0000 */ +#define MSGFWD 0x0020 /* in transit 0000 0000 0010 0000 */ +#define MSGORPHAN 0x0040 /* unknown dest node 0000 0000 0100 0000 */ +#define MSGKILL 0x0080 /* kill after bundling * 0000 0000 1000 0000 */ +#define MSGLOCAL 0x0100 /* FidoNet vs. local 0000 0001 0000 0000 */ +#define MSGHOLD 0x0200 /* Hold, don't send * 0000 0010 0000 0000 */ +#define MSGXX2 0x0400 /* X? 0000 0100 0000 0000 */ +#define MSGFRQ 0x0800 /* file request * 0000 1000 0000 0000 */ +#define MSGRRQ 0x1000 /* receipt requested X* 0001 0000 0000 0000 */ +#define MSGCPT 0x2000 /* is a return receipt X* 0010 0000 0000 0000 */ +#define MSGARQ 0x4000 /* audit trail requested X* 0100 0000 0000 0000 */ +#define MSGURQ 0x8000 /* update request X* 1000 0000 0000 0000 */ + /*-----------------------*/ + /* ^ */ + /* | */ + /* * = preserved by */ + /* the network */ + /* ? = stripped by the */ + /* net (FTSC spec) */ + /* but preserved */ + /* by seadog */ + /* X = not used by Opus */ + /*-----------------------*/ + + + + +/*--------------------------------------------------------------------------*/ +/* */ +/* EVENTS */ +/* */ +/*--------------------------------------------------------------------------*/ +/* #include */ + +/*--------------------------------------------------------------------------*/ +/* Message bundle header */ +/*--------------------------------------------------------------------------*/ + +#define PKTVER 2 /* Used for `ver' (below) */ + +struct _pkthdr + begin + short orig_node; /* originating node */ + short dest_node; /* destination node */ + short year; /* 0..99 when packet was created */ + short month; /* 1..12 when packet was created */ + short day; /* 1..31 when packet was created */ + short hour; /* 0..23 when packet was created */ + short minute; /* 0..59 when packet was created */ + short second; /* 0..59 when packet was created */ + short rate; /* destination's baud rate */ + short ver; /* packet version */ + short orig_net; /* originating network number */ + short dest_net; /* destination network number */ + char product; /* product type */ + char x1; /* filler (used by some systems) */ + + /* ------------------------------ */ + /* THE FOLLOWING SECTION IS not */ + /* THE SAME ACROSS SYSTEM LINES: */ + /* ------------------------------ */ + byte pktpwd[6]; + byte B_fill1[2]; + word Orig_Zone; + word Dest_Zone; + byte B_fill2[16]; + long B_fill3; + end; + + + + + + + + + +/*--------------------------------------------------------------------------*/ +/* WAZOO */ +/*--------------------------------------------------------------------------*/ + +#ifndef ACK +#define ACK 0x06 +#endif + +#ifndef NAK +#define NAK 0x15 +#endif + +#ifndef ENQ +#define ENQ 0x05 +#endif + +#ifndef YOOHOO +#define YOOHOO 0x00f1 /* 241 (a prime number, I think) */ +#endif + +#ifndef TSYNC +#define TSYNC 0x00ae +#endif + +struct _Hello + begin + word signal; /* always 'o' (0x6f) */ + word hello_version; /* currently 1 (0x01) */ + word product; /* product code */ + word product_maj; /* major revision of the product */ + word product_min; /* minor revision of the product */ + char my_name[60]; /* Other end's name */ + char sysop[20]; /* sysop's name */ + ADDR my_address; + byte my_password[8]; /* ONLY 6 CHARACTERS ARE SIGNIFICANT !!!!! */ + byte reserved2[8]; /* reserved by Opus */ + word capabilities; /* see below */ + byte reserved3[12]; /* available to non-Opus systems by prior */ + /* "approval" of 124/108. */ + end; /* size 128 bytes */ + + +/*--------------------------------------------------------------------------*/ +/* YOOHOO CAPABILITY VALUES */ +/*--------------------------------------------------------------------------*/ +#define Y_DIETIFNA 0x0001 /* Can do LoTek 0000 0000 0000 0001 */ +#define FTB_USER 0x0002 /* reserved by Opus 0000 0000 0000 0010 */ +#define Bit_2 0x0004 /* reserved by Opus 0000 0000 0000 0100 */ +#define ZED_ZAPPER 0x0008 /* Can do ZModem/plain 0000 0000 0000 1000 */ +#define DOES_IANUS 0x0010 /* Does Opus Janus 0000 0000 0001 0000 */ +#define Bit_5 0x0020 /* reserved by Opus 0000 0000 0010 0000 */ +#define Bit_6 0x0040 /* reserved by Opus 0000 0000 0100 0000 */ +#define Bit_7 0x0080 /* reserved by Opus 0000 0000 1000 0000 */ +#define Bit_8 0x0100 /* reserved by Opus 0000 0001 0000 0000 */ +#define Bit_9 0x0200 /* reserved by Opus 0000 0010 0000 0000 */ +#define Bit_a 0x0400 /* reserved by Opus 0000 0100 0000 0000 */ +#define Bit_b 0x0800 /* reserved by Opus 0000 1000 0000 0000 */ +#define Bit_c 0x1000 /* reserved by Opus 0001 0000 0000 0000 */ +#define Bit_d 0x2000 /* reserved by Opus 0010 0000 0000 0000 */ +#define Bit_e 0x4000 /* reserved by Opus 0100 0000 0000 0000 */ +#define WZ_FREQ 0x8000 /* accepts file requests 1000 0000 0000 0000 */ + + +/* + + User Indexing Support Items + + Bit setting of (word) UDB_Flags + + & 1 ... Set ON if user name CRC indexing is expected. The general + init func should look for User.Idx and check its size for + a match to the user file size. Must be nrecs * sizeof(long). + + Or, can simply be forced on and the first func that finds the + index to be missing or inconsistent will give a short status + error and turn the bit off, stopping further index attempts. + + & 2 ... Set ON if user file locking is to be attempted which requires + SHARE.EXE to be loaded. This is desired as updates to the + user file index should be controlled as access to 2 separate + files in a multitasked scenario can span some time and the + chance of indexing errors is quite high. When ON, the 1st byte + of ONLY the user file is locked to mean that the user database + is being updated. There should be no need to lock the index + as the user file is always accessed first. + + It has to be tested to see if the effect of other read accesses + to the user file (eg, user listing, searching) will fail if + the file is locked during an update. I suspect that other + activities will be transparent to it and ONLY other LOCKING + attempts will be foiled. This would allow compatibility with + other existing R/O accesses to the file. + + If it proves to be safe, we can force this ON and allow the + the first function wherein it fails to turn it off with a + single short message. + +*/ + +#define UsrIdx 1 /* Says, Attempt CRC indexing */ +#define UsrLok 2 /* Says, Attempt File Locking */ +#define UsrPwd 4 + +#define HAS_UF(v) (ctl.UDB_Flags & v) /* Check if Ufile feature used */ +#define STOP_UF(v) ctl.UDB_Flags &= ~v /* Turn off Ufile feature */ + +/* END OF FILE: opus.h */ + + +// INCLUDE SYSTEM.H ////////////////////////////////////////////////////////// + +/*--------------------------------------------------------------------------*/ +/* */ +/* The Opus Computer-Based Conversation System */ +/* (c) Copyright 1986-1991, Wynn Wagner III, All Rights Reserved */ +/* */ +/* */ +/* YOOHOO is a trademark of Wynn Wagner III */ +/* */ +/* YOOHOO-YOOHOO/2U2 & WaZOO are */ +/* Copyright 1987, Wynn Wagner III, All Rights Reserved */ +/* */ +/* */ +/* This material is available for use by anybody with no strings and */ +/* no guarantees. */ +/* */ +/* */ +/*--------------------------------------------------------------------------*/ +/* */ +/* OPUS 1.20 Message/File area database structures. */ +/* Copyright 1991 Wynn Wagner III, Doug Boone and John Valentyn. */ +/* */ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +/* LEGIBLE SECTION. Definitions to make "C" look like a real language. */ +/*--------------------------------------------------------------------------*/ + +#ifndef begin +# define begin { +# define end } +# define true (-1) +# define false 0 +# define Procedure void +# define shl << +# define shr >> +# define xor ^ +# define and && +# define or || +# define not ! +# define mod % + typedef unsigned Bit; + typedef unsigned short word; + typedef unsigned char byte; + typedef unsigned char const * const STRING; +# define fallthrough /* ... for use in switch statements for clarity. */ +#endif + + +#ifndef max +#define max(a,b) ((a)>(b)?(a):(b)) +#endif + +#ifndef min +#define min(a,b) ((a)<=(b)?(a):(b)) +#endif + + +/*--------------------------------------------------------------------------*/ +/* Structure for SYSMSG.DAT */ +/* A single-file message area database */ +/*--------------------------------------------------------------------------*/ + +struct _filesys { + + char Area_Name[32]; /* Area's primary name */ + + word Area_Number; /* area number */ + word Area_Menu; /* which menu? */ + word Total_Size; + + byte Area_Priv; /* Area Privilege */ + byte Down_Priv; /* Download Privilege */ + + byte Up_Priv; + byte Priv_Up; /* Uploads from users with Priv>= Priv_Up */ + byte Ratio_Priv; /* Privilege where u/d ratios start */ + byte New_Priv; + + byte fill_byte1[2]; +/* 48 */ + word Attrib; /* Area Attribute */ + word Status; /* Area Status, extended Attribute? */ + + long Start_Pos; /* start of Area in sysfile.dat */ +/* 56 */ + long Area_Lock; /* Area Lock */ + + long Up_Lock; + + long Down_Lock; /* edit Lock */ + + long Priv_Key; /* Private Key path */ + +/* 72 */ + long Section; /* edit Lock */ + + long fill_long[2]; + + byte Title_Len; /* length of Title */ + byte Prefiles_Len; /* files shown at Area access like Areainfo */ + + byte Downpath_Len; /* length of path */ + byte Uppath_Len; /* length of path */ +/* 88 */ + byte Barricade_Len; /* Barricade length if used */ + byte Rules_Len; + + byte Privkey_Len; /* Uploads from users with "key" go here */ + byte PrivUp_Len; /* Private Upload path */ + byte Menu_Len; /* file name for this area's ascii menu */ + byte Vol_Len; /* Length of volume name */ + byte Help_Len; /* Length of help name for this area */ + + byte fill_byte2[5]; /* more filler */ +/* 100 */ + word Other_Len; /* external programs use this number bytes */ + + word Def_Upload; /* Area number for default uploads */ + word Priv_Upload; /* Area number for Priv uploads */ + word Key_Upload; /* Area number for Lock uploads */ + + word fill_word[10]; /* more filler to 128 bytes*/ +}; + +/* Title */ +/* Prefiles */ +/* Downpath */ +/* Barricade */ +/* Rules */ +/* Menu */ +/* Help */ +/* Upload */ +/* Priv Upload */ +/* Key Upload */ +/* File area help file */ +/* Volume */ +/* "Other" field. Reserved for external programs */ + +/*--------------------------------------------------------------------------*/ +/* Structure for SYSMSG.DAT */ +/* A single-file message Area database */ +/*--------------------------------------------------------------------------*/ + +struct _msgsys { + + char Area_Name[32]; /* Area's primary name */ + char Echo_Name[32]; /* Area's echo name */ + word Area_Number; /* Area number */ + word Area_Menu; /* which menu? */ + word Total_Size; /* Total size of this Area in SYSMSG.DAT */ + + byte Area_Priv; /* Area Privilege */ + byte Edit_Priv; /* Edit Privilege */ + byte Private_Priv; /* Privilege to read Private messages*/ + byte Upload_Priv; + byte fill_0[3]; + byte Translate; /* Which character set to use 1, 2.... */ +/* 80 */ + long Area_Lock; /* Area Lock */ + long Edit_Lock; /* Edit Lock */ + + long Private_Lock; /* Lock to read Private messages*/ + long Upload_Lock; + + word Attrib; /* Area Attribute */ + word Status; /* Area Status, extended Attribute? */ + + long Start_Pos; /* start of Area in sysmsg.dat */ + long Section; + byte Max_Lines; /* Maximum number of lines in messages */ + byte fill_1[3]; +/* 112 */ + + word Zone; + word Net; + word Node; + word Point; + + byte Path_Len; /* length of Path */ + byte Title_Len; /* length of Title */ + + byte Barricade_Len; /* Barricade length if used */ + byte Origin_Len; /* non-default Origin line */ + + byte Domain_Len; /* Domain (if used) length */ + byte Menu_Len; /* file name for this area's ascii menu */ + byte Vol_Len; /* Length of volume name */ + byte Help_Len; /* Length of help name for this area */ +/* 144 */ + + byte Scan_Len; /* number of boards that Area is Scanned to */ + byte Scan_Pos; /* where Opus is in the Scan right now */ + word Other_Len; /* external programs use this number bytes */ + word Extern_Flags; + word word_fill[5]; +/* 160 */ +}; + +/*--------------------------------------------------------------------------*/ +/* Then some strings/structures follow as needed */ +/*--------------------------------------------------------------------------*/ + /* Path string */ + /* Title string */ + /* Barricade string */ + /* Origin string */ + /* Domain string */ + /* Menu string */ + /* Message area help file */ + /* Volume ID */ + /* aScan[Scan_Len] echoScan addresses */ + /* "Other" field. Reserved for external programs */ + +/*--------------------------------------------------------------------------*/ +/* end of strings */ +/*--------------------------------------------------------------------------*/ + + +struct _ascan { /* structure of address for echoScanning */ + word Net; + word Node; +}; + +/*--------------------------------------------------------------------------*/ +/* LMR is used in LREAD.DAT to store the user's last message read counter */ +/*--------------------------------------------------------------------------*/ +struct _lmr { + unsigned long user_id; + word high_msg; + word last_msg; +}; + +/*--------------------------------------------------------------------------*/ +/* LF is used to store the last time a user has accessed each area */ +/*--------------------------------------------------------------------------*/ +struct _lf { + unsigned long user_id; + unsigned long last_timestamp; +}; + +/*--------------------------------------------------------------------------*/ +/* File Area attributes (limit or describe the behavior of an area) */ +/*--------------------------------------------------------------------------*/ + +#define F_DUPE 0x0001 /* Allow duplicate uploads in this area */ +#define F_FREE 0x0002 /* Downloads from this area area all 0K */ + + +/*--------------------------------------------------------------------------*/ +/* Area attributes (limit or describe the behavior of an area) */ +/*--------------------------------------------------------------------------*/ +#define SYSMAIL 0x01 /* is a mail area */ +#define P_REP 0x02 /* Net mail private echomail back */ +#define NOPUBLIC 0x04 /* OPUS: Disallow public messages */ +#define NOPRIVATE 0x08 /* OPUS: Disallow private messages */ +#define ANON_OK 0x10 /* OPUS: Enable anonymous messages */ +#define _ECHOMAIL 0x20 /* OPUS: Set=Echomail Clear=Not Echomail */ +#define USEALIAS 0x40 /* OPUS: Use user's alias in this area if..... */ +//#define PASSTHROUGH 0x80 /* OPUS: Allow high-bit characters in echo area */ +#define INBOUND 0x0100 /* Inbound Only area */ + + +/*--------------------------------------------------------------------------*/ +/* msgsys.Extern_Flags */ +/* Opus will not use these flags, set them or anything. The ones that are */ +/* marked as RESERVED will be defined in the future for "standard" uses. */ +/* The ones marked as EXTERN will have no "standard" meaning so conflicting */ +/* programs MAY have conflicting uses. */ +/*--------------------------------------------------------------------------*/ + +#define RENUMBER 0x0001 /* This area gets renumbered */ +#define MAILCHECK 0x0002 /* The mail check program will do this area */ +#define RESERVED2 0x0004 /* Reserved for Opus-defined flags */ +#define RESERVED3 0x0008 /* Reserved for Opus-defined flags */ +#define RESERVED4 0x0010 /* Reserved for Opus-defined flags */ +#define RESERVED5 0x0020 /* Reserved for Opus-defined flags */ +#define RESERVED6 0x0040 /* Reserved for Opus-defined flags */ +#define RESERVED7 0x0080 /* Reserved for Opus-defined flags */ +#define EXTERN1 0x0100 /* Undefined! Meaning varies for each program*/ +#define EXTERN2 0x0200 /* Undefined! Meaning varies for each program*/ +#define EXTERN3 0x0400 /* Undefined! Meaning varies for each program*/ +#define EXTERN4 0x0800 /* Undefined! Meaning varies for each program*/ +#define EXTERN5 0x1000 /* Undefined! Meaning varies for each program*/ +#define EXTERN6 0x2000 /* Undefined! Meaning varies for each program*/ +#define EXTERN7 0x4000 /* Undefined! Meaning varies for each program*/ +#define EXTERN8 0x8000 /* Undefined! Meaning varies for each program*/ + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gs_pb200.h b/goldlib/gcfg/gs_pb200.h new file mode 100644 index 0000000..c433ddb --- /dev/null +++ b/goldlib/gcfg/gs_pb200.h @@ -0,0 +1,506 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ + +/* + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ ProBoard v2.00 File Structures ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + +This document describes the file structures used by ProBoard version 2.00. +For information on the structures of the RemoteAccess compatible files, refer +to the RemoteAccess structures document. It can be obtained from any of the +ProBoard distribution sites. + +------------------------------------------------------------------------------- + +The data-structures are C-structures, this means: + +- Strings are stored as an array of characters, terminated by a 0. +- A date is stored as 3 bytes (day,month,year) +- A time is stored as 3 bytes (hour,min,sec) + +The 'accessflags' are stored in a long integer, with bit 31 being flag 'A', +bit 30 flag 'B' , ... Bit 5 is flag '1', bit 4 is flag '2', etc... +I know this doesn't sound logical, but we had some good reasons for doing +this . + +The combined boards are stored in 25 bytes (200 bits). One bit per message +area. +*/ + +//typedef unsigned short uint; +//typedef unsigned long ulong; +//typedef unsigned char byte; +typedef unsigned long accessflags; +typedef unsigned char combinedboards[125]; +typedef unsigned char pb_bool; +typedef unsigned char pb_Time[3]; +typedef unsigned char Date[3]; +typedef unsigned char TimeFrame[7][6]; + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + USERSPB.BBS +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + +This file is tied to the files USERS.BBS and USERSXI.BBS. The records are +stored in the same order as the records in USERS.BBS. The name of the user +is duplicated in this file, so it is possible to fix the userfile after using +a third-party userfile packer/sorter, which does not know about USERSPB.BBS. + +*/ + +struct UsersPbBBS + { + char name[36]; + char country[26]; + char state[26]; + char faxPhone[16]; + char passWord[16]; + char language[9]; + Date lastPwdChange; + Date lastNewFilesCheck; + short logLevel; + short tbTimeBalance; + short tbKbBalance; + short tbTimeWithdrawn; + short tbKbWithdrawn; + uint tbTimeDeposited; + uint tbKbDeposited; + uint tbTimeLoaned; + uint tbKbLoaned; + Date tbTimePayback; + Date tbKbPayback; + Date tbLastUsed; + + uint expLevel; + accessflags expFlagsOn; + accessflags expFlagsOff; + ulong uFlags; + combinedboards mailCheckBoards; + ulong totalTimeUsed; + uint qwkMaxMsgsPerArea; + uint qwkMaxMsgs; + byte qwkArchiver; + byte ripFont; + byte checkMail; + byte checkNewFiles; + + byte extra[398]; + }; + +/* These are the extra user-flags for 'uFlags': */ + +#define RA_UFLAG_NOIBM 1 +#define RA_UFLAG_NOTOPS 2 +#define RA_UFLAG_AVTPLUS 4 +#define RA_UFLAG_ATTEN 8 +#define RA_UFLAG_NORIP 16 +#define RA_UFLAG_MULTILOGIN 32 +#define RA_UFLAG_FREECHAT 64 +#define RA_UFLAG_LOCALONLY 128 + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + CONFIG.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct Config + { + char shellmsg[81]; /* Message to show when shelling */ + char sysopname[36]; /* Name of sysop */ + char txtpath[61]; /* Path for textfiles */ + char mnupath[61]; /* Path for menu-files */ + char msgpath[61]; /* Path for message base */ + char uploadpath[61]; /* Uploadpath */ + char editorname[61]; /* Name of external editor */ + uint newuserlevel; /* Level for new user */ + short newuserloglevel; /* Loglevel for new user */ + accessflags newuserflags; /* New user flags */ + short max_passinput; /* Maximum attempts for password entry */ + short min_passlength; /* Minimum password length */ + short inactivity_time; /* Inactivity time-out limit */ + short max_sysop_pages; /* Maximum times sysop can be paged */ + short pagebell_length; /* Length of page-bell (secs) */ + short mailcheck; /* Check for mail at logon? */ + short europe; /* European date format? */ + short numnodes; /* # nodes */ + pb_bool allowansi; /* Allow ANSI? */ + pb_bool allowavatar; /* Allow AVATAR? */ + short discrete; /* Hide sysop activity? */ + short askphone; /* Ask for phone number? */ + short allowoneword; /* Allow one-word names */ + unsigned crashlevel; /* Level needed for crashmail */ + accessflags crashflags; /* Flags needed for crashmail */ + uint attachlevel; /* Level needed for file attach */ + accessflags attachflags; /* Flags needed for file attach */ + short allowmsgupload; /* Allow message uploads */ + short allowstacking; /* Allow command stacking */ + pb_Time page_start; /* Paging hours start */ + pb_Time page_end; /* Paging hours end */ + short handshaking; /* I/O Handshaking */ + short allowalias; /* Allow alias for login */ + short loglocal; /* Log local calls */ + short doswap; /* Allow swapping */ + char originline[61]; /* Origin line */ + char nodelistdir[61]; /* Nodelist directory */ + char sysopkeys[10][60]; /* Sysop hotkeys */ + pb_Time dl_start; /* Download hours start */ + pb_Time dl_end; /* Download hours end */ + short uploadspace; /* Space needed for uploads */ + char pvtuploadpath[61]; /* Directory for files uploads */ + char quotestring[6]; /* String used for quoting */ + pb_bool fastmode; /* Use fast mode */ + pb_bool extra_bool_1; + pb_bool killsent; /* Kill netmail after sent */ + pb_bool multiline; /* Use message base sharing? */ + pb_bool egamode; /* Use 43/50 line mode */ + pb_bool showuserinfo; /* Show user info while in EGA mode? */ + char pexpath[61]; /* Directory for PEX files */ + pb_bool allowquicklogin; /* Allow quick sysop login? */ + pb_bool suspendmsgtime; /* Suspend time when writing msgs */ + short securityboard; /* MsgBoard for security messages */ + pb_bool pwdmessages; /* Write security-messages? */ + pb_bool extra_bool_2; + char bbsname[36]; /* Name of the BBS */ + char pwdchar; /* Password character */ + short tb_maxtimedeposit; /* Max time deposit per day (TimeBank) */ + short tb_maxkbdeposit; /* Max Kbytes deposit per day (TimeBank) */ + short tb_maxtimewithdrawal; /* Max time withdrawal per day (TimeBank) */ + short tb_maxkbwithdrawal; /* Max Kbytes withdrawal per day (TimeBank) */ + short usage_days; /* Days to keep usage graphs */ + char systempwd[16]; /* System password */ + pb_bool usesystempwd; /* Use system password? */ + pb_bool askbirthdate; /* Ask Birth Date? */ + short binlogdays; /* # days to log in BINLOG.PB */ + pb_bool binloglocal; /* Log local calls to BINLOG.PB yes/no */ + short pageArea; /* Area number for page messages */ + pb_bool indexfiles; /* Use file indexing */ + pb_bool checkdupes; /* Check for dupes */ + pb_bool killdupes; /* Kill duplocate files */ + pb_bool ignore_ext; /* Ignore file extensions for dupe checking */ + + char RIPpath[61]; /* Path for RIP scripts */ + char iconspath[61]; /* Path for RIP icons */ + char location[36]; /* BBS Location (city) */ + char phone[26]; /* BBS Phone # */ + char QWKid[9]; /* BBS QWK id */ + uint IObuffersize; /* I/O buffer size in bytes */ + TimeFrame pagingHours; /* Paging hours */ + char defaultLanguage[9]; /* Default language */ + pb_bool addUploaderName; /* Add uploader's name to FILES.BBS */ + TimeFrame downloadHours; /* Download hours */ + pb_bool askdataphone; /* Ask data phone # */ + pb_bool askfaxphone; /* Ask fax phone # */ + pb_bool askaddress; /* Ask mailing address */ + pb_bool asksex; /* Ask sex */ + pb_bool askdateformat; /* Ask date format */ + pb_bool askstate; /* Ask state */ + pb_bool askcountry; /* Ask country */ + short fuzzyRate; /* Fuzzy search percentage for user editor */ + pb_bool hidePassword; /* Hide password in user editor */ + pb_bool valConfirm; /* Confirm user validation */ + + char extra[272]; + }; + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + TIMELOG.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct TimeLog + { + short numdays; /* Number of days active */ + Date lastdate; /* Last update */ + long hours[24]; /* # minutes per hour usage (obsolete) */ + long days[7]; /* # minutes per day usage (obsolete) */ + long weeks[53]; /* # minutes per week usage (obsolete) */ + long totalcalls; /* Total calls to system */ + }; + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + FILECFG.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct FileCfg + { + char name[80]; /* Name of file area */ + char listpath[80]; /* Path for file-list */ + char filepath[80]; /* Path for files */ + uint level; /* Level needed for access */ + long flags; /* Flags needed for access */ + char type; /* 1 = CDROM File listing type */ + short maxfiles; /* Max files per day in this area downloadable */ + short maxkb; /* Max Kbytes per day in this area */ + pb_bool notops; /* Set to 1 -> should not be listed in TOPFILES.A?? */ + pb_bool free; /* Set to 1 -> free area */ + byte groups[4]; /* Groups belonging to */ + pb_bool allGroups; /* Belongs to all groups */ + byte minAge; /* Minimum age */ + long flagsNot; /* Access flags not allowed */ + byte extra[3]; + }; + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + MSGAREAS.PB +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct MsgAreas + { + short areanum; /* # of message area (1-10000) */ + char name[31]; /* Name of message areas */ + byte msgtype; /* Type of messages */ + byte msgkind; /* Kind of message area */ + byte msgbasetype; /* 0 = hudson , 1 = squish , 2 = *.MSG */ + char path[80]; /* Path/Directory for Squish / *.MSG */ + byte flags; /* Alias allowed/forced/prohibited */ + uint readlevel; /* Minimum level needed to read msgs */ + accessflags readflags; /* flags needed to read msgs */ + uint writelevel; /* Minimum level needed to write msgs */ + accessflags writeflags; /* flags needed to write msgs */ + uint sysoplevel; /* Minimum level needed to change msgs */ + accessflags sysopflags; /* flags needed to change msgs */ + char origin[62]; /* Origin line */ + short aka; /* AKA */ + short rcv_kill_days; /* Kill received after xx days */ + short msg_kill_days; /* Kill after xx days */ + short max_msgs; /* Max # msgs */ + char sysop[36]; /* Area Sysop */ + short replyboard; /* Reply area # (0=here) */ + char echotag[21]; /* Echomail Tag Name */ + char qwktag[13]; /* QWK Area Name */ + byte groups[4]; /* Groups belonging to */ + pb_bool allGroups; /* Belongs to all groups */ + byte minAge; /* Minimum age for this area */ + long readFlagsNot; /* flags not allowed for reading */ + long writeFlagsNot; /* flags not allowed for writing */ + long sysopFlagsNot; /* flags not allowed for sysop access */ + + byte extra[5] ; + }; + +#define MSGTYPE_BOTH 0 /* Private/Public */ +#define MSGTYPE_PVT 1 /* Private Only */ +#define MSGTYPE_PUBLIC 2 /* Public Only */ +#define MSGTYPE_TOALL 3 /* To All */ + +#define MSGKIND_LOCAL 0 /* Local */ +#define MSGKIND_NET 1 /* NetMail */ +#define MSGKIND_ECHO 2 /* EchoMail */ +#define MSGKIND_PVTECHO 3 /* Pvt EchoMail */ + +#define MSGBASE_HUDSON 0 +#define MSGBASE_SQUISH 1 +#define MSGBASE_SDM 2 +#define MSGBASE_JAM 3 + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + ONLINE.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct Online + { + char name[36]; /* Name of user online */ + char city[16]; /* City of user online */ + short baud; /* Baud rate of user */ + short status; /* 0 -> online , <0 -> not online or unavailable */ + char extra[8]; + }; + + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + PROTOCOL.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct Protocol + { + char name[50]; /* Name of protocol */ + char key; /* Hotkey for Protocol */ + char flags; /* Protocol behavior */ + char logfile[60]; /* Logfile from protocol */ + char ctlfile[60]; /* Control file (redirection file) */ + char dlcom[128]; /* Download command line */ + char ulcom[128]; /* Upload command line */ + char dlstring[80]; /* String to place in download control file */ + char ulstring[80]; /* String to place in upload control file */ + char dlkeyword[40]; /* Download keyword to search for in logfile */ + char ulkeyword[40]; /* Upload keyword to search for in logfile */ + short wordnr; /* File name word nr after keyword (1-..) */ + }; + + +/* Flags: */ + +#define PROT_BATCH 1 /* Batch protocol */ +#define PROT_ENABLED 2 /* Enabled */ +#define PROT_BOTH 4 /* Full-duplex protocol */ +#define PROT_BIM 8 /* Bimodem-type ctl-file */ + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + LIMITS.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct Limits + { + uint level; /* Level */ + short timelimit; /* # minutes per day */ + short daily_klimit; /* Kbytes per day allowed */ + short pre_download; /* # minutes online before download */ + char id[6]; /* Usergroup ID */ + uint free; /* Free upload in Kb. */ + byte factor; /* Percentage upload required */ + uint max_download; /* Max download for this level */ + short fallto; /* Fall to level x when max. reached */ + short msgfactor; /* # Kbytes granted per message written */ + char extra[5]; + }; + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + MODEM.PRO +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct MODEM_PRO + { + unsigned baud; + short port; + short quiet; + short blanktime; + char initstring[70]; + char busystring[70]; + char initok[40]; + char busyok[40]; + char connect300[40]; + char connect1200[40]; + char connect2400[40]; + char connect4800[40]; + char connect9600[40]; + char connect19200[40]; + char connect38400[40]; + char ring[40]; + char answer[40]; + char connect7200[40]; + char connect12000[40]; + pb_bool forceanswer; + byte extra1[5]; + short delay; + char connect14400[40]; + char initstring2[70]; + char connect16800[40]; + char connect28800[40]; + char ext_connect1[40]; + char ext_connect2[40]; + short ext_errlevel1; + short ext_errlevel2; + char extra[36]; + }; + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + BINLOG.PB +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct BinLog + { + Date date; + pb_Time timeIn; + pb_Time timeOut; + char name[36]; + char city[26]; + char country[26]; + long baud; + uint node; + long kbDown; + long kbUp; + uint yells; + uint level; + ulong uflags; + char extra[81]; + }; + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + FILESIDX.PB +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct FilesIdx + { + char filename[13]; /* Name of the file, with extension */ + uint area; /* File area number where file is located */ + }; + + + +/* +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + FGROUPS.PB / MGROUPS.PB +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +*/ + +struct xGroups + { + char name[80]; + uint level; + long flags; + long flagsNot; + byte extra[10]; + }; + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_pcb.h b/goldlib/gcfg/gs_pcb.h new file mode 100644 index 0000000..f547dd0 --- /dev/null +++ b/goldlib/gcfg/gs_pcb.h @@ -0,0 +1,336 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard Structures. +// ------------------------------------------------------------------ + +#ifndef __GS_PCB_H +#define __GS_PCB_H + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// PCBoard Conference Information (CNAMES.@@@ file) + +struct PcbConf { + + char name[14]; // Conference name + byte publicconf; // New user default registration + byte autorejoin; // Auto-rejoin for this conference + byte viewmembers; // Allow viewing conference members + byte privuplds; // Make uploads private + byte privmsgs; // Make all messages private + byte echomail; // Is this an Echo-Mail conference + short reqseclevel; // Security required to join non-public conf. + short addsec; // Additional security level added after join + short addtime; // Additional time added after join + char msgblocks; // Number of message base index blocks + char msgfile[32]; // Name and location of messages file + char usermenu[32]; // Name and location of Users Menu + char sysopmenu[32]; // Name and location of Sysops Menu + char newsfile[32]; // Name and location of Conference News + char pubupldsort; // Sort type for public upload DIR file + char uplddir[29]; // Name and location of public upload DIR file + char pubupldloc[26]; // Public upload location + char prvupldsort; // Sort type for public upload DIR file + char privdir[29]; // Name and location of private upload DIR file + char prvupldloc[26]; // Private upload location + char drsmenu[29]; // Name and location of conference doors menu + char drsfile[33]; // Name and location of DOORS.LST file + char bltmenu[29]; // Name and location of conference blt menu + char bltnameloc[33]; // Name and location of BLT.LST file + char scrmenu[29]; // Name and location of conference scripts menu + char scrnameloc[33]; // Name and location of SCRIPT.LST + char dirmenu[29]; // Name and location of directories menu + char dirnameloc[33]; // Name and location of DIR.LST file + char pthnameloc[33]; // Name and location of DLPATH.LST file +}; + + +// ------------------------------------------------------------------ +// PCBoard Additional Conference Information (CNAMES.ADD file) + +struct PcbAddConf { + + byte forceecho; // Turn off echo question, force all msgs to echo + byte readonly; // Do not allow ANY msgs to be entered in conf + byte noprivatemsgs; // Do not allow PRIVATE msgs to be entered + char retreceiptlevel; // Level required to request return receipts + byte recordorigin; // Record ORIGIN in messages + byte promptforrouting; // Prompt user for ROUTING information + byte allowaliases; // Allow aliases to be used + byte showintroonra; // Show the Conf INTRO in the middle of R A scan + char reqleveltoenter; // Security Level required to enter messages + char password[13]; // Password reqd to join if private + char intro[32]; // Name/location of conference INTRO file + char attachloc[32]; // Location for file attachment storage + char regflags[4]; // RXS flags for automatic conf registration + char attachlevel; // Level required to attach a message + char carbonlimit; // Max number of names in carbon list + char cmdlst[32]; // Name/location of CMD.LST use instead of default + byte oldindex; // Maintain old MSGS indexes? + byte longtonames; // Allow long TO: names to be entered + char carbonlevel; // Level required to enter @LIST@ messages + char conftype; // One byte code for conference type + long exportptr; // A pointer to the last message number exported + long chargetime; // Amount to charge for time spent in conference + long chargemsgread; // Amount to charge for each message read + long chargemsgwrite; // Amount to charge for each message written + char reserved[64]; // Reserved for future growth + char name2[48]; // Conf name #2 +}; + + +// ------------------------------------------------------------------ +// Conference types in CNAMES.ADD + +const char PCBCONFTYPE_NORMAL = 0; // Normal PCBoard Conference +const char PCBCONFTYPE_EMAIL = 1; // Internet Email (Import & Export) +const char PCBCONFTYPE_USENETJUNK = 2; // Internet/Usenet Junk (Import Only) +const char PCBCONFTYPE_USENETMOD = 3; // Usenet Moderated Newsgroup (Export Public as Email to Moderator / Private as Email to TO:) +const char PCBCONFTYPE_USENETPUB = 4; // Usenet Public Newsgroup (Export Public as Articles / Private as Email to TO:) +const char PCBCONFTYPE_FIDOCONF = 5; // Fido Conference + + +// ------------------------------------------------------------------ + +struct PcbFidoArea { + + word pcbconference; // PCBoard conference number + char areaname[60]; // FIDO area tag + char messages[66]; // Path to conference message file + char defaultaka[25]; // Aka for conference + char origin[70]; // Origin for conference + char highascii; // S R C N + char reserved[19]; // Reserved space +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoArchivers { + + char archivers[4][66]; // Stores the name of the archiver executable + char archiver_switches[4][80]; // Stores the name of the archiver switches + char unarchivers[4][66]; // Stores the name of the unarchiver executable + char unarchiver_switches[4][80]; // Stores the name of the unarchiver switches +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoDirectories { + + char incoming_packets[66]; // Incoming directory + char outgoing_packets[66]; // outbound directory + char outgoing_msg[66]; // *.MSG directory + char bad_packets[66]; // BAD directory + char nodelist_path[66]; // nodelist directory + char work_directory[66]; // work directory +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoEmsiData { + + char BBS_Name[60]; // BBS name + char City[30]; // City + char Sysop[30]; // Sysop's name + char Phone[50]; // BBS phone number + char Baud[10]; // MAX baud + char Flags[50]; // Fido FLAGS +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoAddress { + + char nodestr[25]; // Full fido address in the form Z:N/N.P + word this_zone; // FIDO zone + word this_net; // FIDO net + word this_node; // FIDO node + word this_point; // FIDO point + char reserved[10]; // Reserved space +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoNode { + + char nodestr[25]; // Full fido address in the form Z:N/N.P + word zone; // FIDO zone + word net; // FIDO net + word node; // FIDO node + word point; // FIDO point + word pkt_type; // FIDO packet type 1=stoneage 2=2+ + short archiver_index; // index to archiver 0=ZIP,1=ARJ,2=ARC,3=LZH + char reserved[10]; // Reserved space +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoTranslate { + + char in[30]; // What to traslate + char out[30]; // What to translate to + char reserved[10]; // reserved space +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoNodelist { + + char basename[80]; // Nodelist name (no extension) + char diffname[9]; // Diff file name (no extension) + short last_compile; // Last compiled version number + char reserved[10]; // reserved space +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoFreqPath { + + char str[60]; // fully qualified path to FREQ files + char reserved[20]; // reserved space. +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoFreqInfo { + + word stime; // Session max time + word dtime; // Daily max time + long sbytes; // Session bytes + long dbytes; // Daily Bytes + char listed; // Allowed Nodes + word baud; // Minimum allowed baud +}; + + +// ------------------------------------------------------------------ + +struct PcbFidoFreqMagic { + + char magic_name[20]; // Magic name + char real_name[50]; // Associated file name +}; + + +// ------------------------------------------------------------------ + +struct PcbDirectories { + char incoming_packets[66]; // Incoming directory + char outgoing_packets[66]; // Outbound directory + char outgoing_msg[66]; // *.MSG directory + char bad_packets[66]; // BAD directory + char nodelist_path[66]; // Nodelist directory + char work_directory[66]; // Work directory + char passthrough[66]; // Passthru files + char securemail[66]; // Secure netmail + char messages[66]; // response Messages +}; + + +// ------------------------------------------------------------------ + +struct PcbArchivers { + char archivers[4][66]; // Stores the name of the archiver executable + char archiver_switches[4][80]; // Stores the name of the archiver switches + char unarchivers[4][66]; // Stores the name of the unarchiver executable + char unarchiver_switches[4][80]; // Stores the name of the unarchiver switches +}; + + +// ------------------------------------------------------------------ + +struct PcbEmsiData { + char bbs_name[60]; // BBS name + char city[30]; // City + char sysop[30]; // Sysop's name + char phone[50]; // BBS phone number + char baud[10]; // MAX baud + char flags[50]; // Fido FLAGS +}; + + +// ------------------------------------------------------------------ + +struct PcbAreasDat { + word confno; + char areatag[60]; + word aka; + word origin; + char high_ascii; + word last_activity; + char allow_private; + char allow_attach; + byte reserved[10]; +}; + + +// ------------------------------------------------------------------ + +struct PcbAkasDat { + ftn_addr addr; + char primary_address; + char in_seenby; + char present_in_handshake; + char up_downlink; + char conf_range[70]; + char reserved[10]; +}; + + +// ------------------------------------------------------------------ + +struct PcbOriginsDat { + char origin[70]; + char conf_range[70]; + char reserved[10]; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gs_pop.h b/goldlib/gcfg/gs_pop.h new file mode 100644 index 0000000..47b9e1f --- /dev/null +++ b/goldlib/gcfg/gs_pop.h @@ -0,0 +1,478 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Portal of Power configuration structures. +// ------------------------------------------------------------------ + +#ifndef __GS_POP_H +#define __GS_POP_H + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// Pascal types + +typedef unsigned char Boolean; +typedef char Char; +typedef unsigned char Byte; +typedef short Integer; +typedef unsigned short Word; +typedef long LongInt; + + +// ------------------------------------------------------------------ +// Misc. types + +typedef LongInt PopDate; +typedef LongInt PopTime; +typedef Byte ColorSet[62]; +typedef Char PathStr[80]; + +// All string types, very handy! +typedef char + S1[2], S2[3], S3[4], S4[5], S5[6], + S6[7], S7[8], S8[9], S9[10], S10[11], + S11[12], S12[13], S13[14], S14[15], S15[16], + S16[17], S17[18], S18[19], S19[20], S20[21], + S21[22], S22[23], S23[24], S24[25], S25[26], + S26[27], S27[28], S28[29], S29[30], S30[31], + S31[32], S32[33], S33[34], S34[35], S35[36], + S36[37], S37[38], S38[39], S39[40], S40[41], + S41[42], S42[43], S43[44], S44[45], S45[46], + S46[47], S47[48], S48[49], S49[50], S50[51], + S51[52], S52[53], S53[54], S54[55], S55[56], + S56[57], S57[58], S58[59], S59[60], S60[61], + S61[62], S62[63], S63[64], S64[65], S65[66], + S66[67], S67[68], S68[69], S69[70], S70[71], + S71[72], S72[73], S73[74], S74[75], S75[76], + S76[77], S77[78], S78[79], S79[80], S80[81], + S81[82], S82[83], S83[84], S84[85], S85[86], + S86[87], S87[88], S88[89], S89[90], S90[91], + S91[92], S92[93], S93[94], S94[95], S95[96], + S96[97], S97[98], S98[99], S99[100], S100[101], + S101[102], S102[103], S103[104], S104[105], S105[106], + S106[107], S107[108], S108[109], S109[110], S110[111], + S111[112], S112[113], S113[114], S114[115], S115[116], + S116[117], S117[118], S118[119], S119[120], S120[121], + S121[122], S122[123], S123[124], S124[125], S125[126], + S126[127], S127[128], S128[129], S129[130], S130[131], + S131[132], S132[133], S133[134], S134[135], S135[136], + S136[137], S137[138], S138[139], S139[140], S140[141], + S141[142], S142[143], S143[144], S144[145], S145[146], + S146[147], S147[148], S148[149], S149[150], S150[151], + S151[152], S152[153], S153[154], S154[155], S155[156], + S156[157], S157[158], S158[159], S159[160], S160[161], + S161[162], S162[163], S163[164], S164[165], S165[166], + S166[167], S167[168], S168[169], S169[170], S170[171], + S171[172], S172[173], S173[174], S174[175], S175[176], + S176[177], S177[178], S178[179], S179[180], S180[181], + S181[182], S182[183], S183[184], S184[185], S185[186], + S186[187], S187[188], S188[189], S189[190], S190[191], + S191[192], S192[193], S193[194], S194[195], S195[196], + S196[197], S197[198], S198[199], S199[200], S200[201], + S201[202], S202[203], S203[204], S204[205], S205[206], + S206[207], S207[208], S208[209], S209[210], S210[211], + S211[212], S212[213], S213[214], S214[215], S215[216], + S216[217], S217[218], S218[219], S219[220], S220[221], + S221[222], S222[223], S223[224], S224[225], S225[226], + S226[227], S227[228], S228[229], S229[230], S230[231], + S231[232], S232[233], S233[234], S234[235], S235[236], + S236[237], S237[238], S238[239], S239[240], S240[241], + S241[242], S242[243], S243[244], S244[245], S245[246], + S246[247], S247[248], S248[249], S249[250], S250[251], + S251[252], S252[253], S253[254], S254[255], S255[256]; + +// Nodelist Types supported +typedef Byte NodeListType; +enum NodeListTypes { + NewNodelistType, + QBBSNodelistType, + RANodelistType, + Version7, + SBBSNodeListType +}; + + +// A 4D FidoNet address +struct AddressType { + Integer Zone, + Net, + Node, + Point; +}; + +typedef S50 SendToType[2]; + +struct FunctionKeyType { + Byte ErrorLevel; + S70 Description; +}; + +#define MaxAddresses 16 + + +// ------------------------------------------------------------------ +// Contents : Configuration information. +// FileName : PORTAL.CFG +// Size : 10240 bytes +// Comments : + +enum NodeStatsT { nsUnknown, nsKnown, nsPassword }; +enum ReqLimitsT { rlPrCall, rlPrDay }; + +#define NodeStatT 3 +#define ReqLimitT 2 + +typedef struct ConfigT *ConfigP; + +struct ConfigT { + Byte Version; + Byte TaskNumber; + PathStr SwapDir, + Inbound, + Outbound, + Banner, + DefaultMacro, + Editor, + LogfileName; + Byte LogLevel; + Boolean UseYearInLog; + + PathStr NodeList; + NodeListType NodelistTyp; + + Byte MainAdrNum; + AddressType Adresses[MaxAddresses]; + + Integer PointNet; + Boolean UseFakeAddress; + + S20 Sysop; + S60 System; + + Boolean SwapOnExec; + + PathStr EnterBBSText, + + DoingMailText, + + PressESCText; + + Byte MaxRinging; + PopTime ZMHStart, + ZMHEnd, + CallTime, + CallWidth; + Boolean ConnectFastest; + + PopTime OutReReadDelay; + + S20 FuncReqPwd; + Boolean UseJanus; + Boolean UseEMSI; + Boolean FastCalls; + Boolean KeepEmptyDirs; + + Byte Filler[272]; + + FunctionKeyType FKey[2][10]; + ColorSet Color[4]; + + struct { + Byte BBSType; + PathStr BBSPath; + PathStr UserFile; + Word MinBaud; + PathStr MinBaudFile; + Byte UserErrorLevel; + struct { + Char Key; + S8 BatName; + } Multi[5]; + Byte Filler[64]; + } BBS; + + struct { + Byte CommPort; + Word BaudRate; + S40 PreInit, + Init, + NoAnswer, + Dial, + Busy, + HangUp, + Answer; + PopTime ReInit; + + S10 LockedBaud; + + + struct { + S10 ConStr; + Byte ErrLvl; + } ExitStr[5]; + struct { + Byte Bit; + S40 Dial; + Boolean DialOut; + Word Baud; + } ModemType[8]; + Byte Filler[64]; + } Modem; + + struct { + PopTime BlankTime; + Boolean ChkSnow, + KeepOffScrMode, + ScrMode, + HardwareBlank, + ExplodingWin; + Byte Filler[32]; + } Screen; + + struct { + PathStr FileList, + NewsList, + Header, + Footer, + TopFile, + StatFile; + Boolean Adopt; + S40 AdoptComment; + Boolean DupeCheck; + Boolean Stat; + Boolean IncludeTop; + Byte Top; + + Boolean DkDate; + Byte NewsDays; + + Byte Threshold; + Boolean RemMissing, + OkPortal, + ZapZero, + Touch; + S12 CrapFiles[10], + ExcludeFiles[10], + NoDupeCheck[10]; + S12 NonAdoptFiles[10]; + S3 NonAdoptAreas[10]; + S3 PrivateAreas[11]; + PathStr DoBefore; + PathStr DoAfter; + PathStr DoPack; + PathStr DupeReport; + S55 TXTFreq[4]; + PathStr OkBimodempath; + Byte Filler[32]; + } ListFiles; + + struct { + struct { + Word MaxFiles; + PopTime MaxTime; + LongInt MaxBytes; + } Limit[NodeStatT][ReqLimitT]; + Boolean RspAsPkt; + Boolean SkipAfterFirst; + + + Byte Filler[63]; + } Request; + + struct { + S50 AddToSeenBy; + Boolean CheckZones; + PathStr NetMailDir; + PathStr Filler3; + Boolean Secure; + PathStr BadMsgs; + PathStr SaveDupesDir; + Word MaxDupes; + PathStr EchoTossLog; + Boolean StripCrash; + Boolean SetAKASent; + Boolean PvtEchoMail; + Boolean SaveFwdMail; + PathStr RouteFile; + Boolean ForwardMail; + Boolean KillFwdFiles; + PathStr Filler2; + Boolean OldExt; + Byte DefaultPacker; + Byte NetMailBoard; + Byte Filler[128]; + } MailScanner; + + struct { + PathStr PreCmd; + PathStr SecureDir; + Word MsgAttribute; + Boolean KillSent; + Boolean MsgPrivate; + S72 Subject; + Byte Filler[64]; + } FwdFile; + + struct { + PathStr DupeDir; + PathStr HoldDir; + PathStr BeforeMoving; + + Boolean RequestMissing; + + Byte Filler[64]; + } Tick; + + struct { + S10 BiOverride[5]; + + + Boolean NoSendOverride; + + + + Word MaxBaud; + + PathStr BiModemPath; + + Byte Filler[16]; + } BiMail; + + struct { + PathStr CostFileName; + S10 IntPrefix; + S10 OurPrefix; + + Boolean UseFidoUserLst; + S5 MTypeStr[8]; + Byte Filler[64]; + } NLCompiler; + + struct { + Boolean CRSendsLF, + DestructiveBS; + S40 ModemInit; + Byte Filler[128]; + } DumbTerm; + + struct { + Char Key; + S8 Name; + Boolean AskDLName; + S10 AutoStart; + PathStr SendCmd; + PathStr RecvCmd; + } ExtProt[5]; + + struct { + Char DLCntStart, + + + DLCntStop; + + + Boolean AdoptDefault, + InsDLCnt, + AddInbound; + Byte FirstArea, + LastArea; + Byte DlCDigits; + Boolean DlCZeroFill; + S50 ViewCMD; + Byte Filler[11]; + } AreaMan; + + struct { + S40 AddCmd, + UnPackCmd, + EraseCmd, + TestCmd; + } Packer[7]; +}; + + +// ------------------------------------------------------------------ +// Contents : Message Areas +// FileName : PORTAL.ARE +// Size : 1024 +// Comments : **NOT USED YET** + +typedef struct AreasTypeT *AreasTypeP; +struct AreasTypeT { + PathStr Directory; + S32 EchoNames[3]; + S50 Origin; + SendToType SendTo; + SendToType SendOnly; + S20 ScramblePwd; + Boolean StripSeenBy; + Boolean Pvt2EMail; + Byte Level, + Keys; + Word MaxScan; + PopDate ScanDate; + Word Scanned; + S40 Description; + Byte AreaType; + Boolean ImportSB; + Byte UsedAka; // 0 = Address[Config.MainAdrNum], otherwise Address[UsedAka] + Byte Filler[513]; +}; + + +// ------------------------------------------------------------------ +// Contents : Nodelist Segments - for Nodelist Compiler +// FileName : PORTAL.NLS +// Size : 512 bytes +// Comments : One record per used nodelist. Shared among all tasks + +typedef struct NodelistSegT *NodelistSegP; +struct NodelistSegT { + S8 NodeListName; + S8 DiffFileName; + Boolean CheckCRC; + PathStr NewNLPath; + SendToType Include; + SendToType Exclude; + Byte Filler[209]; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gs_qbbs.h b/goldlib/gcfg/gs_qbbs.h new file mode 100644 index 0000000..fc2c6c9 --- /dev/null +++ b/goldlib/gcfg/gs_qbbs.h @@ -0,0 +1,416 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// QuickBBS (old and new) configuration data structures +// ------------------------------------------------------------------ + +#ifndef __GS_QBBS_H +#define __GS_QBBS_H + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// QuickBBS 2.60, CONFIG.BBS structure + +typedef struct { + byte Status; // 0=Disabled 1=Enabled + char RunTime[6]; + byte ErrorLevel; + byte Days; + byte Forced; + char LastTimeRun[9]; +} Q260EvtRecT, *Q260EvtRecP, **EvtRecI; + +typedef struct { + char Name[17]; + byte Typ; // 0=Standard 1=Net 3=Echo + byte Kinds; // 0=Private & Public 1=Private 2=Public 3=Read-Only + byte Combined; + byte Aliases; // 0=no aliases,1=yes,2=ask alias,3=Alias/name + short ReadSecLvl; + byte ReadFlags[4]; + short WriteSecLvl; + byte WriteFlags[4]; + short SysopSecLvl; + byte SysopFlags[4]; +} Q260BrdRecT, *Q260BrdRecP, **Q260BrdRecI; + +typedef struct { + short CommPort; + word InitBaud; + word InitTimes; + word AnswerWait; + char ModemInitStr[71]; + char ModemBusyStr[71]; + char ModemInitResp[41]; + char ModemBusyResp[41]; + char Resp300[41]; + char Resp1200[41]; + char Resp2400[41]; + char MenuPath[67]; + char TextPath[67]; + char NetPath[67]; + short MinBaud; + short GraphicsBaud; + short XferBaud; + char LowBaudStart[6]; + char LowBaudEnd[6]; + char DownloadStart[6]; + char DownloadEnd[6]; + char PagingStart[6]; + char PagingEnd[6]; + short MatrixZone; + short MatrixNet; + short MatrixNode; + short AkaNet[5]; + short AkaNode[5]; + short NetMailBoard; + short DefaultSec; + short DefaultCredit; + byte DefaultFlags[4]; + char EditorCmdStr[71]; + char OriginLine[61]; + char SysopName[36]; + byte AutoLogonChar; + byte FastLogon; + byte ScreenBlanking; + byte UseLastRead; + byte MonoMode; + byte DirectWrite; + byte SnowCheck; + byte NetEchoExit; + byte OneWordNames; + byte CheckMail; + byte AskHomePhone; + byte AskDataPhone; + byte GraphicsAvail; + short InactiveTimeOut; + short LogonTime; + short DefFgColor; + short DefBgColor; + short PasswordTries; + short MaxPageTimes; + short PageBellLen; + byte Use_Xmodem; + byte Use_Xmodem1k; + byte Use_Ymodem; + byte Use_YmodemG; + byte Use_Sealink; + byte Use_Zmodem; + byte Inp_Fields; + char QuoteStr[4]; + short UploadCredit; + char LoadingMessage[71]; + char SelectionPrompt[71]; + word VersionID; + char Resp4800[41]; + char Resp9600[41]; + short AkaZone[5]; + short MatrixPoint; + short AkaPoint[5]; + byte UseAka[200]; + byte Spare[51]; + Q260EvtRecT Events[30]; + Q260BrdRecT Boards[200]; +} Q260CfgRecT, *Q260CfgRecP; + + +// ------------------------------------------------------------------ +// QuickBBS 2.76.G2, USERS.BBS structure + +typedef struct { + char Name[36]; + char City[26]; + char Pwd[16]; + char DataPhone[13]; + char HomePhone[13]; + char LastTime[6]; + char LastDate[9]; + byte Attrib; + byte Flagsx[4]; + word Credit; + word Pending; + word TimesPosted; + word HighMsgRead; + word SecLvl; + word Times; + word Ups; + word Downs; + word UpK; + word DownK; + short TodayK; + short Elapsed; + short Len; + word CombinedPtr; // Record number in COMBINED.BBS + word AliasPtr; // Record number in ALIAS.BBS + long Birthday; +} Q276UsrRecT, *Q276UsrRecP, **Q276UsrRecI; + +// Attrib: +// +// Bit 0: Deleted +// Bit 1: Screen Clear Codes +// Bit 2: More Prompt +// Bit 3: ANSI +// Bit 4: No-Kill +// Bit 5: Ignore Download Hours +// Bit 6: ANSI Full Screen Editor +// Bit 7: Sex (0=male, 1=female) + + +// ------------------------------------------------------------------ +// QuickBBS 2.76.G2, MSGCFG.DAT structure + +typedef struct { + word Security; + byte Flagsx[4]; +} Q276SecRecT; + +typedef struct { + char Name[41]; + byte Typ; + byte Kinds; + byte Combined; + byte Aliases; + byte Aka; + char OriginLine[59]; + byte AllowDelete; + word KeepCnt; + word KillRcvd; + word KillOld; + Q276SecRecT ReadSec; + Q276SecRecT WriteSec; + Q276SecRecT TemplateSec; + Q276SecRecT SysopSec; + short FileArea; + byte Group; + byte Spare[9]; +} Q276BrdRecT, *Q276BrdRecP, **Q276BrdRecI; + + +// ------------------------------------------------------------------ +// QuickBBS 2.76.G2, QUICKCFG.DAT structure + +typedef struct { + char TranslateFrom[26]; + word TranslateTo; +} Q276MdmXltRecT; + +typedef struct { + word VersionID; + byte Node; + short CommPort; // Modem Parameters + word InitBaud; + word ModemDelay; + short InitTimes; + short AnswerWait; + char ModemInitStr[71]; + char ModemBusyStr[71]; + char ModemInitResp[41]; + char ModemBusyResp[41]; + Q276MdmXltRecT ModemConnectResp[8]; + word CBV_CallbackDelay; + word CBV_WakeupDelay; + char ARQ_String[9]; + byte ModemSpareInfo[9]; + char EditorCmdStr[71]; // System Paths + char MenuPath[67]; + char TextPath[67]; + char NetPath[67]; + char NodelistPath[67]; + char MsgPath[67]; + char SwapPath[67]; + char OverlayPath[67]; + char LoadingMessage[71]; // System misc strings + char SelectionPrompt[71]; + char NoMailString[71]; + char OriginLine[59]; + char QuoteStr[4]; + long LowBaudStart; // User Restrictions + long LowBaudEnd; + long DownloadStart; + long DownloadEnd; + short MaxPageTimes; + short PageBellLen; + long PageStart; + long PageEnd; + short MinBaud; + short GraphicsBaud; + short XferBaud; + short MatrixZone[11]; // Matrix Information + short MatrixNet[11]; + short MatrixNode[11]; + short MatrixPoint[11]; + short NetMailBoard; + Q276SecRecT DefaultSec; // Default Information for New Users + Q276SecRecT MinimumSec; + short DefaultCredit; + Q276SecRecT SysopSecurity; // Sysop Security Etc. + char SysopName[36]; + char SystemName[41]; + long RegKey; + byte TextFileShells; // Misc System Parameters + byte AltJswap; + byte Editorswap; + byte AutoLogonChar; + byte FastLogon; + byte UseLastRead; + byte MonoMode; + byte DirectWrite; + byte SnowCheck; + byte NetEchoExit; + byte OneWordNames; + byte CheckMail; + byte AskHomePhone; + byte AskDataPhone; + byte AskBirthday; + byte AskSex; + byte Use_Xmodem; + byte Use_Xmodem1k; + byte Use_Ymodem; + byte Use_YmodemG; + byte Use_Kermit; + byte Use_Zmodem; + byte Inp_Fields; + byte GraphicsAvail; + byte ForceUS_Phone; + short InactiveTimeOut; + short LogonTime; + short DefFgColor; + short DefBgColor; + short PasswordTries; + byte EntFldColor; + byte BorderColor; + byte WindowColor; + byte StatusBarColor; + short UploadCredit; + byte ScreenBlank; + char VerifierInit[36]; // Callback verifier + char DialString[16]; + char DialSuffix[16]; + byte DupeCheck; + word NewUserSec; + word MemberSec; + char MemberFlags[4][8]; + word LDcost; + byte LDenable; + byte ResumeLocal; + byte ResumeLD; + long LDstart; + long LDend; + byte ForgotPwdBoard; + byte SendATA; + char Location[61]; + byte ArchiveNetMail; + byte IEMSI; + byte IEMSI_New; + byte AutoAnsi; + byte MultiNode; + byte ExtraSpace[332]; +} Q276CfgRecT, *Q276CfgRecP; + + +// ------------------------------------------------------------------ +// RemoteAccess 2.00 GAMMA, USERS.BBS structure + +// Some Pascal types +typedef char Char; +typedef unsigned char Byte; +typedef unsigned short Word; +typedef signed short Integer; +typedef signed long LongInt; +typedef Byte FlagType[4]; +typedef Char Time[6]; +typedef Char Date[9]; + +typedef struct { + + char name[36]; + char location[26]; + char organisation[51]; + char address1[51]; + char address2[51]; + char address3[51]; + char handle[36]; + char comment[81]; + long passwordcrc; + char dataphone[16]; + char voicephone[16]; + char lasttime[6]; + char lastdate[9]; + byte attribute; + byte attribute2; + byte flagsx[4]; + long credit; + long pending; + word msgsposted; + word security; + long lastread; + long nocalls; + long uploads; + long downloads; + long uploadsk; + long downloadsk; + long todayk; + short elapsed; + word screenlength; + byte lastpwdchange; + word group; + word combinedinfo[200]; + char firstdate[9]; + char birthdate[9]; + char subdate[9]; + byte screenwidth; + byte language; + byte dateformat; + char forwardto[36]; + word msgarea; + word filearea; + char defaultprotocol; + word filegroup; + byte lastdobcheck; + byte sex; + long xirecord; + word msggroup; + byte freespace[48]; + +} RA2UsrRecT, *RA2UsrRecP, **RA2UsrRecI; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gs_qfrnt.h b/goldlib/gcfg/gs_qfrnt.h new file mode 100644 index 0000000..ed515b3 --- /dev/null +++ b/goldlib/gcfg/gs_qfrnt.h @@ -0,0 +1,118 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// QFront 1.13. +// ------------------------------------------------------------------ + +#ifndef __GS_QFRNT_H +#define __GS_QFRNT_H + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// Typedefs + +typedef unsigned char _boolean; +typedef unsigned char byte; +typedef unsigned short word; + + +// ------------------------------------------------------------------ +// Constants + +const int MaxOrigins = 35; + + +// ------------------------------------------------------------------ +// File : QORIGIN.DAT +// Stores : Information about each of your origin lines. +// + +struct OriginLineRecord { + + char OriginLine[MaxOrigins][61]; + byte Extra[50]; +}; + + +// ------------------------------------------------------------------ +// File : QECHOS.DAT +// Stores : Information about each EchoMail area you have configured in your +// Area Manager. +// Notes : This is VERY IMPORTANT. Each EchoMail area has an associated +// "tag". The tag MUST be unique among ALL EchoMain areas, and the +// tag must be between 1 and MaxConferences. QFront uses the tag +// as a bit number in the SelectedConfs field in the +// EchoMailAssignmentRecord record to know which areas each node has +// selected. Failure to set the tag properly will result in +// duplicate selected conferences for all of your nodes. You must +// not add any more than MaxConferences records to this file. +// + +struct EchoMailConferenceRecord { + + _boolean PassThru; + + word ConfNum; + word ConfTag; + char AreaName[81]; + + long HighMsgPointer; + + word AreaLevel; + + _boolean CheckForDupes; + _boolean ImportSeenByLines; + _boolean ImportPathLines; + _boolean KeepPrivate; + + _boolean Deleted; + + byte OriginLine; + byte Group; + + _boolean ScanPrivate; + _boolean Mandatory; + _boolean ForcePrivate; + + byte Extra[45]; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gs_qwk.h b/goldlib/gcfg/gs_qwk.h new file mode 100644 index 0000000..cdbbe04 --- /dev/null +++ b/goldlib/gcfg/gs_qwk.h @@ -0,0 +1,54 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ + +struct QWKHdr { + byte status; + char msgno[7]; + char date[8]; + char time[5]; + char to[25]; + char from[25]; + char subject[25]; + char password[12]; + char refno[8]; + char blocks[6]; + byte activestatus; + word confno; + word pktmsgno; + char tagline; +}; + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_ra.h b/goldlib/gcfg/gs_ra.h new file mode 100644 index 0000000..802239b --- /dev/null +++ b/goldlib/gcfg/gs_ra.h @@ -0,0 +1,188 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// RemoteAccess configuration data structures. +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// RA Address structure + +typedef struct { + word zone; + word net; + word node; + word point; +} _raaddr; + + +// ------------------------------------------------------------------ +// RA Area info structure + +typedef struct { + char name[41]; // 000 + char type; // 041 + byte msgkinds; // 042 + byte attribute; // 043 + byte dayskill; // 044 + byte recvkill; // 045 + word countkill; // 046 + word readsecurity; // 048 + byte readflags[4]; // 050 + word writesecurity; // 054 + byte writeflags[4]; // 056 + word sysopsecurity; // 060 + byte sysopflags[4]; // 062 + char originline[61]; // 066 + byte akaaddress; // 127 +} _messagesra; // 128 Bytes + + +// ------------------------------------------------------------------ +// RA Configuration structure + +typedef struct { + word versionid; + byte commport; + long baud; + byte inittries; + char initstr[71], + busystr[71]; + char initresp[41], + busyresp[41], + connect300[41], + connect1200[41], + connect2400[41], + connect4800[41], + connect9600[41], + connect19k[41], + connect38k[41]; + byte answerphone; + char ring[21], + answerstr[21]; + byte flushbuffer; + short modemdelay; + short minimumbaud, + graphicsbaud, + transferbaud; + char slowbaudtimestart[6], + slowbaudtimeend[6], + downloadtimestart[6], + downloadtimeend[6], + pagingtimestart[6], + pagingtimeend[6]; + char loadingmsg[71], + listprompt[71]; + short pwdexpiry; + char menupath[61], + textpath[61], + netpath[61], + nodelistpath[61], + msgbasepath[61], + syspath[61], + externaledcmd[61]; + _raaddr address[10]; + char systemname[31]; + short newsecurity; + short newcredit; + byte newflags[4]; + char originline[61]; + char quotestring[16]; + char sysop[36]; + char logfilename[61]; + byte fastlogon, + allowsysrem, + monomode, + strictpwdchecking, + directwrite, + snowcheck; + short creditfactor; + short usertimeout, + logontime, + passwordtries, + maxpage, + pagelength; + byte checkformultilogon, + excludesysopfromlist, + onewordnames; + char checkmail; + byte askvoicephone, + askdataphone, + dofullmailcheck, + allowfileshells, + fixuploaddates, + showfiledates; + short ansi, + clearscreen, + moreprompt, + uploadmsgs, + killsent; + short crashasksec; + byte crashaskflags[4]; + short crashsec; + byte crashflags[4]; + short fattachsec; + byte fattachflags[4], + normfore, + normback, + statfore, + statback, + hiback, + hifore, + windfore, + windback, + exitlocal, + exit300, + exit1200, + exit2400, + exit4800, + exit9600, + exit19k, + exit38k; + byte multiline; + byte minpwdlen; + word minupspace; + char hotkeys; + byte borderfore, + borderback, + barfore, + barback, + logstyle, + multitasker, + pwdboard; + word buffersize; + char fkeys[10][61]; + byte futureexpansion[1024]; +} _configra; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_ra2.h b/goldlib/gcfg/gs_ra2.h new file mode 100644 index 0000000..6ac3332 --- /dev/null +++ b/goldlib/gcfg/gs_ra2.h @@ -0,0 +1,498 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// RemoteAccess 2.xx configuration data structures. +// ------------------------------------------------------------------ + +#ifndef __GS_RA2_H +#define __GS_RA2_H + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// +// C++ structures for RemoteAccess 2.00 GAMMA. +// +// Based on the document STRUCT.200 which is (C) Copyright Andrew +// Milner & Continental Software, 1993. All rights reserved. +// +// ------------------------------------------------------------------ + +typedef unsigned char Boolean; +typedef char Char; +typedef unsigned char Byte; +typedef unsigned short Word; +typedef signed short Integer; +typedef signed long LongInt; + +typedef Byte FlagType[4]; +typedef Char ra_Time[6]; +typedef Char Date[9]; +typedef Char LongDate[10]; +typedef Byte ByteArray32[32]; + +typedef Byte AskType; +typedef Byte VideoType; +typedef Byte MsgType; +typedef Byte MsgKindsType; +typedef Byte OrphanType; + +enum _AskType { Yes, No, Ask, Only }; +enum _VideoType { Auto, Short, Long }; +enum _MsgType { LocalMail, NetMail, EchoMail }; +enum _MsgKindsType { Both, Private, Public, ROnly, NoReply }; +enum _OrphanType { Ignore, Create, Kill }; + +struct NetAddress { + Word Zone, + Net, + Node, + Point; +}; + +typedef Char MSGTOIDXrecord[36]; + +struct USERSIDXrecord { + LongInt NameCRC32, + HandleCRC32; +}; + +typedef Word COMBINEDrecord[200]; + +struct USERSrecord { + MSGTOIDXrecord Name; + Char Location[26]; + Char Organisation[51]; + Char Address1[51]; + Char Address2[51]; + Char Address3[51]; + Char Handle[36]; + Char Comment[81]; + LongInt PasswordCRC; + Char DataPhone[16]; + Char VoicePhone[16]; + ra_Time LastTime; + Date LastDate; + + Byte Attribute, + + /* Bit 0 : Deleted + 1 : Clear screen + 2 : More prompt + 3 : ANSI + 4 : No-kill + 5 : Xfer priority + 6 : Full screen msg editor + 7 : Quiet mode */ + + Attribute2; + + /* Bit 0 : Hot-keys + 1 : AVT/0 + 2 : Full screen message viewer + 3 : Hidden from userlist + 4 : Page priority + 5 : No echomail in mailbox scan + 6 : Guest account + 7 : Post bill enabled */ + + FlagType Flagsx; + LongInt Credit, + Pending; + Word MsgsPosted, + Security; + LongInt LastRead, + NoCalls, + Uploads, + Downloads, + UploadsK, + DownloadsK, + TodayK; + Integer Elapsed; + Word ScreenLength; + Byte LastPwdChange; + Word Group; + COMBINEDrecord CombinedInfo; + Date FirstDate, + BirthDate, + SubDate; + Byte ScreenWidth, + Language, + DateFormat; + Char ForwardTo[36]; + Word MsgArea, + FileArea; + Char DefaultProtocol; + Word FileGroup; + Byte LastDOBCheck; + Byte Sex; + LongInt XIrecord; + Word MsgGroup; + Byte FreeSpace[48]; +}; + +struct USERSXIrecord { + Byte FreeSpace[200]; +}; + +struct MESSAGErecord { + Word AreaNum; // NEW in 2.50 + Word Unused; + Char Name[41]; + MsgType Typ; + MsgKindsType MsgKinds; + Byte Attribute; + + /* Bit 0 : Enable EchoInfo + 1 : Combined access + 2 : File attaches + 3 : Allow aliases + 4 : Use SoftCRs as Characters + 5 : Force handle + 6 : Allow deletes + 7 : Is a JAM area */ + + Byte DaysKill, /* Kill older than 'x' days */ + RecvKill; /* Kill recv msgs, recv for more than 'x' days */ + Word CountKill; + + Word ReadSecurity; + FlagType ReadFlags, + ReadNotFlags; + + Word WriteSecurity; + FlagType WriteFlags, + WriteNotFlags; + + Word SysopSecurity; + FlagType SysopFlags, + SysopNotFlags; + + Char OriginLine[61]; + Byte AkaAddress; + + Byte Age; + + Char JAMbase[61]; + Word Group; + Word AltGroup[3]; + + Byte Attribute2; + + /* Bit 0 : Include in all groups */ + + Byte FreeSpace2[9]; +}; + +struct GROUPrecord { + Word AreaNum; + Char Name[41]; + Word Security; + FlagType Flagsx, + NotFlagsMask; + Byte FreeSpace[100]; +}; + +struct CONFrecord { + Char Name[9]; + Char Parent[9]; + Char Desc[71]; + Byte Attr; + + /* Bit 0 : Private + 1 : Unlisted + 2 : Global + 3 : Permanent + 4 : Use handles + */ + + Char Moderator[36]; + Char Language[21]; + Char Password[16]; + Word Security; + FlagType Flagsx; + Byte NumNodes; + Byte Active[250]; + Boolean Child[250]; + FlagType NotFlagsMask; + Byte FreeSpace[96]; +}; + +struct ARCrecord { + Char Extension[4]; + Char UnpackCmd[61]; + Char PackCmd[61]; +}; + +struct CONFIGrecord { + Word VersionID; + Byte xCommPort; + LongInt xBaud; + Byte xInitTries; + Char xInitStr[71]; + Char xBusyStr[71]; + Char xInitResp[41]; + Char xBusyResp[41]; + Char xConnect300[41]; + Char xConnect1200[41]; + Char xConnect2400[41]; + Char xConnect4800[41]; + Char xConnect9600[41]; + Char xConnect19k[41]; + Char xConnect38k[41]; + Boolean xAnswerPhone; + Char xRing[21]; + Char xAnswerStr[21]; + Boolean xFlushBuffer; + Integer xModemDelay; + + Word MinimumBaud; + Word GraphicsBaud, + TransferBaud; + ra_Time SlowBaudTimeStart, + SlowBaudTimeEnd, + DownloadTimeStart, + DownloadTimeEnd; + + ra_Time PageStart[7]; + ra_Time PageEnd[7]; + + Char SeriNum[23]; + Char CustNum[23]; + Byte FreeSpace1[24]; + Word PwdExpiry; + + Char MenuPath[61]; + Char TextPath[61]; + Char AttachPath[61]; + Char NodelistPath[61]; + Char MsgBasePath[61]; + Char SysPath[61]; + Char ExternalEdCmd[61]; + + NetAddress Address[10]; + Char SystemName[31]; + + Word NewSecurity; + Word NewCredit; + FlagType NewFlags; + + Char OriginLine[61]; + Char QuoteString[16]; + Char Sysop[36]; + Char LogFileName[61]; + Boolean FastLogon, + AllowSysRem, + MonoMode, + StrictPwdChecking, + DirectWrite, + SnowCheck; + Integer CreditFactor; + + Word UserTimeOut, + LogonTime, + PasswordTries, + MaxPage, + PageLength; + Boolean CheckForMultiLogon, + ExcludeSysopFromList, + OneWordNames; + AskType CheckMail; + Boolean AskVoicePhone, + AskDataPhone, + DoFullMailCheck, + AllowFileShells, + FixUploadDates, + FreezeChat; + AskType ANSI, /* ANSI: Yes, no, or ask new users */ + ClearScreen, /* Clear: " */ + MorePrompt; /* More: " */ + Boolean UploadMsgs; + AskType KillSent; /* Kill/Sent " */ + + Word CrashAskSec; /* Min sec# to ask 'Crash Mail ?' */ + FlagType CrashAskFlags; + Word CrashSec; /* Min sec# to always send crash mail. */ + FlagType CrashFlags; + Word FAttachSec; /* " ask 'File Attach ?' */ + FlagType FAttachFlags; + + Byte NormFore, + NormBack, + StatFore, + StatBack, + HiBack, + HiFore, + WindFore, + WindBack, + ExitLocal, + Exit300, + Exit1200, + Exit2400, + Exit4800, + Exit9600, + Exit19k, + Exit38k; + + Boolean MultiLine; + Byte MinPwdLen; + Word MinUpSpace; + AskType HotKeys; + Byte BorderFore, + BorderBack, + BarFore, + BarBack, + LogStyle, + MultiTasker, + PwdBoard; + Word xBufferSize; + Char FKeys[10][61]; + + Boolean WhyPage; + Byte LeaveMsg; + Boolean ShowMissingFiles, + xLockModem; + Byte FreeSpace2[10]; + Boolean AllowNetmailReplies; + Char LogonPrompt[41]; + AskType CheckNewFiles; + Char ReplyHeader[61]; + Byte BlankSecs; + Byte ProtocolAttrib[6]; + Char xErrorFreeString[16]; + Byte xDefaultCombined[25]; + Word RenumThreshold; + Char LeftBracket, + RightBracket; + Boolean AskForHandle; + Boolean AskForBirthDate; + + Word GroupMailSec; + + Boolean ConfirmMsgDeletes; + + Byte FreeSpace4[30]; + + Char TempScanDir[61]; + AskType ScanNow; + Byte xUnknownArcAction, + xFailedUnpackAction, + FailedScanAction; /* Bit 0:Mark deleted, 1:Mark unlisted, 2:Mark notavail */ + Word xUnknownArcArea, + xFailedUnpackArea, + FailedScanArea; + Char ScanCmd[61]; + Boolean xDeductIfUnknown; + + Byte NewUserGroup; + AskType AVATAR; + Byte BadPwdArea; + Char Location[41]; + Byte DoAfterAction; /* 0 = wait for CR, > 0 = wait for x seconds */ + Char OldFileLine[41]; + Byte CRfore, + CRback; + Char LangHdr[41]; + Boolean xSendBreak; + Char ListPath[61]; + AskType FullMsgView; + AskType EMSI_Enable; + Boolean EMSI_NewUser; + + Char EchoChar[2]; + Char xConnect7200[41]; + Char xConnect12000[41]; + Char xConnect14400[41]; + Byte Exit7200; + Byte Exit12000; + Byte Exit14400; + Char ChatCommand[61]; + AskType ExtEd; + Byte NewuserLanguage; + Char LanguagePrompt[41]; + VideoType VideoMode; + Boolean AutoDetectANSI; + Boolean xOffHook; + Byte NewUserDateFormat; + Char KeyboardPwd[16]; + Boolean CapLocation; + Byte NewuserSub; + Char PrinterName[5]; + Byte HilitePromptFore, + HiLitePromptBack; + Char xInitStr2[71]; + Boolean AltJSwap; + Char SemPath[61]; + Boolean AutoChatCapture; + + Char FileBasePath[61]; + Boolean NewFileTag; + Boolean IgnoreDupeExt; + Char TempCDFilePath[61]; + Byte TagFore, + TagBack; + Char xConnect16k[41]; + Byte Exit16k, + FilePayback; + Char FileLine[201]; + Char FileMissingLine[201]; + Byte NewUserULCredit; + Word NewUserULCreditK; + ARCrecord ArcInfo[10]; + Char RAMGRAltFKeys[5][61]; + Char ArcViewCmd[61]; + Char xConnectFax[41]; + Byte ExitFax; + Boolean UseXMS, + UseEMS; + Byte CheckDOB; + AskType EchoCheck; + Word ccSec, + ReturnRecSec; + Boolean HonourNetReq; + COMBINEDrecord DefaultCombined; + Boolean AskForSex, + AskForAddress; + AskType DLdesc; + Boolean NewPhoneScan; + Byte FutureExpansion[587]; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gs_recho.h b/goldlib/gcfg/gs_recho.h new file mode 100644 index 0000000..9cfb832 --- /dev/null +++ b/goldlib/gcfg/gs_recho.h @@ -0,0 +1,211 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// RA-ECHO areafile structure +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// Original Pascal unit: +// ------------------------------------------------------------------ +// +// UNIT EchoDefs; +// +// (* Definitions for RA-ECHO v.1.0 *) +// +// +// INTERFACE +// +// CONST +// +// EchoConfigName = 'RA-ECHO.CFG'; +// AreaInfoName = 'AREAS'; +// NodeFileName = 'NODE'; +// DupeFileName = 'DUPES'; +// LinkFileName = 'LINKS'; +// ExportMarkName = 'LASTEXP'; +// ImportMarkName = 'LASTIMP'; +// ConfTextName = 'CONFNAME'; +// EchoExt = '.RAE'; +// +// TYPE +// +// LastReadRec = RECORD +// LastMsg : word; +// LastDate : LONGINT; +// END; (* of RECORD *) +// +// +// AddressRec = RECORD +// Zone, +// Net, +// Node, +// Point : word; +// Domain : STRING [20]; +// END; (* of RECORD *) +// +// +// PacketFlags = (NoFlags,Hold,Crash,Direct,KillSend,KillFileSend,TruncatFileSend); +// +// +// MailTypeDef = (Echomail, Netmail, Localmail, Newmail); +// +// +// ArcProgramDef = (NoArc,ZIPArc,LZHArc,PAKArc,ARCArc,ZOOArc,LHAArc,ARJArc +// ,HyperArc,UnknownArc, +// UserArc1,UserArc2,UserArc3,UserArc4,UserArc5,UserArc6); +// +// NodeDatenRec = RECORD +// PointNr, (* Point-Number *) +// NodeNr, (* Node-Number *) +// NetNr, (* Net-Number *) +// ZoneNr, (* Zone-Number *) +// SendZone, (* Zone of Sender *) +// SendNet, (* Net of Sender *) +// SendNode, (* Node of Sender *) +// SendPoint : word; (* Point of Sender *) +// Conferences : ARRAY [1..20] OF booleanEAN; (* Echomail Conferences *) +// Access : word; (* Access Level *) +// NodeName : STRING [30]; (* Name of Node *) +// PassWord : STRING [20]; (* Password for Areafix/Filefix *) +// ArcType : ArcProgramDef; (* Definition of the arcer *) +// ArcPassword : STRING [20]; (* Password in Arcmail header *) +// ReAddress : booleanEAN; (* true, if address has to be ramapped *) +// (* to 3-d Pointnet address *) +// ArcMailStatus : PacketFlags; (* Status of ArcMail-Packets for the Node *) +// (* Node o. Hold o. Crash o. Direct *) +// NameExport : booleanEAN; (* true, if Node wants to get mail addresed *) +// (* to his name no matter if he is linked to that echo *) +// AddPacket : booleanEAN; (* Append mail to exeistimg packets *) +// TotalImport, (* Totale Imports from this node (# of mails *) +// TotalExport : word; (* Totale Exports to this node *) +// NotifyFlag : booleanEAN; (* Does this node get notify messages *) +// AcceptNewEchos: booleanEAN; (* New echos received from this node are *) +// (* created as passthru echos *) +// nodeispassive : booleanEAN; (* if false mail will not be exported to *) +// (* this node *) +// LastDate : STRING [8]; (* The last date the user requested via Filefix *) +// AddNewAreas : booleanEAN; +// packnetmail : ArcProgramDef; +// NetmailStatus : Packetflags; +// Dummy : ARRAY [1..6] OF byte; (* - unused - *) +// END; (* of RECORD *) +// +// AreaDatenRec = ARRAY [1..500] OF booleanEAN; +// +// NodeFileRec = RECORD +// NodeDaten : NodeDatenRec; +// AreaFeld : AreaDatenRec; +// END; (* of RECORD *) +// +// +// (* Das File AREAS.RAE enth„lt alle 500 Echo-Areas, Nr. 1-200 sind die +// internen Areas von RA, 201-500 die Passthru Areas *) +// +// +// EchoAreaRec = RECORD +// Name : STRING [40]; (* Area Name *) +// Descr : STRING [60]; (* Description *) +// MailType : MailTypeDef; +// ImportFlag : booleanEAN; (* true, if the message has to be *) +// (* imported to a directory as *.MSG *) +// MsgDirectory : STRING [60]; +// ReadSecurity : Word; (* Read access level *) +// WriteSecurity : Word; (* Write access level *) +// OriginLine : String [60]; +// AreaAddress : AddressRec; (* Adress of sender for this echo *) +// ConferenceNr : Byte; (* The conference this echo belongs *) +// (* to. If 0 the echo has NO conference *) +// END; (* of RECORD *) +// +// ConfNameRec = STRING [255]; +// +// +// IMPLEMENTATION +// +// END. +// +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +enum { + RAE_ECHO, + RAE_NET, + RAE_LOCAL +}; + + +// ------------------------------------------------------------------ +// Structure for AREAS.RAE Version 1.00 + +typedef struct { + char echoid[41]; + char desc[61]; + byte type; + byte isopus; + char path[61]; + word readsec; + word writesec; + char origin[61]; + ftn_addr addr; + char domain[21]; + byte conference; +} TRaEchoArea100, *PRaEchoArea100; + + +// ------------------------------------------------------------------ +// Structure for AREAS.RAE Version 1.01 (I hope!) + +typedef struct { + char echoid[41]; + char desc[61]; + byte type; + byte isopus; + char path[61]; + word readsec; + word writesec; + char origin[61]; + ftn_addr addr; + char domain[21]; + byte conference; + word maxdays; + word maxrecv; + word maxcount; + word totalimp; + word totalexp; + char dummy[130]; +} TRaEchoArea101, *PRaEchoArea101; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_sbbs.h b/goldlib/gcfg/gs_sbbs.h new file mode 100644 index 0000000..8ccd5e4 --- /dev/null +++ b/goldlib/gcfg/gs_sbbs.h @@ -0,0 +1,486 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// SuperBBS configuration data structures +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// Misc types + +typedef char MsgToIdxRecord[36]; +typedef byte SbFlagType[4]; + + +// ------------------------------------------------------------------ +// Structure of SCONFIG.BBS + +typedef struct { + + char SystemPath[67]; + char MsgBasePath[67]; + char TempPath[67]; + char RedirectDevice[13]; + char Resp19200[41]; + char Resp38400[41]; + byte ShowSecurity; + byte ShowPswdAtLogon; + long BetaCode; + byte Unused[200]; + byte Empty1[284]; + byte AllowCat; + byte Answerboard; + byte Use7bitChars; + word BufferSize; + byte Empty2[45]; + byte EntryColor; + byte FilesBeforeRatio; + word MinSpace; + byte ClearTemp; + byte Empty3[163]; + byte UseAliasSystem; + byte Ansilogon; // 0 = No, 1 = Yes, 2 = Auto detect + byte ExcludeSysOp; + byte Empty4[122]; + char AltFkeys[10][61]; + byte Checkfiles; + byte PasswordBoard; + byte Alt_J_Swaptoems; + word MaxTimeInBank; + byte NoBirthDayAsk; + byte MaxDescLines; + byte Empty5[45]; + byte FastMailCheck; + byte DefaultColors[10]; + byte Empty6[45]; + byte LinesInSystem; + char CommonDir[80]; + word VersionNumber; + word FullScrChatBaud; + byte PressEnterColor; + byte AreaSelectColor[3]; + byte StatusLineColor; + byte VirusChkMode; + char WorkPath[80]; + byte WatchCDatDos; + byte UseCtrlX; + byte MsgAfterPageBoard; + byte SearchAliases; + byte EchoConvert; + byte SwapAtPackers; + byte InternalProtocols; + // bit 0 : Zmodem + // bit 1 : Ymodem batch + // bit 2 : Xmodem + // bit 3 : Xmodem 1K (Ymodem) + // bit 4 : Xmodem 1K G + // bit 5 : Ymodem-g + char FirstMenuInSystem[9]; + byte ColoredQuoteText; + byte AddUploadersName; + word DaysUntilExpiration; + char QWKBBSID[7]; + byte QWKDefaultBoard; + short QwkMaxNrToPack; + char StatuslineStr[2][101]; + char Location[41]; + byte UsPhoneNrFormat; + char DlCounterLBracket; + char DlCounterRBracket; + byte QWKAllowTagLines; // 0=no, 1=yes, 2=only local areas + word LogonSecLvl; + byte LogonAge; + char LogonPassword[16]; + byte NoGroupMailCheck; + byte NoUserListIntype27; + word GroupMsgSecLvl; + byte AskSex; + byte AskAnsi; // 0=ask, 1=yes, 2=no + byte AskMailCheck; // 0=ask, 1=yes, 2=no + byte AskNewFilesCheck; // 0=ask, 1=yes, 2=no + byte AskFullScrEditor; // 0=ask, 1=yes, 2=no + byte AskFullScrViewer; // 0=ask, 1=yes, 2=no + byte AskPagePause; // 0=ask, 1=yes, 2=no + byte AskScreenClears; // 0=ask, 1=yes, 2=no + char PageStart[7][6]; + char PageEnd[7][6]; + byte UseIEMSI; + byte CapitalizeCity; + byte CapitalizeAlias; + char VirusScannerCmd[128]; + byte NoExtractBeforeScan; + byte VirusFoundErrorLvl; + byte SysOpsFscrChatClr; + byte UsersFscrChatClr; + byte ScanForDupePhones; // 0 = no, 1 = log entry, 2 = don't allow + byte NormalLongDesc; + char NodelistPath[73]; + word MinCrashMailSec; + byte NoDorinfo1; + byte NoTouch; + byte ZoneMatching; + byte strictdupecheck; + byte noextendednodeinfo; + byte Birthdayverify; + byte realmsgnumbers; + char LocalAttachPath[67]; + byte NoLACheckAtLogon; + byte AllowedPackers; + // Bit 0 ; ZIP + // Bit 1 ; ARC + // Bit 2 ; LZH + // Bit 3 ; ARJ + byte BoardsFileToCurDir; + char UnLockPwd[16]; + char Resp7200[41]; + char Resp12000[41]; + char Resp14400[41]; + byte LineEditorQuote; // 0=intelligent, 1=normal, 2=no + byte SevenBitOnly; + byte nofileflagging; + char ReplyingToStr[81]; + byte FreeFileTimeCheck; // 0 = NO, 1 = YES, 2 = EVENT + byte PageReasonToSubj; + byte AgeGraphStartAge; + word ETGCLocalAttrib; + word ETGCRemoteAttrib; // Not yet used + // BIT 0 ; 320x200x16 + // BIT 1 ; 640x200x16 + // BIT 2 ; 640x350x16 + // BIT 3 ; 640x480x16 + // BIT 4 ; 320x200x256 + byte AskCombinedBoards; + byte AskCombMailCheck; // 0=ask, 1=yes, 2=no + byte UseNewFilesCheckDate; + word BurnOutSecs; + byte NoNamesInGroupMail; + byte AutoChatCapture; + byte AskDefProto; + byte AskHotkeys; // 0=ask, 1=yes, 2=no + byte FreeAttaches; + SbFlagType LogonFlags; + byte NoRemoteSysOp; + byte FscrReaderColors[12]; + byte NewsDateCheck; + byte NoNameIdx; + word AkaZone[15]; + word AkaNet[15]; + word AkaNode[15]; + word AkaPoint[15]; + byte MinorVersionNumber; // ie. 1 = Gamma-1, 2 = Gamma-2, 100 = official + byte Extraspace[2709]; + +} ExtraConfigT, *ExtraConfigP, **ExtraConfigI; + + +// ------------------------------------------------------------------ +// Structure of SUSERS.BBS + +typedef struct { + + MsgToIdxRecord Name; + char Birthday[9]; + word Attrib; + byte Flagsx[4]; // Not yet used + char Firsttime[6]; + char FirstDate[8]; + byte CombinedBoards[25]; + char SysOpComment[80]; + char DefaultProto; + short UserRecPtr; + byte Colors[10]; + byte FileListType; // Not yet used + MsgToIdxRecord Alias; + long MinutesUsed; + char ViewFileName[13]; // SeeAlso attrib bits 4 - 6 + char MenuToRun[9]; + word Timeinbank; + byte TodayCalls; + char LanguageFileN[9]; + char Expirationdate[9]; + byte CurrentFArea; + byte CurrentMArea; + byte CurrentDoor; + byte DefaultPacker; + // not bit mapped ! + // 1 = ZIP + // 2 = ARC + // 3 = LZH + // 4 = ARJ + char LastNewFilesCheck[9]; + byte ExtraSpace[403]; + +} ExtraUserRecT, *ExtraUserRecP, **ExtraUserRecI; + +// Attrib; +// +// 1 Bit 0; MailCheck at logon +// 2 Bit 1; Newfiles Check at logon +// 4 Bit 2; No downloadratio +// 8 Bit 3; Female +// 16 Bit 4; Delete file after viewing +// 32 Bit 5; Display file only once +// 64 Bit 6; File viewed +// 128 Bit 7; Fullscreen viewer +// 256 Bit 8; Combined mail check +// 512 Bit 9; No hotkeys +// Bit 10; +// Bit 11; +// Bit 12; +// Bit 13; +// Bit 14; +// Bit 15; + + +// ------------------------------------------------------------------ +// Structure of USERS.BBS + +typedef struct { + + MsgToIdxRecord Name; + char City[26]; + char Password[16]; + char DataPhone[13]; + char HomePhone[13]; + char LastTime[6]; + char LastDate[9]; + byte Attrib; + SbFlagType Flagsx; + short Credit; + short Pending; + word MsgsPosted; + word HighMsgRead; + word SecLvl; + word Times; + word Ups; + word Downs; + word UpK; + word DownK; + short TodayK; + short Elapsed; + short Len; + byte ExtraSpace1[2]; + byte Age; + short ExtraUserrecPtr; + byte ExtraSpace2[3]; + +} UserRecordT, *UserRecordP, **UserRecordI; + +// Attrib; +// +// bit 0; Deleted user +// bit 1; Screen clear codes +// bit 2; More prompt +// bit 3; ANSI graphics +// bit 4; No-Kill +// bit 5; Ignore Download Hours +// bit 6; ANSI editor +// bit 7; Do not disturb mode ON +// +// + + +// ------------------------------------------------------------------ +// Structure of CONFIG.BBS + +typedef struct { + + byte Status; // 0=Disabled 1=Enabled + char RunTime[6]; + byte ErrorLevel; + byte Days; + byte Forced; + char LastTimeRun[9]; + +} EventRecordT, *EventRecordP, **EventRecordI; + +typedef struct { + + char Name[17]; + byte Typ; // 0=Standard 1=Net 3=Echo + byte Kinds; // 0=Private & Public 1=Private 2=Public 3=Read-Only + byte Combined; + byte Aliases; // 0=no aliases,1=yes,2=ask alias,3=Alias/name + + short ReadSecLvl; + SbFlagType ReadFlags; + + short WriteSecLvl; + SbFlagType WriteFlags; + + short SysopSecLvl; + SbFlagType SysopFlags; + +} BoardRecordT, *BoardRecordP, **BoardRecordI; + +typedef struct { + + short CommPort; + word InitBaud; + word InitTimes; + word AnswerWait; + char ModemInitStr[71]; + char ModemBusyStr[71]; + char ModemInitResp[41]; + char ModemBusyResp[41]; + char Resp300[41]; + char Resp1200[41]; + char Resp2400[41]; + + char MenuPath[67]; + char TextPath[67]; + char NetPath[67]; + + short MinBaud; + short GraphicsBaud; + short XferBaud; + char LowBaudStart[6]; + char LowBaudEnd[6]; + char DownloadStart[6]; + char DownloadEnd[6]; + char PagingStart[6]; // !! Not used anymore !! + char PagingEnd[6]; // !! Not used anymore !! + + short MatrixZone; + short MatrixNet; + short MatrixNode; + short OldAkaNet[5]; // not used + short OldAkaNode[5]; // not used + short NetMailBoard; + + short DefaultSec; + short DefaultCredit; + SbFlagType DefaultFlags; + + char EditorCmdStr[71]; + char OriginLine[61]; + MsgToIdxRecord SysopName; + byte AutoLogonChar; + byte FastLogon; + byte ScreenBlanking; + byte UseLastRead; + byte MonoMode; + byte DirectWrite; + byte SnowCheck; + byte NetEchoExit; + byte OneWordNames; + byte CheckMail; + byte AskHomePhone; + byte AskDataPhone; + byte GraphicsAvail; + short InactiveTimeOut; + short LogonTime; + short DefFgColor; + short DefBgColor; + short PasswordTries; + short MaxPageTimes; + short PageBellLen; + + byte Use_Xmodem; + byte Use_Xmodem1k; + byte Use_Ymodem; + byte Use_YmodemG; + byte Use_Sealink; + byte Use_Zmodem; + byte Inp_Fields; + char QuoteStr[4]; + short UploadCredit; + char LoadingMessage[71]; + char SelectionPrompt[71]; + + word VersionID; + char Resp4800[41]; + char Resp9600[41]; + + short OldAkaZone[5]; // not used + + short MatrixPoint; + short OldAkaPoint[5]; // not used + + byte UseAka[200]; + byte AskAge; // Not used + char SystemName[41]; + long RegKey; + + byte EntryfieldColor; + byte MenuBorderColor; + + short SysOpSeclvl; + byte AllowDelMsgs; + + EventRecordT EventRec[30]; + BoardRecordT UnusedBoards[200]; + +} ConfigRecordT, *ConfigRecordP, **ConfigRecordI; + + +// ------------------------------------------------------------------ +// Structure of BOARDS.BBS + +typedef struct { + + char Name[31]; + char QwkName[13]; + + byte Typ; // 0=Standard 1=Net 3=Echo + byte Kinds; // 0=Private & Public 1=Private 2=Public 3=Read-Only + byte Aliases; // 0=no aliases, 1=yes, 2=ask alias, 3=Alias/name + + short ReadSecLvl; + SbFlagType ReadFlags; + + short WriteSecLvl; + SbFlagType WriteFlags; + + short SysopSecLvl; + SbFlagType SysopFlags; + + char Group; + byte Replystatus; // 0 = normal, 1 = net/normal, 2 = net only, 3 = no replies + byte Age; + byte Attrib; + byte UseAka; + +} MsgBoardRecordT, *MsgBoardRecordP, **MsgBoardRecordI; + +// Attributes ; +// +// bit 0 ; Combined +// bit 1 ; Default combined +// bit 2 ; Allow message deleting +// bit 3 ; Allow taglines +// bit 4 ; Use in template system +// bit 5 ; Convert 8bit -> 7bit +// bit 6 ; forced ON in the mail check + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_ts.h b/goldlib/gcfg/gs_ts.h new file mode 100644 index 0000000..209ba9d --- /dev/null +++ b/goldlib/gcfg/gs_ts.h @@ -0,0 +1,92 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// TosScan Areafile struct. Reverse engineered spec! +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// +// The TosScan AREAFILE.FD +// +// Original hack by Bjarne Maschoreck 2:231/50. +// Later modified by Odinn Sorensen 2:231/77 +// +// ------------------------------------------------------------------ +// +// The first 4 bytes are ignored (probably CRC32 of total file). +// +// The rest are records of fixed-length 650 bytes. +// Strings are NUL-terminated. +// Some fields are indexes into tables in FD.SYS. +// Conferences are not removed when deleted, a flag is set instead. +// The same record format is used for TosScan/QBBS and TosScan/MSG. +// +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +typedef byte bit; + + +// ------------------------------------------------------------------ +// Structure of the records + +typedef struct { + char echoname[51]; /* Echomail conference name */ + char path[51]; /* Path, if .MSG format otherwise NUL'ed */ + bit seenbys : 1; /* 1 = Import Seen-By 0 = No Seen-By */ + bit security : 1; /* 1 = Security On 0 = Security Off */ + bit passthru : 1; /* 1 = Passthru 0 = Not Passthru */ + bit visible : 1; /* 1 = Visible 0 = Not visible */ + bit deleted : 1; /* 1 = Deleted 0 = In Use */ + bit cpp : 1; /* 1 = CPP On 0 = CPP Off */ + bit tiny : 1; /* 1 = Tiny 0 = Not Tiny */ + bit Private : 1; /* 1 = Private 0 = Not Private */ + byte originno; /* FrontDoor origin number? Seems to follow origno */ + ftn_addr feeders[60]; /* List of feeds. Sorted descending, NUL-padded */ + char fill2[4]; /* Unknown */ + byte groupid; /* Group-relation. (A-Z, uppercase) */ + byte board; /* Board number, if QBBS format - otherwise zero */ + bit akano : 4; /* Index in FD.SYS - Aka number */ + bit origno : 4; /* Index in FD.SYS - Origin number */ + char fill3; /* Unknown */ + short maxmsgs; /* Max msgs in area (max 20000) */ + short dayskeep; /* Day to keep before deleting (max 365) */ + char fill4[4]; /* Unknown */ + char desc[40]; /* Area description for AreaMgr */ + char fill5[10]; /* Unknown */ +} TS_Areafile; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_wmail.h b/goldlib/gcfg/gs_wmail.h new file mode 100644 index 0000000..ee9b6af --- /dev/null +++ b/goldlib/gcfg/gs_wmail.h @@ -0,0 +1,116 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WMail 2.2 config structs +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ +// Structure of WMAIL.PRM + +typedef struct { + word version; + char sysop[31]; + char key[17]; + struct this_name_for_msvc { + ftn_addr addr; + char domain[21]; + } aka[11]; + word fakenet; + struct { + word net; + word node; + } zonegate[10]; + byte active_options; + byte swap; + word minspace; + struct { + char mail[61]; + char files[61]; + char out[61]; + char arcmail[61]; + char msgbase[61]; + char dupes[61]; + char badecho[61]; + char packer[61]; + char stats[61]; + char newareas[61]; + char nodelist[61]; + } dir; + char origin[10][66]; + char arealistfile[61]; + byte logstyle; + byte active_options2; + struct this_name_for_msvc_too { + ftn_addr addr; + byte packer; + char cmdpw1[21]; + char cmdpw2[21]; + byte level; + short misc; + byte aka; + } bbsinfo[50]; + char routefile[61]; + struct { + char name[13]; + char parms[21]; + } packer[7]; + struct { + char name[13]; + char parms[21]; + } unpacker[7]; + byte defpacker; + byte defmisc; + byte unused[1000]; +} TWmailPrm, *PWmailPrm; + + +// ------------------------------------------------------------------ +// Structure of AREAS.PRM + +typedef struct { + char titolo[41]; + char path[81]; + byte tipo; // Local=1, EchoMail=2, NetMail=3, Passthru=4 + byte wedorigin; + char tag[41]; + byte def_attr; // Bit 0: Pvt, 1: Crash, 4: F/A, 7: Kill/Sent + char forwardto[3][61]; + byte aka; + byte misc; + byte level; + byte wmorigin; + char fill[8]; +} TAreasPrm, *PAreasPrm; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_wtr.h b/goldlib/gcfg/gs_wtr.h new file mode 100644 index 0000000..2372f22 --- /dev/null +++ b/goldlib/gcfg/gs_wtr.h @@ -0,0 +1,536 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +// header file converted from Pascal to C by damWARE, 08.06.98. + +// WaterGate Developers Kit for release 0.93 +// database structures + +// include this file from one of your source files with $I structs.pas + +// this file describes the structures of WaterGate's database. There is +// no code in header, but just the declarations of the structures. There +// _is_ a whealth of explanation in this file though! + +/* History: + + 950903 0.19 - Initial release. + 950918 0.19.p2 - The config structure in the original release was a + complete mess and unusable. + 951030 0.20 - Added administrator fields. + 951203 0.21 - New list server user type, longer time zone string, + export AKA in user record. + 960214 0.90 - Config: Log9->LogAreaFix and Log10->LogMapApply. + UUCPForwardRecord: reduced path length by 1 and + added Group letter. + 960530 0.91 - AreaBase: Added fields for decoding files. + Config: Log11..Log14 are now used. + New fields for config: CopyHeaders_FU, MailGrade, + NewsGrade, TimeSlicing, NetmailDecode, + NetmailDecodePath, PrivateDecode, PrivateDecodPath. + 961014 0.92 - Config: Log15 and Log16 are now used, Added RAR + support, more system node numbers, more copy header + entries, more areafix/newsfix forward entries, + remove unused fields. + ListServer: Added Access and DefaultAccess. + UserBase: Added BAG and SMTP variant record entry. + AreaBase: Seen-BY akas now support 100 bits. + 960706 0.93 - New groups format and lots of other changes. + AreaBase 04->07: Changed IsInGroups, Added Hidden. + Updated groups explanation. + UserBase 05->08: Removed unused longint. Changed + groups, added envelope header. + ListServer 03->05: Added re-confirmation fields, + added MLAddress, added confirm interval. + Config 14->22: Changed Default_F and Default_U, + removed ConversionTable, Added SmtpForward, + MaxXPostNewsGroups, WildCatMSGLockDir, OpusDateFormat, + MaxWildCatMsgLen, KillAreafixMsgs, Color set. +*/ + +// I have reduced all the types and constants we use, to make it easier +// for you to read the structures. The names used end with _F if it is +// Fidonet related, and with _U if it is UUCP/Usenet related. _B is BAG, +// _S is SMTP and _P is POP3. + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +/* +**========================================================================== +** ABOUT THE DATABASES +**========================================================================== +*/ + +// WaterGate uses six binary database files and one ascii configuration +// file. This source file only covers the six binary databases. Each of +// the database files starts of with a 26 byte long header, which is +// basically a string that is written to disk, including the length byte +// at the first position. The string is thus declared as a STRING[25]. +// Each database has its own header, as defined below. The last two +// digits are a modification counter, which is increased by one very +// time the database structures change. You have to check this header +// and it has to match exactly, or else you should not access the +// databases with the structures in this file! + +const char AreaBaseHeader[26] = "WtrGate AreaBase 07"; +//const char UserBaseHeader[26] = "WtrGate UserBase 08"; +//const char SubscrBaseHeader[26] = "WtrGate SubscrBase 01"; +//const char GrpDescrBaseHeader[26] = "WtrGate GroupDescr 03"; +//const char ListServerHeader[26] = "WtrGate ListServer 05"; +const char ConfigHeader[26] = "WtrGate Config 22"; + +// Directly after this string, the first record starts. All record +// numbering is 1..n, with the special value 65535 meaning a NIL pointer +// record, mostly used to indicate free positions or the end of a list +// of record numbers. + +const word NILRecordNr = 0xFFFF; + +// to find out how many records are present in a database, you use the +// following formule: +// +// RecCount = ((FileSize (Database)-26) DIV SizeOf (Record)); +// +// This formula can be used for each of the databases. Simply substitute +// "Record" with the correct structure name and "Database" with the +// actual file variable. It is best to declare the file variable as a +// FILE and to open the database with a Reset (Database,1), as below: +// +// VAR AreaFile : FILE; +// RecCount : WORD; +// +// BEGIN +// Assign (AreaFile,'AREABASE.TDB'); +// Reset (AreaFile,1); +// BlockRead (AreaFile,Header,26); +// RecCount:=(FileSize (AreaFile)-26) DIV SizeOf (AreaBaseRecord)); +// Close (AreaFile); +// END +// +// To read and write a record, you substract 1 from the record number, +// multiply it with the record size and add 26, then seek to that +// position in the file and read or write the record, like this: +// +// VAR AreaRec : AreaBaseRecord; +// AreaRecNr : WORD; +// Position : LONGINT; +// +// BEGIN +// Position:=26+(AreaRecNr-1)*SizeOf (AreaRecord); +// Seek (AreaFile,Position); +// BlockRead (AreaFile,AreaRec,SizeOf (AreaBaseRecord)); +// END; + +/* +**========================================================================== +** GLOBAL STRUCTURES +**========================================================================== +*/ + +// this structure is used to hold an AKA, whereever required + +typedef struct { + word zone; + word net; + word node; + word point; + char domain[26]; +} FidoAddrType; + + +/* +**========================================================================== +** GROUP DESCRIPTIONS DATABASE +**========================================================================== +*/ + +// this database contains 128 records, one for each of the groups. Each +// record hold the description of the group, the system AKA to use, +// which is an index number from 1 to 100 in the array of system AKAs +// in the Configuration Record. And finally it contains the ReadOnly +// boolean, which is set to TRUE to disable posting to any area in this +// group, unless the user and the area are both in read/write group as +// well. + +struct { + char groupdesc[31]; + byte originaka; // 1..100 + bool readonly; +} GroupDescRecord; + +// [...] + +// new groups storage (0.93): +// +// there are 128 groups, numbered 1 to 128. The AreaBase.IsInGroups +// and UserBase.Groups are 16 byte arrays, where each byte represents +// subscription to one group. Bit 0 in the first byte is group 1, etc. + +const word MaxGroups = 128; // A1-5,B1-5,..,Y1-5,Z1-3 +const word GroupFlagLen = MaxGroups / 8; + +typedef byte GroupFlagType[GroupFlagLen]; // bit mask + +// to access to groups, use the GroupFlagType and the following code +// sequence to access the group list. +// +// VAR I,O : BYTE; +// +// I:=1+((NewGroupNr-1) DIV 8); +// O:=(NewGroupNr-1) MOD 8; +// Group[I]:=Group[I] OR (1 SHL O); +// +// The above example adds NewGroupNr (1..128) by settings the correct +// bit in the array. I is an index into the array and O is the bit +// number ("offset", 0..7). +// +// You can use constructions with AND to reset a bit. I have created +// abstract functions to access a GroupFlagType for resetting it, +// adding a single group, removing a single group, testing for +// membership, set overlap tests, etc. + + +/* +**========================================================================== +** AREABASE +**========================================================================== +*/ + +typedef struct { + bool deleted; + byte areatype; // 0=Echo, 1=Netmail, 2=Local, 3=Email + char areaname_U[61]; // the two names of this area + char areaname_F[61]; + char comment[61]; // the comment / description + byte isingroups[16]; // the groups this area is in. See the group + // descriptions database for an explanation. + + word userlist; // points to the first subscription base + // record. See explanation there. + + byte originaka; // the system AKA to use for the origin line, + // is an index 1..20 into the array in the + // configuration record. + + byte addseenbyakas[13]; // The system AKAs 1..100 to add to the SEEN-BY + // If the bit is set, it is added. [0]bit0 is + // AKA 1, [0]bit1 2, etc. + + bool passive; // TRUE if this area is passive + bool alwpassive; // TRUE if this area is allowed to be passive + byte originnr; // origin number to use: 0=custon, 1/2=system + char origin[62]; // the custom origin line + byte fidomsgstyle; // the style of this area's message base + // 0=None, 1=Msg, 2=Squish, 3=Jam, 4=WildCat + + char fidomsgpath[80]; // the path to the database + word fidomsgage; // the maximum age of a message, when cleaning + word fidomsglimit; // the max. num of msgs in allowed + byte moderated; // is this area moderated? 0=No, 1=Usenet + char moderator[51]; // the e-mail address of the moderator + bool decode; // XX/UU/MIME decode? + char decodepath[80]; // path where to store decoded files + bool hidden; // if TRUE then doesn't show up in AreaFix/newsfix +} AreaBaseRecord; + +/* +**========================================================================== +** USERBASE +**========================================================================== +*/ + +// the userbase holds all the users that are configured in WtrConf. There +// is one record for each user. The maximum number of records is 65534. + +struct { + bool deleted; // TRUE means deleted + byte system; // 0=Fido, 1=Usenet, 2=Bag supplier + char organization[61]; // description of this user + byte groups[16]; // the groups this user is allowed in + // see the group description database + // for an explanation of the storage. + + bool passive; // is this user passive? + char areafixpwd[21]; // its AreaFix/newsfix password + bool allowfrom; // TRUE = allow special AreaFix commands + bool allowcreate; // TRUE = allow new area creation + bool allowsubdomains; // TRUE if this user is allowed to have sub-domains + word arealist; // pointer to the first subscription base + // record, holding the areas this user is + // subscribed to. See the subscription + // base for an explanation. + + char uucpname[11]; // the user's UUCP name + bool worldreg; // World Registered UUCP name? + char domains[51][6]; // domain names + + word type; + + union { + // 0 = FidoNet style user + struct { + FidoAddrType Address; // AKA + char sysop[51]; // full name of the sysop + char packetpwd[9]; // password for *.PKT files + byte compression; + dword maxpktlength; // max length of an .PKT files + // before it is cut off and packed + + byte sendformat; // the send condition: 0=Normal, + // 1=Hold, 2=Crash, 3=Direct. + + byte lastarchdow; // day-of-week used on the last sent + // archive. 0=first, 1..7 = dow. + + byte lastarchnr; // last archive number used + byte exportaka; // Export AKA. 0=Auto, 1..100=System AKA + bool decodefiles; // TRUE = decode files for this user? + } fidostyle; + // 1 = UUCP style user + struct { + byte compress; // 0=None, 1=Compress, 2=Zip + bool cunbatch; // TRUE= add CunBatch to compressed archive + char mailgrade; + char newsgrade; + bool gigot; // TRUE = create GIGOT compatible .XQT files + } uucpstyle; + // 2 = BAG style user + struct { + char bagbacklink[11]; // uucp name of the bag return system + char bagpath[80]; // Search path for the bag files + } bagstyle; + // 3 = SMTP mailer link + struct { + char smtpinpath[80]; // where to process .WRK/.TXT files from + char smtpoutpath[80]; // where to create .WRK/.TXT files + } smtpstyle; + // 4 = POP3 mailbox link + struct { + char pop3file[80]; // where is the POP3 file stored? } + char recipient[51]; // single recipient address + char separator[16]; // separator searched for + char envelopehdr[26]; // envelope header searched for + } pop3style; + // 5 = BBS + struct { + char inbound[80]; // search for .PKT files from BBS tosser here + char outbound[80]; // create .PKT files for BBS tosser here + byte systemaka; // 1..100 + word fakezone; // fake AKA + word fakenet; + word fakenode; + + char inboundext[3]; // extension for inbound packets (PKT/OUT) + bool keepsbp; // TRUE = keep SEEN-BY and PATH? + byte reserved1; // unused + } bbsstyle; + }; + +} UserBaseRecord; + + +/* +**========================================================================== +** SUBSCRIPTIONS DATABASE +**========================================================================== +*/ + +// [...] + +/* +**========================================================================== +** CONFIGURATION DATABASE +**========================================================================== +*/ + +// structures for the system configuration database. There is only one +// record in this database. The structures below start with the areafix +// and newsfix forwarding records, which are used in the configuration +// record. I have removed all other references and put them straigt in. + +// Since AreaFix and newsfix forwarding have not been re-implemented +// yet, I have not described the structures, until they become certain. + +typedef struct { + FidoAddrType uplinkaddress; // uplink AKA + bool unconditional; // allow all new names, or check against file? + char arealistpath[51]; // path to the forwarding file + byte arealist; // type of the file. 0=areas.bbs, 1=names list + char areamanager[11]; // name of uplink's AreaFix + char password[11]; // password for uplink's areafix + byte group; // group to put new areas in. 0 = Group A1 + bool addplus; // Add "+" to connect in front of areaname +} AreafixForwardRecord; + +typedef struct { + char uucpname[11]; // UUCPname of uplink + char arealistpath[50]; // path to the newsgroups listing + byte group; // group to put new areas in. 0 = Group A1 +} UUCPForwardRecord; + +typedef struct { + char systemdir[80]; // path to the other databases + char sysop[51]; // full name of the sysop + word dupechecks; // max. number of dupes to remember (16000 max.) + bool dodupechk; // TRUE = Check for dupes + byte maxhandles; // max. number of outbound files to keep open + bool cachetdbs; // TRUE cache the databases in XMS + char toolargepath[80]; // path to the too-large directory for oversized msgs + char logfilepath[80]; // path and filename of the logfile and stats file + FidoAddrType nodenrs[100]; // system AKAs + word pointnets[100]; // pointnet for each of the system AKAs + byte security_F[2]; // Secure the inbound paths: 0=Yes, 1=No + char inbound_F[80][2]; // paths to the inbound directories + char outbound_F[80]; // path to the outbound directory + char comprprgs_F[80][18]; // Fido compress/decompression programs + dword maxfidomsglen; + dword maxfidoarclen; + byte defgroups_F[16]; // default groups for a new Fido user + byte fidosystem; // 0=Binkley, 1=Frontdoor, 2=dBridge + bool fidoacceptto; // scan the To: field for a e-mail address? + byte fidonetmailtype; // Netmail msgbase type: 0=None, 1=Msg, 2=Squish, 3=Jam + char fidonetmailpath[80]; // path to the database + byte fidobadareatype; // Bad msgbase type: 0=None, 1=Msg, 2=Squish, 3=Jam + char fidobadpath[80]; // path to the database + byte fidodupeareatype; // Dupe msgbase type: 0=None, 1=Msg, 2=Squish, 3=Jam + char fidodupepath[80]; // path to the database + byte fidoautocreatetype; // New created areas type: 0=None, 1=Msg, 2=Squish, 3=Jam + char defaultfidomsgpath[80];// default path to use (no filename) + bool stripseenby; // TRUE = strip seen-bys when importing + bool autolink; // TRUE = link after import + bool replacetear; // replace the tearline when exporting? + word defnumbtokeep_F; // default number of msgs to keep for an new area + word defdaystokeep_F; // default number of days to keep msgs for a new area + byte fidoarcmailextension; // 0=Arc(0..9), 1=Hex(0..9,A..F), 2=All(0..9,A..Z) + byte uucpgateway; // Gateway AKA nr: 1..10, as index in system AKAs array + char nameseparator; // character to replace spaces with in user names + // when building an e-mail address. + + char origins[2][62]; // the two system origin lines + bool worldwide; // TRUE = system UUCPname is world-reg + byte defgroups_U[16]; // default groups to use for UUCP + char spoolbasedir[80]; // path to the spool directories + dword maxdatlength; // Max. length of .DAT files, before compression + char smarthost[11]; // UUCPname of your smarthost + char uucpname[11]; // system UUCP name + char backbone[51]; // domain name of the backbone + char organization[60]; // system organization line + char domains[6][51]; // system domain names + char comprprg_U[4][80]; // installed compression/decompression programs + byte privmailtype; // type of private mail message base: + // 0=None, 1=*.MSG, 2=Squish, 3=JAM + char privmailpath[80]; // path to the message base + char privmailoption[10][73]; + byte privmailselect[10]; // where to search: 0=From, 1=To, 2=Subj + byte reserved1; + AreafixForwardRecord areafixforward[50]; + UUCPForwardRecord uucpforward[50]; + dword maxsquishmsglen; // max msg length when importing into Squish base + dword maxjammsglen; // max msg length when importing into JAM base + byte defaultcompressor; // default compression to set in new user records: + // 0=ARC, 1=ARJ, 2=LZH, 3=PAK, 4=ZIP, 5=ZOO, 6=RAR + // 7=OP1, 8=GUS, 9=PKT. + bool packedaddresses; // TRUE = build small e-mail addresses + char rescanflagfile[80]; // path to the rescan flag file + char dbridgequeuepath[80]; // path to the d'Bridge dir where to store the queueing files } + char areafixname[11]; // name of the fido areafix + bool killgatednetmail; // TRUE = automatically kill gated netmail + char newsfixname[11]; // name of the UUCP areafix (newsfix) + bool useswapfile; // TRUE = use swapfile + char swapfilepath[80]; // path to the swapfile + byte swapfilesize; // max length of the swapfile in megabytes + bool replyfsc35; // TRUE = create FSC35 reply kludges + bool headerfullname; // TRUE put the full name in the From: field? + bool logdebug; // TRUE = enable all other options + bool logspooltossed; // TRUE = log tossed spool files + bool logfidoextract; // TRUE = log extracted fidonet archives + bool logfidotossed; // TRUE = log tossed fido .PKT files + bool logtranslationFU; // TRUE = log built e-mail addressed + bool logcheckfilter; // TRUE = log accepted / denied new newsgroup names + bool logxfix; // TRUE = log fixed to-address from .X files + bool logcopyheaders; // TRUE = Log headers that were copied from fido netmail/echomail messages + bool logillegalheaders; // TRUE = Log found headers that are not allowed + bool logareafix; // TRUE = Log commands to / replyies from areafix / newsfix + bool logmapapply; // TRUE = Log applied mapping statements + bool lognetmailimport; // TRUE = log all imported netmails + bool logrodeny; // TRUE = log all read-only denied postings in areas + bool logpkteachecho; // TRUE = log each echomail plus length + bool loguucpoutbound; // TRUE = log all created UUCP files + bool logsmtpoutbound; // TRUE = log all created SMTP jobs + bool logexportednetmail; // TRUE = + bool log17, log18, log19, log20, log21; + char copyheadernames[16][30];// names of the e-mail Headers to search for + // without the trailing space! + + byte copyheaderhow[30]; // How to store the copied header: + // 0=Not, 1=Kludge, 2=Text + + char gatewayuser[37]; // user name of the gateway user + bool bounceunknown; // TRUE=bounce undeliverable mail + // FALSE=Write to netmail + + bool bouncesmall; // TRUE=Send only the first approximate 20 lines + byte adminaddrtype; // 0=None, 1=Fido, 2=Usenet + char adminfidoname[37]; // Full name of the administrator, for the Fidonet address + FidoAddrType adminfidoaddr; // Fidonet address of the administrator + char adminuucpaddr[256]; // E-mail address of the administrator + bool adminsendlog; // Send the logfile to the administrator? + bool adminsend2, adminsend3, adminsend4, adminsend5, adminsend6, adminsend7, + adminsend8, adminsend9, adminsend10,adminsend11, adminsend12, adminsend13, + adminsend14,adminsend15,adminsend16; + char timezone[26]; // time zone description + bool copyheaders_FU; // TRUE = Scan and copy headers Fido->Usenet + char mailgrade; // grade letter to use in mail job UUCP filenames + char newsgrade; // grade letter to use in news batch job UUCP filenames + bool timeslicing; // FALSE = Do not detect multitasker + bool netmaildecode; // TRUE = scan and decode files from imported netmail + char netmaildecodepath[80]; // where to store the files + bool privatedecode; // TRUE = scan and decode files from imported private scanned messages + char privatedecodepath[80]; // where to store the files + word maxrmaillinelen; // max len for rmail line in .X file + byte minimumdiskfree; // min MB's free for disk check + char diskfreedrives[27]; // drives to check for disk check + byte old; + byte rmailcorrect; // rmail correction to use + bool gatemsgid; // TRUE = gate Message-ID -> MSGID + bool forcenobitmask; // TRUE = don't put "0" in front of UUCP jobs + char rescanflagfile2[80]; // editor rescan flag file + byte organizationinorigin; // Gate organization -> origin: no, yes, override + bool alwaysmimequoteprint; // TRUE = always use quoted-printable + char smtpforward[51]; // address for dumping mail at ISP + byte maxxpostnewsgroups; // cross-post limit. 255 = allow all + char wildcatmsglockdir[80]; // path to MSGLOCK directory for WildCat conference lock + bool opusdateformat; // TRUE = create *.MSG with Opus date fields + dword maxwildcatmsglen; // max len of a single WildCat message + bool killareafixmsgs; // kill *.MSG with areafix after processing? + byte colors[21]; // color codes for each of the elements +} ConfigRecord; + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +//==== END OF FILE ========================================================== diff --git a/goldlib/gcfg/gs_xbbs.h b/goldlib/gcfg/gs_xbbs.h new file mode 100644 index 0000000..038fd70 --- /dev/null +++ b/goldlib/gcfg/gs_xbbs.h @@ -0,0 +1,642 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ + +#define SMALLEST_MSG_SIZE_FOR_PACKING 384 + +#define MAX_MSG_AREAS 10240 +#define MAX_FIL_AREAS 10240 + +/* bbs.attribs */ + #define B_LOGALLHELP 0x00000001 + #define B_PREREGISTERED 0x00000002 + #define B_NOPRETTY 0x00000004 + #define B_INTL 0x00000008 + #define B_NOHAPPY 0x00000010 + #define B_ANSINEWS 0x00000020 + #define B_NODUPENUMS 0x00000040 + #define B_COLOR 0x00000080 + #define B_HIGHASCII 0x00000100 + #define B_PAUSE 0x00000200 + #define B_CLEAR 0x00000400 + #define B_COLD 0x00000800 + #define B_WIDTH 0x00001000 + #define B_LENGTH 0x00002000 + #define B_SHOW 0x00004000 + #define B_PHONE 0x00008000 + #define B_ADDRESS 0x00010000 + #define B_HANDLE 0x00020000 + #define B_PASSWORD 0x00040000 + #define B_INTERESTS 0x00080000 + #define B_COMPUTERS 0x00100000 + #define B_NO_NEW_EDIT 0x00200000 + #define B_LOGONQUOTE 0x00400000 + #define B_COMPRESS 0x00800000 + #define B_LOGOFFQUOTE 0x01000000 + #define B_LOGOFFMSG 0x02000000 + #define B_FIRSTLOGMSG 0x04000000 + #define B_FIRSTLOGCALLBK 0x08000000 + #define B_ALWAYSCALLBACK 0x10000000 + #define B_AUTOPASSWORDS 0x20000000 + #define B_FOLLOWBBS 0x40000000 + #define B_SYSOPIN 0x80000000 + #define BIT_1 0x00000001 + #define BIT_2 0x00000002 + #define BIT_3 0x00000004 + #define BIT_4 0x00000008 + #define BIT_5 0x00000010 + #define BIT_6 0x00000020 + #define BIT_7 0x00000040 + #define BIT_8 0x00000080 + #define BIT_9 0x00000100 + #define BIT_10 0x00000200 + #define BIT_11 0x00000400 + #define BIT_12 0x00000800 + #define BIT_13 0x00001000 + #define BIT_14 0x00002000 + #define BIT_15 0x00004000 + #define BIT_16 0x00008000 + #define BIT_17 0x00010000 + #define BIT_18 0x00020000 + #define BIT_19 0x00040000 + #define BIT_20 0x00080000 + #define BIT_21 0x00100000 + #define BIT_22 0x00200000 + #define BIT_23 0x00400000 + #define BIT_24 0x00800000 + #define BIT_25 0x01000000 + #define BIT_26 0x02000000 + #define BIT_27 0x04000000 + #define BIT_28 0x08000000 + #define BIT_29 0x10000000 + #define BIT_30 0x20000000 + #define BIT_31 0x40000000 + #define BIT_32 0x80000000 + +/* bbs.attribs2 */ + #define B2_ANSI 0x00000001 + #define B2_USEVER7 0x00000002 + #define B2_AUTOVERIFY 0x00000004 + #define B2_FTNTOALL 0x00000008 + #define B2_MINIMIZEBBS 0x00000010 + #define B2_SMALLFONT 0x00000020 + #define B2_DATAPHONE 0x00000040 + #define B2_FAXPHONE 0x00000080 + #define B2_BUSPHONE 0x00000100 + #define B2_ADDRESS2 0x00000200 + #define B2_ADDRESS3 0x00000400 + #define B2_CITY 0x00000800 + #define B2_STATE 0x00001000 + #define B2_ZIPCODE 0x00002000 + #define B2_USEHANDLE 0x00004000 + #define B2_NOVIDWHENMIN 0x00008000 + #define B2_ABORTREXX 0x00010000 + #define B2_NOBBSSCREEN 0x00020000 + #define B2_CANFASTLOGIN 0x00040000 + #define B2_ADDRESS1REQ 0x00080000 + #define B2_ADDRESS2REQ 0x00100000 + #define B2_ADDRESS3REQ 0x00200000 + #define B2_CITYREQ 0x00400000 + #define B2_STATEREQ 0x00800000 + #define B2_ZIPREQ 0x01000000 + #define B2_HOMEREQ 0x02000000 + #define B2_DATAREQ 0x04000000 + #define B2_BUSINESSREQ 0x08000000 + #define B2_FAXREQ 0x10000000 + #define B2_NOREGTXTINMSG 0x20000000 //JM960109 + #define B2_NUMONLYPHONE 0x40000000 //JM960109 + #define B2_ALWAYSSAVEINI 0x80000000 //JM960109 + +/* bbs.attribs3 */ + #define B3_UNVERIFIED_NEWMENU 0x00000001 + #define B3_NO_NEWUSERALIAS 0x00000002 + #define B3_DROP_CARRIER_ON_TIMEUP 0x00000004 + #define B3_BBS_WATCH_THREAD 0x00000008 + #define B3_NO_TELNET_TIMEOUT 0x00000010 + #define B3_ENABLE_ACCOUNTING 0x00000020 + #define B3_ENABLE_EXCEPTIONS 0x00000040 + #define B3_FLUSH_SYSTEM 0x00000080 + #define B3_FLUSH_SYSTEM_LOG 0x00000100 + #define B3_NOSTATUS 0x00000200 + #define B3_STARTFTP 0x00000400 + #define B3_NOCHAT 0x00000800 + #define B3_SYSTEM_INFO 0x00001000 + #define B3_BBS_INFO 0x00002000 + #define B3_SYSOP_MAIL 0x00004000 + #define B3_FULL_LANG_BUF 0x00008000 + #define B3_ALLOW_KILL 0x00010000 + #define B3_POP_KEEP 0x00020000 + + +/* user attribs */ + #define U_ANSI 0x00000001 + #define U_COLOR 0x00000002 + #define U_HIGHASCII 0x00000004 + #define U_NOMORE 0x00000008 + #define U_NOCLEAR 0x00000010 + #define U_COLD 0x00000020 + #define U_NOSHOWADDRESS 0x00000040 + #define U_NOSHOWPHONE 0x00000080 + #define U_NOSHOWREAL 0x00000100 + #define U_NOKILL 0x00000200 + #define U_DELETED 0x00000400 + #define U_EXPERT 0x00000800 + #define U_TWIT 0x00001000 + #define U_NEWFILES 0x00002000 + #define U_NEWMSGS 0x00004000 + #define U_DLNEWMSGS 0x00008000 + #define U_DLNEWFILELIST 0x00010000 + #define U_SEENEWS 0x00020000 + #define U_ASKDL 0x00040000 + #define U_NOVICE 0x00080000 + #define U_NOROLL 0x00100000 + #define U_POINTONLY 0x00200000 + #define U_LOCKEDOUT 0x00400000 + #define U_AVAILABLE 0x00800000 + #define U_LISTPROTECTED 0x01000000 + #define U_MISCNEWSOK 0x02000000 + #define U_LIMITFLIST 0x04000000 + #define U_EBCDIC 0x08000000 + #define U_VERIFIED 0x10000000 // user call back verified, turn this off, they get + +// verified again.. (if BBS verifies) + #define U_ANSITE2 0x20000000 + #define U_RIPSCRIPT 0x40000000 + #define U_AVATAR 0x80000000 + +/* user attribs2*/ + #define U2_FSE 0x00000001 + #define U2_OFF_AFTER_MAIL 0x00000002 + #define U2_MONITOR_MAIL 0x00000004 + #define U2_INT_NEW_FILES 0x00000008 + #define U2_INC_BULLETS 0x00000010 + #define U2_INC_WELCOME 0x00000020 + #define U2_DEFAULT_QWK 0x00000040 + #define U2_DEFAULT_FIDO 0x00000080 + #define U2_DEFAULT_TEXT 0x00000100 + #define U2_DEFAULT_BLUE 0x00000200 + #define U2_AVTANS 0x00000400 + #define U2_8DOT3 0x00000800 //JM940610 + #define U2_NOSHOWBDAY 0x00001000 + #define U2_ALLOW_NET_ATTACH 0x00002000 + #define U2_ALLOW_LOCAL_ATTACH 0x00004000 + #define U2_NO_ALT_ED 0x00008000 + #define U2_POP_SCAN 0x00010000 + #define U2_KEEP_SEENBY 0x00020000 + #define U2_ALLOW_KILL 0x00040000 + #define U2_POP_KEEP 0x00080000 + + +/* Used by string_input */ +/* flags */ + #define STRF_UCASE 0x00000001 + #define STRF_LCASE 0x00000002 + #define STRF_REQUIRED 0x00000004 + #define STRF_NOECHO 0x00000008 + #define STRF_ENCRYPT 0x00000010 + #define STRF_HOT 0x00000020 + #define STRF_EDIT 0x00000040 + #define STRF_PRETTY 0x00000080 + #define STRF_MUSTHOT 0x00000100 + #define STRF_NEAT 0x00000200 + #define STRF_NOHELP 0x00000400 + #define STRF_NOQUE 0x00000800 + #define STRF_NOQUEONE 0x00001000 + #define STRF_CHATCLNT 0x00002000 + #define STRF_NOTIMECHECK 0x00004000 + #define STRF_NOANSIINCHECK 0x00008000 + #define STRF_ENTEROK 0x00010000 + #define STRF_ALWAYSCHAT 0x00020000 //JM960202 + #define STRF_NOFIRSTPROMPT 0x00040000 //JM960202 + +/* types */ + #define STRT_ALPHA 1 + #define STRT_NUMERIC 2 + #define STRT_ALPHANUMERIC 3 + #define STRT_HEX 4 + #define STRT_FILENAME 5 + #define STRT_FILESPEC 6 + #define STRT_ALL 7 + #define STRT_ANY 8 + #define STRT_YN 9 + #define STRT_MULTFILES 10 + #define STRT_MULTSPECS 11 + #define STRT_YNQ 12 + #define STRT_YNQS 13 + #define STRT_JUSTFILE 14 + #define STRT_MULTJUST 15 + #define STRT_TELEPHONE 16 + #define STRT_YNNUM 17 + #define STRT_TELEPHONENUM 18 //JM960109 + +// Input flags (input, as in do_more, wait_inkey, etc) + #define IF_RETURNONERROR 0x00000001 // return lost carrier, or timeout + #define IF_NOQUEUE 0x00000002 + #define IF_NOTIMECHECK 0x00000004 + #define SINGLE_INPUT 0x00000008 + #define PASSWORD_PROMPT 0x00000010 + +// Input return codes (along with TIMEOUT and LOSTCARRIER) + #define IRC_NOTIMELEFT -3 + #define IRC_LOCKEDOUT -4 + #define IRC_MORON -5 + #define IRC_REPROMPT -6 + #define IRC_ENDSYSOPCHAT -7 + #define IRC_CHATWAITING -8 + #define IRC_CHATDOWN -9 + #define IRC_IDLETIMEOUT -10 + +#if 0 +struct _msgarea + { + char *name; + char *descr; + char *forceto; + char *origin; + char *path; + char *usenettag; + int minage; + int maxage; + unsigned long r_security1; + unsigned long r_security2; + unsigned long r_flags1; + unsigned long r_flags2; + unsigned long w_security1; + unsigned long w_security2; + unsigned long w_flags1; + unsigned long w_flags2; + unsigned long s_security1; + unsigned long s_security2; + unsigned long s_flags1; + unsigned long s_flags2; + unsigned long areaflags; + unsigned long *groupnum; + PADDR addr; + PADDR feeds; + unsigned int number; + LONG TimeFactor; + char *password; + struct _msgarea *next; + struct _msgarea *prior; + }; + +typedef struct _msgarea MSGAREA, *PMSGAREA; //JM931019 +#endif + +/*----------------------------------------------------------*/ +/* Message area flags (areaflags) */ +/*----------------------------------------------------------*/ + #define M_NOORIG 0x00000001 /* No Origin or tear */ + #define M_ANSI 0x00000002 /* Allow Ansi Messages */ + #define M_PRIVATE 0x00000004 /* Force Msgs Public */ + #define M_PUBLIC 0x00000008 /* Force Msgs Private */ + #define M_ECHO 0x00000010 /* Is a Echomail */ + #define M_NET 0x00000020 /* It a Netmail area */ + #define M_MCI 0x00000040 /* Allows MCI Commands */ + #define M_ANON 0x00000080 /* All Msgs Annon. */ + #define M_REAL 0x00000100 /* Requires Real Name */ + #define M_ASSOC 0x00000200 /* Msg area allows assoc */ + #define M_FORCE 0x00000400 /* Always force */ + #define M_COMPRESS 0x00000800 /* Allow LZSS comp here */ + #define M_GROUP 0x00001000 /* groupmail */ + #define M_USENET 0x00002000 /* usenet conference */ + #define M_QWK 0x00004000 /* qwk conference */ + #define M_SQUISH 0x00008000 /* Squish MSG Base */ + #define M_EMAIL 0x00010000 /* Internet E-Mail */ + #define M_FIDO 0x00100000 /* Star . msg Format */ + #define M_JAM 0x00200000 /* JAM msg Format */ + + +struct _filearea + { + char *name; + char *descr; + int minage; + int maxage; + unsigned long r_security1; + unsigned long r_security2; + unsigned long r_flags1; + unsigned long r_flags2; + unsigned long w_security1; + unsigned long w_security2; + unsigned long w_flags1; + unsigned long w_flags2; + unsigned long s_security1; + unsigned long s_security2; + unsigned long s_flags1; + unsigned long s_flags2; + unsigned long areaflags; + unsigned long groupnum[256]; + int cost_per_k; + unsigned int number; + char *upath; + char *dpath; + char *password; + char *ftpname; + LONG TimeFactor; + struct _filearea *next; + struct _filearea *prior; + }; + + +typedef struct _filearea FILEAREA, *PFILEAREA; //JM931019 + +/*-----------------------------------------------------------*/ +/* File area flags (areaflags) */ +/*-----------------------------------------------------------*/ + #define F_FREE 0x00000001 /* */ + #define F_NOUP 0x00000002 /* */ + #define F_NODOWN 0x00000004 /* */ + #define F_LEECH 0x00000008 /* */ + #define F_DOWNBACK 0x00000010 /* */ + #define F_UPBACK 0x00000020 /* */ + #define F_CHARGE 0x00000040 /* */ + #define F_CANTLIST 0x00000080 // Uploads not listable + #define F_CANTDL 0x00000100 // Uploads not downloadable + #define F_NOFBBS 0x00000200 /* no FILES.BBS at all */ + #define F_COMMONONLY 0x00000400 /* use only common FILES.BBS */ + #define F_UPBLIND 0x00000800 // UL get desc. afterwards + #define F_COPYFILE 0x00001000 // copy download from CD to HD + #define F_NODIR 0x00002000 // copy download from CD to HD + #define F_NOCOMMON 0x00004000 // copy download from CD to HD + #define F_NOSEARCH 0x00008000 // copy download from CD to HD + + +typedef struct _libarea + { + char *name; + char *descr; + int minage; + int maxage; + unsigned long r_security1; + unsigned long r_security2; + unsigned long r_flags1; + unsigned long r_flags2; + unsigned long w_security1; + unsigned long w_security2; + unsigned long w_flags1; + unsigned long w_flags2; + unsigned long s_security1; + unsigned long s_security2; + unsigned long s_flags1; + unsigned long s_flags2; + unsigned long areaflags; + unsigned int number; + char *path; + char *password; + struct _libarea *next; + struct _libarea *prior; + } LIBAREA, *PLIBAREA; + + +/*----------------------------------------------------------*/ +/* Library area flags (areaflags) */ +/*----------------------------------------------------------*/ + #define L_ANSIONLY 0x00000001 /* */ +// Group structure + + +typedef struct _GROUP + { + PSZ Name; + PSZ Password; + LONG Number; + ULONG Flags; + ULONG MinutesPerDay; + ULONG MinutesPerCall; + ULONG DaysBeforeExpiration; + LONG ExpireToGroup; + ULONG MaxBankTime; + ULONG MaxUKPerDay; + ULONG MaxDKPerDay; + ULONG ULDLRatio; + ULONG RatioCredit; + ULONG Security1; + ULONG Security2; + ULONG Flags1; + ULONG Flags2; + int CreditsPerUnit; + int CreditsPerUnitPeek; + int FreeCreditsDay; + int FreeCreditsWeek; + int FreeCreditsMonth; + int FreeCreditsPercentage; + int MaxDebt; + LONG GroupIfBroke; + USHORT DaysBetweenPWChange; + PSZ MainMenu; + PSZ MainMenuUnVerified; + struct _GROUP *Next; + struct _GROUP *Prev; + } GROUP, *PGROUP; + + +// Group Flags + #define G_FLAGSOVERWRITE 0x00000001 // if not overwrite, then accumulate + #define G_SECOVERWRITE 0x00000002 // if not overwrite, then ignore + #define G_RATIOONBYTES 0x00000004 // if not bytes, then files + #define G_TIMEOVERWRITE 0x00000008 // if not overwrite, then ignore +///// New File Search Info + + +typedef struct _user_info + { + CHAR name[36]; + CHAR handle[36]; + CHAR address[60]; + CHAR address1[60]; + CHAR address2[60]; + CHAR city[20]; + CHAR state[5]; + CHAR zipcode[10]; + CHAR home_phone[21]; + CHAR data_phone[21]; + CHAR fax_phone[21]; + CHAR bus_phone[21]; + CHAR interests[78]; + CHAR SysOpComment[78]; + USHORT BankTime; + USHORT computer_type; + ULONG userid; + USHORT pointid; + time_t initial_logon; + time_t expires; + time_t last_logon; + time_t logon_today; + USHORT birthyear; + UCHAR birthmonth; + UCHAR birthday; + UCHAR Gender; + LONG credit; + LONG minlimit; // what exactly is this? + LONG Group; // must match Group->Number + ULONG CurrLastRead; // last Read for current msg area + ULONG time_today; // seconds used today + ULONG time_per_day; // minutes allowed per day + ULONG time_per_call; // minutes per call 0=just per day + ULONG numcalls; + ULONG ulnum; // files uploaded (ever) + ULONG dlnum; // files downloaded (ever) + ULONG ulk; // UL in K (ever) + ULONG dlk; // DL in K (ever) + ULONG uktoday; // UL in K Today + ULONG dktoday; // DL in K Today + ULONG ukperday; // Max UL K Per day + ULONG dkperday; // Max DL K Per day + ULONG numposts; + ULONG security1; + ULONG security2; + ULONG flags1; + ULONG flags2; + ULONG attribs; + ULONG attribs2; + USHORT length; + USHORT width; + USHORT lastmsgarea; + USHORT lastfilearea; + UCHAR lastprotocol; + UCHAR lastarchiver; + LONG forsysop; + UCHAR interface; + UCHAR exp; + USHORT leech_percent; + USHORT MaxBankTime; + SHORT TimeCredit; // can be negative or positive + SHORT CallsToday; + LONG TotalMinsEver; + LONG NetmailDebits; + time_t LastPWChange; + time_t LastListedNewFiles; //JM940822 + ULONG FileKCredit; + CHAR UnixId[8]; + CHAR Country[24]; + USHORT weight; + CHAR height[5]; + CHAR Pref; + CHAR LangIdent[4]; // permanent language identifier + USHORT MailDLsToday; //JM960118 + USHORT UsesOLMail; //JM960119 + CHAR POPPassword[16]; + CHAR POPLogin[16]; + CHAR POPServer[128]; + CHAR NoLongerUsed[22]; + UCHAR _UnUsedOldTags[256]; + ULONG PasswordCRC; + ULONG PasswordCRC2; + USHORT Max_Mail_Pkt; + CHAR ReAsked; // TRUE if reasked question were answered + USHORT timeout; + USHORT CurrMsgGroup; + USHORT CurrFileGroup; + CHAR EMail[37]; + CHAR FidoMail[32]; + } USER, *PUSER; + + +typedef struct _xmsg + { + CHAR MajorVersion; + CHAR MinorVersion; + USHORT StructLen; + CHAR from[60]; + CHAR to[60]; + CHAR subj[70]; + CHAR date[35]; /* */ + CHAR indate[4]; /* import date (YMD(null)) */ + ULONG msgnum; + ULONG timesread; + time_t timerecv; + ULONG length; /* Length of message */ + LONG start; /* Starting postition in text file */ + ULONG OrigMsg; + ULONG miscdatlen; + ULONG miscdatstart; + USHORT o_zone; + USHORT o_net; + USHORT o_node; + USHORT o_point; + USHORT d_zone; + USHORT d_net; /* Destination network number */ + USHORT d_node; /* Destination node */ + USHORT d_point; + USHORT cost; /* Unit cost charged to send the message */ + USHORT fflags; /* Attribute (behavior) of the message */ + USHORT xflags; /* Extra attributes */ + ULONG bflags; + ULONG cflags; + } XMSG, *PXMSG; + + +/*----------------------------------------------------*/ +/* FIDO Message attributes (fflags) */ +/*----------------------------------------------------*/ + #define MSGPRIVATE 0x0001 /* private message, */ + #define MSGCRASH 0x0002 /* accept for forwarding */ + #define MSGREAD 0x0004 /* read by addressee */ + #define MSGSENT 0x0008 /* sent OK (remote) */ + #define MSGFILE 0x0010 /* file attached to msg */ + #define MSGFWD 0x0020 /* being forwarded */ + #define MSGORPHAN 0x0040 /* unknown dest node */ + #define MSGKILL 0x0080 /* kill after mailing */ + #define MSGLOCAL 0x0100 /* FidoNet vs. local */ + #define MSGXX1 0x0200 /* */ + #define MSGXX2 0x0400 /* STRIPPED by FidoNet */ + #define MSGFRQ 0x0800 /* file request */ + #define MSGRRQ 0x1000 /* receipt requested */ + #define MSGCPT 0x2000 /* is a return receipt */ + #define MSGARQ 0x4000 /* audit trail requested */ + #define MSGURQ 0x8000 /* update request */ + +/*----------------------------------------------------*/ +/*----------------------------------------------------*/ +/* Adept Message attributes (xflags) */ +/*----------------------------------------------------*/ + #define MSGDELETED 0x0001 /* deleted message, 0000 0000 0000 0001*/ + #define MSGANON 0x0002 /* anonymous message 0000 0000 0000 0010*/ + #define MSGECHO 0x0004 /* unmoved echo message 0000 0000 0000 0100*/ + #define MSGNET 0x0008 /* unmoved net message 0000 0000 0000 1000*/ + #define MSGHOLD 0x0010 /* file attached to msg 0000 0000 0001 0000*/ + #define MSGHOST 0x0020 /* being forwarded 0000 0000 0010 0000*/ + #define MSGSCANNED 0x0040 /* fidonet scanned 0000 0000 0100 0000*/ + #define MSGKEEP 0x0080 /* don't delete 0000 0000 1000 0000*/ + #define MSGTREATED 0x0100 /* soft cr's & lf's removed 0000 0001 0000 0000*/ + #define MSGPACKED 0x0200 /* message LZSS compressed 0000 0010 0000 0000*/ + #define MSGGSCAN 0x0400 /* groupmail scanned 0000 0100 0000 0000*/ + #define MSGRSCAN 0x0800 /* rfc0822 scanned 0000 1000 0000 0000*/ +/*#define 0x1000 0001 0000 0000 0000*/ +/*#define 0x2000 0010 0000 0000 0000*/ + #define MSGARCHIVED 0x4000 /* 0100 0000 0000 0000*/ + #define MSGTAGGED 0x8000 /* used by offline readers 1000 0000 0000 0000*/ +/*----------------------------------------------------*/ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gs_xmail.h b/goldlib/gcfg/gs_xmail.h new file mode 100644 index 0000000..c2e7337 --- /dev/null +++ b/goldlib/gcfg/gs_xmail.h @@ -0,0 +1,107 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (‘) 1993 Roger Kirchhoff & Stefan Graf +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// File structures for xMail v.1.00 +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + +// ------------------------------------------------------------------ + +enum MsgBaseType { + FmtHudson, + FmtMsg, + FmtPassThrough, + FmtSquish, + FmtJam +}; + + +// ------------------------------------------------------------------ + +enum MailTypeDef { + Echomail, + Netmail, + Localmail, + Newmail +}; + + +// ------------------------------------------------------------------ + +struct AddressRec { + + unsigned short Zone; + unsigned short Net; + unsigned short Node; + unsigned short Point; + char Domain[21]; +}; + + +// ------------------------------------------------------------------ +// Structure of AREAS.XM + +struct EchoAreaRec { + + char Name[41]; // Area Name + char Descr[61]; // Description + unsigned char MailType; // (MailTypeDef) local, netmail or what + unsigned char StoreType; // (MsgBaseType) + char MsgDirectory[61]; // ... and the corresponding directory + unsigned short ReadSecurity; // Read access level + unsigned short WriteSecurity; // Write access level + char OriginLine[61]; // Origin line for this echo + AddressRec AreaAddress; // Adress of sender for this echo + unsigned char ConferenceNr; // The conference this echo belongs to. If 0 the echo has NO conference + unsigned short maxdays; + unsigned short maxrecv; + unsigned short maxcount; + unsigned short totalimp; + unsigned short totalexp; // Purge info + long totalimpL; + long totalexpL; // total # of msgs imported/exported in this echo + unsigned char BasePathStrip; // Don't import PATH line to base + unsigned char ExportPathStrip; // Strip PATH line for downlinks + unsigned char BaseSeenStrip; // Don't import SEEN-BY to base + unsigned char ExportSeenStrip; // Strip SEEN-BY for downlinks + unsigned short AbsCosts; + unsigned short RelCosts; // The cost for each mail in this echo + long LastActionDate; // Last date something happened in this echo + unsigned char NeverRemove; // Never remove this echo automatically + unsigned short MaxDupes; // Maximum nr. of Dupes + unsigned char SkipPathCheck; + unsigned char Dummy[106]; // unused +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxareas.cpp b/goldlib/gcfg/gxareas.cpp new file mode 100644 index 0000000..11d5671 --- /dev/null +++ b/goldlib/gcfg/gxareas.cpp @@ -0,0 +1,91 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from an AREAS.BBS file (any type!) +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read one or more AREAS.BBS files + +void gareafile::ReadAreasBBS(char* tag) { + + AreaCfg aa; + int echos; + char origin[80], options[80]; + char* ptr; + char* echoid=NULL; + char* path=NULL; + char* desc=NULL; + + *origin = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + + // Read each AREAS.BBS + while(ptr) { + if(*ptr != '-') { + GetAreasBBS(ptr, origin, options); + echos = echolist.Echos(); + for(int n=0; n 200) and (aa.board < 501)) + aa.msgbase = GMB_GOLDBASE; + else if(*path == '$') { + aa.msgbase = GMB_SQUISH; + adjustpath(path+1); + aa.setpath(path+1); + } + else if(*path == '!') { + aa.msgbase = GMB_JAM; + adjustpath(path+1); + aa.setpath(path+1); + } + else { + aa.msgbase = fidomsgtype; + adjustpath(path); + aa.setpath(path); + } + aa.setdesc(desc); + aa.setechoid(echoid); + aa.setorigin(origin); + AddNewArea(aa); + } + } + ptr = strtok(NULL, " \t"); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxcrash.cpp b/goldlib/gcfg/gxcrash.cpp new file mode 100644 index 0000000..35cf8c2 --- /dev/null +++ b/goldlib/gcfg/gxcrash.cpp @@ -0,0 +1,214 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Crashmail II +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +bool gareafile::jbstrcpy(char *dest, char *src, size_t maxlen, size_t *jbc) { + size_t d=0; + size_t stopchar1,stopchar2; + size_t jbcpos; + + jbcpos= *jbc; + + while(isspace(src[jbcpos])) jbcpos++; + + if(src[jbcpos]=='\"') { + jbcpos++; + stopchar1='\"'; + stopchar2=0; + } + else { + stopchar1=' '; + stopchar2=9; + } + + while(src[jbcpos]!=stopchar1 and src[jbcpos]!=stopchar2 and src[jbcpos]!='\n' and src[jbcpos]!=NUL and d +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read D'Bridge 1.30 + +void gareafile::ReadDB130(char* tag, char* dbpath) { + + AreaCfg aa; + DB130_AA1 AA1; + DB130_AA2 AA2; + FILE *fp1, *fp2; + Path file1, file2; + + MakePathname(file1, dbpath, "dbridge.aa1"); + MakePathname(file2, dbpath, "dbridge.aa2"); + + fp1 = fsopen(file1, "rb", sharemode); + if(fp1) { + setvbuf(fp1, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file1 << endl; + + fp2 = fsopen(file2, "rb", sharemode); + if(fp2) { + setvbuf(fp2, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file2 << endl; + + while(fread(&AA1, sizeof(DB130_AA1), 1, fp1) == 1) { + + fread(&AA2, sizeof(DB130_AA2), 1, fp2); + + if(AA1.allocated and strchr("QFqf", AA2.msgbase)) { + aa.reset(); + switch(toupper(AA2.msgbase)) { + case 'Q': + aa.msgbase = GMB_HUDSON; + aa.board = AA2.board; + break; + case 'F': + aa.msgbase = fidomsgtype; + aa.setpath(STRNP2C(AA2.path)); + break; + } + switch(toupper(AA2.kind)) { + case 'N': + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case 'E': + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + default: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + STRNP2C(AA2.origin); + aa.setorigin(AA2.origin); + aa.attr.pvt(AA2.ispvt); + aa.groupid = (char)AA2.group; + aa.setechoid(STRNP2C(AA1.echoid)); + aa.setdesc(STRNP2C(AA2.desc)); + aa.aka = AA2.addr; + AddNewArea(aa); + } + } + + fclose(fp2); + } + + fclose(fp1); + } +} + + +// ------------------------------------------------------------------ +// Read D'Bridge B1046 + +void gareafile::ReadDB1046(char* file, char* tag) { + + AreaCfg aa; + DB1046_ADF* ADF = (DB1046_ADF*)throw_calloc(1, sizeof(DB1046_ADF)); + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(ADF, sizeof(DB1046_ADF), 1, fp) == 1) { + if(ADF->allocated and strchr("QFqf", ADF->msgbase)) { + aa.reset(); + switch(toupper(ADF->msgbase)) { + case 'Q': + aa.msgbase = GMB_HUDSON; + aa.board = ADF->board; + break; + case 'F': + aa.msgbase = fidomsgtype; + aa.setpath(STRNP2C(ADF->path)); + break; + } + switch(toupper(ADF->kind)) { + case 'N': + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case 'E': + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + default: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + STRNP2C(ADF->origin); + aa.setorigin(ADF->origin); + aa.attr.pvt(ADF->ispvt); + aa.groupid = (char)ADF->group; + aa.setechoid(STRNP2C(ADF->echoid)); + aa.setdesc(STRNP2C(ADF->desc)); + aa.aka = ADF->addr; + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_free(ADF); +} + + +// ------------------------------------------------------------------ +// Read D'Bridge B1047.A22 and B1047.A27+ + +void gareafile::ReadDB1047A22(char* file, int reclen, char* tag) { + + AreaCfg aa; + FILE* fp; + DB1047A22_ADF* ADF; + + ADF = (DB1047A22_ADF *)throw_malloc(reclen); + if(ADF) { + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(ADF, reclen, 1, fp) == 1) { + if(ADF->allocated and strchr("QFqf", ADF->msgbase)) { + aa.reset(); + switch(toupper(ADF->msgbase)) { + case 'Q': + aa.msgbase = GMB_HUDSON; + aa.board = ADF->board; + break; + case 'F': + aa.msgbase = fidomsgtype; + aa.setpath(STRNP2C(ADF->path)); + break; + } + switch(toupper(ADF->kind)) { + case 'N': + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case 'E': + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + default: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + STRNP2C(ADF->origin); + aa.setorigin(ADF->origin); + aa.attr.pvt(ADF->ispvt); + aa.groupid = (char)ADF->group; + aa.setechoid(STRNP2C(ADF->echoid)); + aa.setdesc(STRNP2C(ADF->desc)); + aa.aka = ADF->addr; + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_free(ADF); + } +} + + +// ------------------------------------------------------------------ +// Read D'Bridge B2011 + +void gareafile::ReadDB2011(char* file, int reclen, char* tag) { + + AreaCfg aa; + FILE* fp; + DB2011_ADF* ADF; + + ADF = (DB2011_ADF *)throw_malloc(reclen); + if(ADF) { + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(ADF, reclen, 1, fp) == 1) { + if(ADF->allocated and strchr("QFqf", ADF->msgbase)) { + aa.reset(); + switch(toupper(ADF->msgbase)) { + case 'Q': + if(ADF->board < 1 or ADF->board > 200) + continue; // Bad area number + aa.msgbase = GMB_HUDSON; + aa.board = ADF->board; + break; + case 'F': + aa.msgbase = fidomsgtype; + aa.setpath(STRNP2C(ADF->path)); + break; + } + switch(toupper(ADF->kind)) { + case 'N': + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case 'E': + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + default: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + STRNP2C(ADF->origin); + aa.setorigin(ADF->origin); + aa.attr.pvt(ADF->ispvt); + aa.groupid = (char)ADF->group; + aa.setechoid(STRNP2C(ADF->echoid)); + aa.setdesc(STRNP2C(ADF->desc)); + aa.aka = ADF->addr; + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_free(ADF); + } +} + + +// ------------------------------------------------------------------ +// Read D'Bridge areas, various versions... + +void gareafile::ReadDBridge(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + int line; + char buf[256], type, options[80]; + Path dbpath, file, badecho, netpath; + + *dbpath = NUL; + strcpy(options, tag); + + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(dbpath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*dbpath == NUL) { + ptr = getenv("DBRIDGE"); + if(ptr == NULL) + ptr = getenv("DB"); + if(ptr) + AddBackslash(strcpy(dbpath, ptr)); + } + if(*dbpath == NUL) + strcpy(dbpath, areapath); + + MakePathname(file, dbpath, "dbridge.prm"); + + fp = fsopen(file, "rt", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + // Read netmail storage method etc + for(line=1; line <= 2; line++) + fgets(buf, 255, fp); + type = (char)toupper(*buf); + + // Fido-style netmail path + line++; + fgets(buf, 255, fp); + strtrim(buf); + strcpy(netpath, buf); + + // BADECHO area + for(; line <= 8; line++) + fgets(buf, 255, fp); + strtrim(buf); + strcpy(badecho, buf); + + // Hudson path + for(; line <= 11; line++) + fgets(buf, 255, fp); + strtrim(buf); + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(buf)); + + // Primary address + for(; line <= 15; line++) + fgets(buf, 255, fp); + strtrim(buf); + CfgAddress(buf); + + // Username + for(; line <= 17; line++) + fgets(buf, 255, fp); + strtrim(buf); + //CfgUsername(buf); + + // Hudson netmail board + for(; line <= 20; line++) // NOTE: was 17 in older versions + fgets(buf, 255, fp); + + // Address/misc field + if(type == 'F' or type == 'Q') { + aa.reset(); + aa.type = GMB_NET; + aa.attr = attribsnet; + if(type == 'F') { + aa.msgbase = fidomsgtype; + aa.setpath(strbtrim(netpath)); + } + else if(type == 'Q') { + strtrim(buf); + aa.msgbase = GMB_HUDSON; + aa.board = atoi(buf+50); + } + aa.setdesc("D'Bridge Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + strbtrim(badecho); + if(*badecho) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.setpath(badecho); + aa.setdesc("D'Bridge Bad Messages"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + fclose(fp); + } + + // Read the areafile from the correct version + MakePathname(file, dbpath, "dbridge.adf"); + if(fexist(file)) { + long size = GetFilesize(file); + if(size != -1L) { + if(striinc("-2011", options)) + ReadDB2011(file, sizeof(DB2011_ADF), options); + else if(striinc("-1047A27", options)) + ReadDB1047A22(file, sizeof(DB1047A27_ADF), options); + else if(striinc("-1047A22", options)) + ReadDB1047A22(file, sizeof(DB1047A22_ADF), options); + else if(striinc("-1046", options)) + ReadDB1046(file, options); + else if((size % sizeof(DB2011_ADF)) == 0) + ReadDB2011(file, sizeof(DB2011_ADF), options); + else if((size % sizeof(DB1047A27_ADF)) == 0) + ReadDB1047A22(file, sizeof(DB1047A27_ADF), options); + else if((size % sizeof(DB1047A22_ADF)) == 0) + ReadDB1047A22(file, sizeof(DB1047A22_ADF), options); + else if((size % sizeof(DB1046_ADF)) == 0) + ReadDB1046(file, options); + } + } + else if(fexist(AddPath(dbpath, "DBRIDGE.AA1"))) { + ReadDB130(options, dbpath); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxdutch.cpp b/goldlib/gcfg/gxdutch.cpp new file mode 100644 index 0000000..c9c5ae3 --- /dev/null +++ b/goldlib/gcfg/gxdutch.cpp @@ -0,0 +1,99 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Dutchie 2.9x +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read Dutchie DUTCHIE.ARE + +void gareafile::ReadDutchie(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + char* ptr2; + Path dupath, file; + char buf[256], options[80]; + + *dupath = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(dupath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*dupath == NUL) { + ptr = getenv("DUTCHIE"); + if(ptr) + AddBackslash(strcpy(dupath, ptr)); + } + if(*dupath == NUL) + strcpy(dupath, areapath); + + MakePathname(file, dupath, "dutchie.are"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fgets(buf, 255, fp)) { + + ptr = strbtrim(buf); + if(*ptr != ';' and *ptr != '-' and strnicmp(ptr, "PASSTHRU", 8) and *ptr != '\x1A' and *ptr) { + + aa.reset(); + aa.msgbase = GMB_FTS1; + ptr = strtok(ptr, " \t"); // Get path + aa.setpath(ptr); + ptr = strtok(NULL, " \t"); // Get description + aa.setdesc(ptr); + strchg(aa.desc, '_', ' '); + aa.type = GMB_ECHO; + aa.attr = attribsecho; + ptr2 = strtok(NULL, " \t"); // Skip flags field + ptr = strtok(NULL, " \t"); // Get echoid + if(ptr == NULL) + ptr = ptr2; // Echoid field missing - use string in flags field + aa.setechoid(strbtrim(ptr)); + AddNewArea(aa); + } + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxezy102.cpp b/goldlib/gcfg/gxezy102.cpp new file mode 100644 index 0000000..b3f5d55 --- /dev/null +++ b/goldlib/gcfg/gxezy102.cpp @@ -0,0 +1,275 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Ezycom +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadEzycom102(FILE* fp, char* path, char* file, char* options) { + + int n; + AreaCfg aa; + char abuf[40]; + + CONFIGRECORD* config = new CONFIGRECORD; throw_new(config); + CONSTANTRECORD* constant = new CONSTANTRECORD; throw_new(constant); + MESSAGERECORD* messages = new MESSAGERECORD; throw_new(messages); + + fread(config, sizeof(CONFIGRECORD), 1, fp); + fclose(fp); + + MakePathname(file, path, "constant.ezy"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(constant, sizeof(CONSTANTRECORD), 1, fp); + fclose(fp); + + STRNP2C(config->defaultorigin); + STRNP2C(config->userbasepath); + STRNP2C(config->msgpath); + STRNP2C(config->netmailpath); + CfgOrigin(config->defaultorigin); + + STRNP2C(constant->sysopname); + STRNP2C(constant->sysopalias); + + if(*ezycom_msgbasepath == NUL) + AddBackslash(strcpy(ezycom_msgbasepath, MapPath(config->msgpath))); + if(*ezycom_userbasepath == NUL) + AddBackslash(strcpy(ezycom_userbasepath, MapPath(config->userbasepath))); + + // Fido netmail directory + if(not strblank(config->netmailpath)) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.setpath(config->netmailpath); + aa.setdesc("Ezycom Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // Ezycom aka netmail boards + for(n=0; nnetaddress[n].net) { + if(constant->netmailboard[n]) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka.zone = constant->netaddress[n].zone; + aa.aka.net = constant->netaddress[n].net; + aa.aka.node = constant->netaddress[n].node; + aa.aka.point = constant->netaddress[n].point; + aa.board = constant->netmailboard[n]; + Desc desc; + sprintf(desc, "Ezycom Netmail Board, %s", constant->netaddress[n].make_string(abuf)); + aa.setdesc(desc); + sprintf(desc, "NET_AKA%u", n); + aa.setautoid(desc); + AddNewArea(aa); + } + } + } + + // Ezycom watchdog board + if(constant->watchmess) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->watchmess; + aa.setdesc("Ezycom Watchdog Board"); + aa.setautoid("LOCAL_WATCHDOG"); + AddNewArea(aa); + } + + // Ezycom paging board + if(constant->pagemessboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->pagemessboard; + aa.setdesc("Ezycom Paging Board"); + aa.setautoid("LOCAL_PAGING"); + AddNewArea(aa); + } + + // Ezycom bad logon board + if(constant->badpwdmsgboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->badpwdmsgboard; + aa.setdesc("Ezycom Bad Logon Board"); + aa.setautoid("LOCAL_BADLOGON"); + AddNewArea(aa); + } + + // Ezycom bad qwk board + if(constant->qwkmsgboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->qwkmsgboard; + aa.setdesc("Ezycom Bad QWK Board"); + aa.setautoid("ECHO_BADQWK"); + AddNewArea(aa); + } + + // Ezycom bad echomail board + if(constant->badmsgboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->badmsgboard; + aa.setdesc("Ezycom Bad Echomail Board"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + MakePathname(file, path, "messages.ezy"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + int record = 1; + + while(fread(messages, sizeof(MESSAGERECORD), 1, fp) == 1) { + + if(record <= constant->maxmess) { + + if(*messages->name) { + + switch(messages->typ) { + + case 0: // localmail + case 1: // netmail + case 2: // echomail + case 5: // allmail + + aa.reset(); + + STRNP2C(messages->name); + STRNP2C(messages->areatag); + STRNP2C(messages->originline); + + aa.board = record; + aa.msgbase = GMB_EZYCOM; + aa.groupid = messages->areagroup; + aa.setorigin(*messages->originline ? messages->originline : config->defaultorigin); + + aa.setdesc(messages->name); + aa.setechoid(messages->areatag); + + switch(messages->typ) { + case 0: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case 1: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + switch(messages->msgkinds) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + } + + aa.aka.zone = constant->netaddress[messages->originaddress-1].zone; + aa.aka.net = constant->netaddress[messages->originaddress-1].net; + aa.aka.node = constant->netaddress[messages->originaddress-1].node; + aa.aka.point = constant->netaddress[messages->originaddress-1].point; + + AddNewArea(aa); + + break; + } + } + } + + record++; + } + fclose(fp); + } + } + + throw_delete(messages); + throw_delete(constant); + throw_delete(config); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxezy110.cpp b/goldlib/gcfg/gxezy110.cpp new file mode 100644 index 0000000..9078f4e --- /dev/null +++ b/goldlib/gcfg/gxezy110.cpp @@ -0,0 +1,335 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Ezycom +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadEzycom110(FILE* fp, char* path, char* file, char* options) { + + int n; + AreaCfg aa; + char abuf[40]; + + CONFIGRECORD* config = new CONFIGRECORD; throw_new(config); + CONSTANTRECORD* constant = new CONSTANTRECORD; throw_new(constant); + MESSAGERECORD* messages = new MESSAGERECORD; throw_new(messages); + + fread(config, sizeof(CONFIGRECORD), 1, fp); + fclose(fp); + + MakePathname(file, path, "constant.ezy"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(constant, sizeof(CONSTANTRECORD), 1, fp); + fclose(fp); + + STRNP2C(config->defaultorigin); + STRNP2C(config->userbasepath); + STRNP2C(config->msgpath); + STRNP2C(config->netmailpath); + CfgOrigin(config->defaultorigin); + + STRNP2C(constant->sysopname); + STRNP2C(constant->sysopalias); + + if(*ezycom_msgbasepath == NUL) + AddBackslash(strcpy(ezycom_msgbasepath, MapPath(config->msgpath))); + if(*ezycom_userbasepath == NUL) + AddBackslash(strcpy(ezycom_userbasepath, MapPath(config->userbasepath))); + + // Fido netmail directory + if(not strblank(config->netmailpath)) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.setpath(config->netmailpath); + aa.setdesc("Ezycom Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // Ezycom aka netmail boards + for(n=0; nnetaddress[n].net) { + if(constant->netmailboard[n]) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka.zone = constant->netaddress[n].zone; + aa.aka.net = constant->netaddress[n].net; + aa.aka.node = constant->netaddress[n].node; + aa.aka.point = constant->netaddress[n].point; + aa.board = constant->netmailboard[n]; + Desc desc; + sprintf(desc, "Ezycom Netmail Board, %s", constant->netaddress[n].make_string(abuf)); + aa.setdesc(desc); + sprintf(desc, "NET_AKA%u", n); + aa.setautoid(desc); + AddNewArea(aa); + } + } + } + + // Ezycom watchdog board + if(constant->watchmess) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->watchmess; + aa.setdesc("Ezycom Watchdog Board"); + aa.setautoid("LOCAL_WATCHDOG"); + AddNewArea(aa); + } + + // Ezycom paging board + if(constant->pagemessboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->pagemessboard; + aa.setdesc("Ezycom Paging Board"); + aa.setautoid("LOCAL_PAGING"); + AddNewArea(aa); + } + + // Ezycom bad logon board + if(constant->badpwdmsgboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->badpwdmsgboard; + aa.setdesc("Ezycom Bad Logon Board"); + aa.setautoid("LOCAL_BADLOGON"); + AddNewArea(aa); + } + + // Ezycom bad qwk board + if(constant->qwkmsgboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->qwkmsgboard; + aa.setdesc("Ezycom Bad QWK Board"); + aa.setautoid("ECHO_BADQWK"); + AddNewArea(aa); + } + + // Ezycom bad echomail board + if(constant->badmsgboard) { + aa.reset(); + aa.msgbase = GMB_EZYCOM; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka.zone = constant->netaddress[0].zone; + aa.aka.net = constant->netaddress[0].net; + aa.aka.node = constant->netaddress[0].node; + aa.aka.point = constant->netaddress[0].point; + aa.board = constant->badmsgboard; + aa.setdesc("Ezycom Bad Echomail Board"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + MakePathname(file, path, "MESSAGES.EZY"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + int record = 1; + + while(fread(messages, sizeof(MESSAGERECORD), 1, fp) == 1) { + + if(record <= constant->maxmess) { + + if(*messages->name) { + + switch(messages->typ) { + + case 0: // localmail + case 1: // netmail + case 2: // echomail + case 5: // allmail + + aa.reset(); + + STRNP2C(messages->name); + STRNP2C(messages->areatag); + STRNP2C(messages->originline); + + aa.board = record; + aa.msgbase = GMB_EZYCOM; + aa.groupid = messages->areagroup; + aa.setorigin(*messages->originline ? messages->originline : config->defaultorigin); + + aa.setdesc(messages->name); + aa.setechoid(messages->areatag); + + switch(messages->typ) { + case 0: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case 1: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + switch(messages->msgkinds) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + } + + aa.aka.zone = constant->netaddress[messages->originaddress-1].zone; + aa.aka.net = constant->netaddress[messages->originaddress-1].net; + aa.aka.node = constant->netaddress[messages->originaddress-1].node; + aa.aka.point = constant->netaddress[messages->originaddress-1].point; + + AddNewArea(aa); + + break; + } + } + } + + record++; + } + fclose(fp); + } + } + + throw_delete(messages); + throw_delete(constant); + throw_delete(config); +} + + +// ------------------------------------------------------------------ + +void gareafile::ReadEzycom(char* tag) { + + FILE* fp; + char* ptr; + Path path, file; + char options[80], abuf[40]; + + *file = NUL; + *path = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("EZY"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + if(*path == NUL) + strcpy(path, areapath); + + ptr = getenv("TASK"); + if(ptr and *ptr) { + sprintf(abuf, "CONFIG.%u", atoi(ptr)); + MakePathname(file, path, abuf); + } + if(not fexist(file)) + MakePathname(file, path, "config.ezy"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + char _verstr[9]; + fread(_verstr, 9, 1, fp); + rewind(fp); + + strp2c(_verstr); + + if(strnicmp(_verstr, "1.02", 4) < 0) { + cout << "* Error: Ezycom v" << _verstr << " is not supported - Skipping." << endl; + return; + } + else if(strnicmp(_verstr, "1.10", 4) >= 0) + ReadEzycom110(fp, path, file, options); + else + ReadEzycom102(fp, path, file, options); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxfd.cpp b/goldlib/gcfg/gxfd.cpp new file mode 100644 index 0000000..823dcbe --- /dev/null +++ b/goldlib/gcfg/gxfd.cpp @@ -0,0 +1,164 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from FrontDoor 1.99c - 2.0x +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read FrontDoor FD.SYS/SETUP.FD and FOLDER.SYS/FOLDER.FD + +void gareafile::ReadFrontDoor(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + word sysrev; + long behave; + FD_Folder* folder; + FD_Editor* editor; + FD_Shared* shared; + Path fdpath, file; + char buf[256], origin[80], options[80]; + + *fdpath = NUL; + *origin = NUL; + folder = new FD_Folder; throw_new(folder); + editor = new FD_Editor; throw_new(editor); + shared = new FD_Shared; throw_new(shared); + + ptr = getenv("FD"); + if(ptr) + AddBackslash(strcpy(fdpath, ptr)); + else + strcpy(fdpath, areapath); + + // Read AREAS.BBS + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + if(is_dir(ptr) and (*fdpath == NUL)) + AddBackslash(strcpy(fdpath, ptr)); + else + GetAreasBBS(ptr, origin, options); + } + ptr = strtok(NULL, " \t"); + } + + if(not fexist(AddPath(fdpath, "setup.fd"))) + MakePathname(file, fdpath, "fd.sys"); + else + MakePathname(file, fdpath, "setup.fd"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(buf, 5, 1, fp); + if(streql(buf, "JoHo")) { // Check to see that it is v1.99b or higher + fread(&sysrev, sizeof(word), 1, fp); + // This probably ought to be if(sysrev == FD_THISREV).. + fseek(fp, 4, SEEK_CUR); // Seek past CRC32 + fseek(fp, sizeof(FD_Mailer), SEEK_CUR); // Seek past some data + fread(editor, sizeof(FD_Editor), 1, fp); + fread(shared, sizeof(FD_Shared), 1, fp); + //CfgUsername(shared->user[0].name); + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(editor->qbase)); + aa.reset(); + aa.aka = shared->aka[0]; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.msgbase = fidomsgtype; + aa.attr.r_o(editor->netfolderflags & EDREADONLY); + aa.attr.pvt(editor->msgbits & MSGPRIVATE); + aa.attr.cra(editor->msgbits & MSGCRASH); + aa.attr.k_s(editor->msgbits & MSGKILL); + aa.setpath(shared->mailpath); + aa.setdesc("FrontDoor Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + fclose(fp); + } + + if(fexist(AddPath(fdpath, "folder.fd"))) + MakePathname(file, fdpath, "folder.fd"); + else + MakePathname(file, fdpath, "folder.sys"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(folder, sizeof(FD_Folder), 1, fp) == 1) { + behave = folder->behave; + if(not strblank(folder->title) and not (FOLDER_DELETED & behave)) { + aa.reset(); + aa.aka = shared->aka[folder->useaka]; + aa.type = (behave & FOLDER_ECHOMAIL) ? GMB_ECHO : GMB_LOCAL; + aa.attr = (behave & FOLDER_ECHOMAIL) ? attribsecho : attribslocal; + aa.attr.r_o(behave & FOLDER_READONLY); + if(behave & FOLDER_HMB) { + aa.msgbase = GMB_HUDSON; + aa.board = folder->board; + } + else if(behave & FOLDER_JAM) { + aa.msgbase = GMB_JAM; + aa.setpath(folder->path); + } + else { + aa.msgbase = fidomsgtype; + aa.setpath(folder->path); + } + if(behave & FOLDER_PRIVATE) + aa.attr.pvt1(); + else + aa.attr.pvt0(); + aa.setdesc(folder->title); + aa.setorigin(editor->origin[folder->origin]); + AddNewArea(aa); + } + } + fclose(fp); + } + + throw_delete(editor); + throw_delete(shared); + throw_delete(folder); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxfecho6.cpp b/goldlib/gcfg/gxfecho6.cpp new file mode 100644 index 0000000..6c714bc --- /dev/null +++ b/goldlib/gcfg/gxfecho6.cpp @@ -0,0 +1,212 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from FastEcho 1.42 (config revision level 6) +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read FASTECHO.CFG + +void gareafile::ReadFastecho142(int fh) { + + AreaCfg aa; + + CONFIG6* cfg = (CONFIG6*)throw_calloc(1, sizeof(CONFIG6)); + FeArea6* area = (FeArea6*)throw_calloc(1, sizeof(FeArea6)); + + // Read main config record + read(fh, cfg, sizeof(CONFIG6)); + + // Get Hudson msgbase path + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->MsgBase)); + + // Setup aka and origin lists + SysAddress* aka = (SysAddress*)throw_calloc(cfg->AkaCnt, sizeof(SysAddress)); + OriginLines* origin = (OriginLines*)throw_calloc(cfg->OriginCnt, sizeof(OriginLines)); + + // Process extended headers + ulong offset = 0; + while(offset < cfg->offset) { + ExtensionHeader ehdr; + read(fh, &ehdr, sizeof(ExtensionHeader)); + offset += sizeof(ExtensionHeader); + switch(ehdr.type) { + case EH_AKAS: + read(fh, aka, cfg->AkaCnt*sizeof(SysAddress)); + break; + case EH_ORIGINS: + read(fh, origin, cfg->OriginCnt*sizeof(OriginLines)); + break; + default: + lseek(fh, ehdr.offset, SEEK_CUR); + } + offset += ehdr.offset; + } + + // Skip node records + lseek(fh, (long)(cfg->NodeCnt)*(long)cfg->NodeRecSize, SEEK_CUR); + + // The *.MSG netmail area + aa.reset(); + aa.aka = aka[0].main; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.msgbase = fidomsgtype; + aa.setpath(cfg->NetMPath); + aa.setdesc("FastEcho Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + + // All the echomail areas + for(int n=0; nAreaCnt; n++) { + read(fh, area, sizeof(FeArea6)); + if(area->board != AREA_DELETED) { + + aa.reset(); + + aa.aka = aka[area->info.aka].main; + + switch(area->flags.storage) { + case QBBS: + aa.msgbase = GMB_HUDSON; + aa.board = area->board; + break; + case FIDO: + aa.msgbase = fidomsgtype; + aa.setpath(area->path); + break; + case SQUISH: + aa.msgbase = GMB_SQUISH; + aa.setpath(area->path); + break; + case JAM: + aa.msgbase = GMB_JAM; + aa.setpath(area->path); + break; + default: + // Passthrough or unknown + continue; + } + + switch(area->flags.atype) { + case AREA_BADMAILBOARD: + case AREA_DUPEBOARD: + case AREA_ECHOMAIL: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + case AREA_NETMAIL: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case AREA_LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + default: + // Unknown type + continue; + + } + aa.setdesc(area->desc); + aa.setechoid(area->name); + if(area->flags.origin < cfg->OriginCnt) + aa.setorigin(origin[area->flags.origin].line); + aa.groupid = (char)('A' + area->info.group); + if(aa.groupid > 'Z') + aa.groupid = 0x8000u + (area->info.group-25); + + AddNewArea(aa); + } + } + + throw_free(origin); + throw_free(aka); + throw_free(area); + throw_free(cfg); +} + + +// ------------------------------------------------------------------ +// Read FASTECHO.CFG + +void gareafile::ReadFastecho(char* tag) { + + char* ptr; + Path file; + char options[80]; + int fh; + short revision; + + *file = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + strcpy(file, ptr); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*file == NUL) { + ptr = getenv("FASTECHO"); + if(ptr) + AddBackslash(strcpy(file, ptr)); + } + if(*file == NUL) + strcpy(file, areapath); + + if(not fexist(file)) { + AddBackslash(file); + strcat(file, "fastecho.cfg"); + } + + fh = sopen(file, O_RDONLY|O_BINARY, sharemode, S_STDRD); + if(fh != -1) { + + if(not quiet) + cout << "* Reading " << file << endl; + + read(fh, &revision, sizeof(revision)); + lseek(fh, 0L, SEEK_SET); // rewind + + if(revision == 6) + ReadFastecho142(fh); + else + cout << "* Error: FastEcho system file revision level " << revision << " is not supported - Skipping." << endl; + + close(fh); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxfidpcb.cpp b/goldlib/gcfg/gxfidpcb.cpp new file mode 100644 index 0000000..a896ebc --- /dev/null +++ b/goldlib/gcfg/gxfidpcb.cpp @@ -0,0 +1,230 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from FidoPCB. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +struct fparea { + + Echo echoid; + Path path; + int msgs; +}; + + +// ------------------------------------------------------------------ + +const word CRC_AREA = 0x010B; +const word CRC_AREA_MSGS = 0x90E4; +const word CRC_LOST_MAIL = 0x7C78; +const word CRC_MAIL = 0x6A39; +const word CRC_NET_MAIL = 0x7F80; +const word CRC_SYSOP = 0x967F; +const word CRC_ORIGIN = 0x4CE5; +const word CRC_PCBOARD = 0x84EC; +const word CRC_TAG = 0x5B36; +const word CRC_NODE = 0xD3AD; + + +// ------------------------------------------------------------------ + +void gareafile::ReadFidoPCB(char* tag) { + + AreaCfg aa; + char options[80]; + Path file, path; + + *path = NUL; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("FIDOPCB"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + if(*path == NUL) + strcpy(path, areapath); + + MakePathname(file, path, "fidopcb.cfg"); + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + int areas = 0; + fparea* area = NULL; + + Path mailpath; + *mailpath = NUL; + Path lostmailpath; + *lostmailpath = NUL; + Path netmailpath; + *netmailpath = NUL; + ftn_addr mainaddr; + char origin[80]; + *origin = NUL; + int innode = false; + + char buf[512]; + while(fgets(buf, sizeof(buf), fp)) { + + char* val = strskip_wht(buf); + if(*val != ';' and *val) { + + // Extract keyword and value + char* key; + word crc = getkeyvalcrc(&key, &val); + + switch(crc) { + case CRC_MAIL: + PathCopy(mailpath, val); + break; + case CRC_PCBOARD: + PathCopy(pcboardpath, val); + break; + case CRC_LOST_MAIL: + PathCopy(lostmailpath, val); + break; + case CRC_NET_MAIL: + PathCopy(netmailpath, val); + break; + case CRC_SYSOP: + if(not innode) + NW(val); + //CfgUsername(val); + break; + case CRC_ORIGIN: + mainaddr.set(val); + innode = false; + break; + case CRC_TAG: + strxcpy(origin, val, sizeof(origin)); + break; + case CRC_AREA: + area = (fparea*)throw_realloc(area, (areas+1)*sizeof(fparea)); + area[areas].msgs = false; + getkeyval(&key, &val); // Skip the unique number + getkeyval(&key, &val); // Get echoid + strxcpy(area[areas].echoid, key, sizeof(Echo)); + getkeyval(&key, &val); // Get path + PathCopy(area[areas].path, key); + areas++; + break; + case CRC_AREA_MSGS: + if(areas) { + strcat(area[areas-1].path, val); + area[areas-1].msgs = true; + } + break; + case CRC_NODE: + innode = true; + break; + } + + } + } + + // *.MSG style netmail + aa.reset(); + aa.aka = mainaddr; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(mailpath); + aa.setdesc("FidoPCB Mailer Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + + // Matrix area + if(*netmailpath) { + aa.reset(); + aa.aka = mainaddr; + aa.msgbase = GMB_PCBOARD; + aa.type = GMB_NET; + aa.attr = attribsnet; + strcat(AddBackslash(netmailpath), "MATRIX"); + aa.setpath(netmailpath); + aa.setorigin(origin); + aa.setdesc("FidoPCB Matrix Board"); + aa.setautoid("MATRIX"); + AddNewArea(aa); + } + + // Lost mail area + if(*lostmailpath) { + aa.reset(); + aa.aka = mainaddr; + aa.msgbase = GMB_PCBOARD; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + strcat(AddBackslash(lostmailpath), "LOST"); + aa.setpath(lostmailpath); + aa.setorigin(origin); + aa.setdesc("FidoPCB Lost Mail Board"); + aa.setautoid("LOST"); + AddNewArea(aa); + } + + // Process areas + fparea* ap = area; + for(int n=0; nmsgs) + strcat(ap->path, "MSGS"); + aa.setpath(ap->path); + aa.setechoid(ap->echoid); + aa.setorigin(origin); + AddNewArea(aa); + } + + throw_free(area); + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxfm092.cpp b/goldlib/gcfg/gxfm092.cpp new file mode 100644 index 0000000..6a74d43 --- /dev/null +++ b/goldlib/gcfg/gxfm092.cpp @@ -0,0 +1,208 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from FMail +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadFMail092(FILE* fp, char* path, char* file, char* options) { + + AreaCfg aa; + + configType* cfg = new configType; throw_new(cfg); + + fread(cfg, sizeof(configType), 1, fp); + fclose(fp); + + // Get Hudson msgbase path + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->bbsPath)); + + // Opus-.MSG style netmail + if(not strblank(cfg->netPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->netPath); + aa.setdesc("FMail Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // Opus-.MSG style netmail sent + if(not strblank(cfg->sentPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->sentPath); + aa.setdesc("FMail Netmail Sent"); + aa.setautoid("NET_SENT"); + AddNewArea(aa); + } + + // Opus-.MSG style netmail rcvd + if(not strblank(cfg->rcvdPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->rcvdPath); + aa.setdesc("FMail Netmail Received"); + aa.setautoid("NET_RECEIVED"); + AddNewArea(aa); + } + + // Q-style netmail + for(int x=0; xnetmailBoard[x] and cfg->netmailBoard[x] < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.board = cfg->netmailBoard[x]; + aa.aka = cfg->akaList[x].nodeNum; + Desc desc; + sprintf(desc, "%s", cfg->descrAKA[x]); + aa.setdesc(desc); + sprintf(desc, "NET_AKA%u", x); + aa.setautoid(desc); + AddNewArea(aa); + } + } + + // Q-style recovery board + if(cfg->recBoard and cfg->recBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->recBoard; + aa.setdesc("FMail Recovery Board"); + aa.setautoid("ECHO_RECOVERY"); + AddNewArea(aa); + } + + // Q-style badmsgs + if(cfg->badBoard and cfg->badBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->badBoard; + aa.setdesc("FMail Bad Echomail Board"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + // Q-style dupmsgs + if(cfg->dupBoard and cfg->dupBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->dupBoard; + aa.setdesc("FMail Duplicates Board"); + aa.setautoid("ECHO_DUPES"); + AddNewArea(aa); + } + + // Personal mail + if(not strblank(cfg->pmailPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.setpath(cfg->pmailPath); + aa.setdesc("FMail Personal Mail"); + aa.setautoid("ECHO_PERSONAL"); + AddNewArea(aa); + } + + + rawEchoType* ar = new rawEchoType; throw_new(ar); + + MakePathname(file, path, "fmail.ar"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + while(fread(ar, sizeof(rawEchoType), 1, fp) == 1) { + + if(ar->options.active and ar->board and ar->board < 201) { + + aa.reset(); + aa.aka = cfg->akaList[ar->address].nodeNum; + if(ar->options.local) { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + else { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + switch(ar->msgKindsRA) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + case 3: + aa.attr.r_o1(); + break; + } + aa.board = ar->board; + aa.msgbase = GMB_HUDSON; + aa.setdesc(ar->comment); + aa.setechoid(ar->areaNameOld[0] ? ar->areaNameOld : ar->areaName); + aa.setorigin(ar->originLine); + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_delete(ar); + throw_delete(cfg); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxfm100.cpp b/goldlib/gcfg/gxfm100.cpp new file mode 100644 index 0000000..c1d9c59 --- /dev/null +++ b/goldlib/gcfg/gxfm100.cpp @@ -0,0 +1,236 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from FMail +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadFMail098(FILE* fp, char* path, char* file, char* options) { + + AreaCfg aa; + + configType* cfg = new configType; throw_new(cfg); + + fread(cfg, sizeof(configType), 1, fp); + fclose(fp); + + // Get Hudson msgbase path + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->bbsPath)); + + // .MSG style netmail + if(not strblank(cfg->netPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->netPath); + aa.setdesc("FMail Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // .MSG style netmail sent + if(not strblank(cfg->sentPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->sentPath); + aa.setdesc("FMail Netmail Sent"); + aa.setautoid("NET_SENT"); + AddNewArea(aa); + } + + // .MSG style netmail rcvd + if(not strblank(cfg->rcvdPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->rcvdPath); + aa.setdesc("FMail Netmail Received"); + aa.setautoid("NET_RECEIVED"); + AddNewArea(aa); + } + + // Hudson netmail + for(int x=0; xnetmailBoard[x] and cfg->netmailBoard[x] < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.board = cfg->netmailBoard[x]; + aa.aka = cfg->akaList[x].nodeNum; + Desc desc; + sprintf(desc, "%s", cfg->descrAKA[x]); + aa.setdesc(desc); + sprintf(desc, "NET_AKA%u", x); + aa.setautoid(desc); + AddNewArea(aa); + } + } + + // Hudson recovery board + if(cfg->recBoard and cfg->recBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->recBoard; + aa.setdesc("FMail Recovery Board"); + aa.setautoid("ECHO_RECOVERY"); + AddNewArea(aa); + } + + // Hudson badmsgs + if(cfg->badBoard and cfg->badBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->badBoard; + aa.setdesc("FMail Bad Echomail Board"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + // Hudson dupmsgs + if(cfg->dupBoard and cfg->dupBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->dupBoard; + aa.setdesc("FMail Duplicates Board"); + aa.setautoid("ECHO_DUPES"); + AddNewArea(aa); + } + + // Personal mail + if(not strblank(cfg->pmailPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.setpath(cfg->pmailPath); + aa.setdesc("FMail Personal Mail"); + aa.setautoid("ECHO_PERSONAL"); + AddNewArea(aa); + } + + headerType hdr; + + rawEchoType* ar; + + MakePathname(file, path, "fmail.ar"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + + fread(&hdr, sizeof(headerType), 1, fp); + fseek(fp, hdr.headerSize, SEEK_SET); + + ar = (rawEchoType*)throw_calloc(1, hdr.recordSize); + if(ar) { + + while(fread(ar, hdr.recordSize, 1, fp) == 1) { + + if(ar->options.active) { + + aa.reset(); + + aa.groupid = 'A'; + dword grp = ar->group; + while((grp & 1L) == 0) { + if((++aa.groupid) == 'Z') + break; + grp >>= 1; + } + + //aa.groupid = (char)toupper((char)ar->group); + aa.aka = cfg->akaList[ar->address].nodeNum; + if(ar->options.local) { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + else { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + switch(ar->msgKindsRA) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + case 3: + aa.attr.r_o1(); + break; + } + if(ar->board) { + aa.board = ar->board; + aa.msgbase = GMB_HUDSON; + } + else if(*ar->msgBasePath) { + aa.setpath(ar->msgBasePath); + aa.msgbase = GMB_JAM; + } + + aa.setdesc(ar->comment); + aa.setechoid(ar->areaName); + aa.setorigin(ar->originLine); + AddNewArea(aa); + } + } + } + + throw_free(ar); + + fclose(fp); + } + + throw_delete(cfg); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxfm116.cpp b/goldlib/gcfg/gxfm116.cpp new file mode 100644 index 0000000..49a73a0 --- /dev/null +++ b/goldlib/gcfg/gxfm116.cpp @@ -0,0 +1,307 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from FMail +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadFMail116(FILE* fp, char* path, char* file, char* options) { + + AreaCfg aa; + + configType* cfg = new configType; throw_new(cfg); + + fread(cfg, sizeof(configType), 1, fp); + fclose(fp); + + // Get Hudson msgbase path + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->bbsPath)); + + // .MSG style netmail + if(not strblank(cfg->netPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->netPath); + aa.setdesc("FMail Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // .MSG style netmail sent + if(not strblank(cfg->sentPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->sentPath); + aa.setdesc("FMail Netmail Sent"); + aa.setautoid("NET_SENT"); + AddNewArea(aa); + } + + // .MSG style netmail rcvd + if(not strblank(cfg->rcvdPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(cfg->rcvdPath); + aa.setdesc("FMail Netmail Received"); + aa.setautoid("NET_RECEIVED"); + AddNewArea(aa); + } + + // Hudson netmail + for(int x=0; xnetmailBoard[x] and cfg->netmailBoard[x] < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.board = cfg->netmailBoard[x]; + aa.aka = cfg->akaList[x].nodeNum; + Desc desc; + sprintf(desc, "%s", cfg->descrAKA[x]); + aa.setdesc(desc); + sprintf(desc, "NET_AKA%u", x); + aa.setautoid(desc); + AddNewArea(aa); + } + } + + // Hudson recovery board + if(cfg->recBoard and cfg->recBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->recBoard; + aa.setdesc("FMail Recovery Board"); + aa.setautoid("ECHO_RECOVERY"); + AddNewArea(aa); + } + + // Hudson badmsgs + if(cfg->badBoard and cfg->badBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->badBoard; + aa.setdesc("FMail Bad Echomail Board"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + // Hudson dupmsgs + if(cfg->dupBoard and cfg->dupBoard < 201) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = cfg->dupBoard; + aa.setdesc("FMail Duplicates Board"); + aa.setautoid("ECHO_DUPES"); + AddNewArea(aa); + } + + // Personal mail + if(not strblank(cfg->pmailPath)) { + aa.reset(); + aa.aka = cfg->akaList[0].nodeNum; + aa.msgbase = fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.setpath(cfg->pmailPath); + aa.setdesc("FMail Personal Mail"); + aa.setautoid("ECHO_PERSONAL"); + AddNewArea(aa); + } + + headerType hdr; + + rawEchoType116* ar; + + MakePathname(file, path, "fmail.ar"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + + fread(&hdr, sizeof(headerType), 1, fp); + + uint headerSize = hdr.headerSize; + uint recordSize = hdr.recordSize; + + fseek(fp, headerSize, SEEK_SET); + + ar = (rawEchoType116*)throw_calloc(1, recordSize); + if(ar) { + + while(fread(ar, recordSize, 1, fp) == 1) { + + if(ar->options.active) { + + aa.reset(); + + aa.groupid = 'A'; + dword grp = ar->group; + while((grp & 1L) == 0) { + if((++aa.groupid) == 'Z') + break; + grp >>= 1; + } + + //aa.groupid = (char)toupper((char)ar->group); + aa.aka = cfg->akaList[ar->address].nodeNum; + if(ar->options.local) { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + else { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + switch(ar->msgKindsRA) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + case 3: + aa.attr.r_o1(); + break; + } + if(ar->board) { + aa.board = ar->board; + aa.msgbase = GMB_HUDSON; + } + else if(*ar->msgBasePath) { + aa.setpath(ar->msgBasePath); + aa.msgbase = GMB_JAM; + } + + aa.setdesc(ar->comment); + aa.setechoid(ar->areaName); + aa.setorigin(ar->originLine); + AddNewArea(aa); + } + } + } + + throw_free(ar); + + fclose(fp); + } + + throw_delete(cfg); +} + + +// ------------------------------------------------------------------ + +void gareafile::ReadFMail(char* tag) { + + char* ptr; + FILE* fp; + char options[80]; + Path path, file; + + *file = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*file == NUL) { + ptr = getenv("FMAIL"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + if(*path == NUL) + strcpy(path, areapath); + + MakePathname(file, path, "fmail.cfg"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + struct { + byte vmajor; + byte vminor; + } _rev; + + fread(&_rev, sizeof(_rev), 1, fp); + rewind(fp); + + uint fmver = (_rev.vmajor << 8) | _rev.vminor; + + if(fmver < 94) + ReadFMail092(fp, path, file, options); + else { + + FILE* fpar; + headerType ar; + fpar = fsopen(AddPath(path, "fmail.ar"), "rb", sharemode); + if(fpar) { + fread(&ar, sizeof(ar), 1, fpar); + fclose(fpar); + } + + uint ar_rev = (ushort)ar.revNumber; + + if((ar_rev >= 0x0100) and (ar_rev < 0x0110)) + ReadFMail098(fp, path, file, options); + else if((ar_rev >= 0x0110) and (ar_rev < 0x0200)) + ReadFMail116(fp, path, file, options); + else + cout << "* Error: Unknown FMail config revision " << setfill('0') << setw(4) << hex << ar_rev << "h - Skipping." << endl; + } + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxgecho.cpp b/goldlib/gcfg/gxgecho.cpp new file mode 100644 index 0000000..ceac209 --- /dev/null +++ b/goldlib/gcfg/gxgecho.cpp @@ -0,0 +1,453 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from GEcho +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#if defined(ADDRESS) +#undef ADDRESS +#endif + +#include + + +// ------------------------------------------------------------------ +// Read GEcho AREAFILE.GE and SETUP.GE + +void gareafile::ReadGEcho(char* tag) { + + FILE* fp; + char* ptr; + char* ptr2; + AreaCfg aa; + int n; + word sysrev; + AREAFILE_GE* area; + AREAFILE_HDR ahdr; + SETUP_GE* gesetup; + Path gepath, file; + char options[80], abuf[40]; + + *gepath = NUL; + + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(gepath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*gepath == NUL) { + ptr = getenv("GE"); + if(ptr) { + ptr = strcpy(gepath, ptr); + ptr2 = strchr(ptr, ' '); + if(ptr2) + *ptr2 = NUL; + AddBackslash(gepath); + } + } + if(*gepath == NUL) + strcpy(gepath, areapath); + + MakePathname(file, gepath, "setup.ge"); + + gesetup = (SETUP_GE*)throw_calloc(1, sizeof(SETUP_GE)); + if(gesetup) { + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(&sysrev, sizeof(word), 1, fp); + rewind(fp); + + if(sysrev == GE_THISREV) { + + fread(gesetup, sizeof(SETUP_GE), 1, fp); + fclose(fp); + + int ge_version = (gesetup->version_major * 100) + gesetup->version_minor; + + //for(n=0; nusername[n]); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(gesetup->hmbpath)); + + if(*jampath == NUL) + PathCopy(jampath, MapPath(gesetup->jampath)); + + int _fidomsgtype = fidomsgtype; + + if(ge_version >= 102) { + _fidomsgtype = (gesetup->extraoptions & OPUSDATES) ? GMB_OPUS : GMB_FTS1; + if((_fidomsgtype == GMB_FTS1) and (fidomsgtype == GMB_OPUS)) { + cout << + "* Warning - FTS-1 format is used for *.MSG. For better compatibility set this" << endl << + "* in GSETUP: Miscellanous->GEcho Options->MSG compatibilty = Opus (not Fido)." << endl << + "* To disable this warning, set FIDOMSGTYPE FTS1 in your GoldED setup." << endl; + } + } + + int _AKAS = AKAS; + ftn_addr* _aka = (ftn_addr*)gesetup->aka; + if(ge_version < 110) { + _aka = (ftn_addr*)gesetup->oldaka; + _AKAS = OLDAKAS; + } + + // Old netmail board (no longer in use by GEcho, but just in case...) + if(gesetup->oldnetmailboard and gesetup->oldnetmailboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = _aka[0]; + aa.board = gesetup->oldnetmailboard; + aa.setdesc("GEcho Netmail (HMB)"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + else if(not strblank(gesetup->mailpath)) { + aa.reset(); + aa.msgbase = _fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = _aka[0]; + aa.setpath(gesetup->mailpath); + aa.setdesc("GEcho Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // Bad msgs + uint _badboard = (ge_version >= 110) ? gesetup->badarea : gesetup->oldbadboard; + if(_badboard and _badboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = _badboard; + aa.aka = _aka[0]; + aa.setdesc("GEcho Bad Msgs (HMB)"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + else if(not strblank(gesetup->badecho_path)) { + aa.reset(); + aa.msgbase = _fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka = _aka[0]; + aa.setpath(gesetup->badecho_path); + aa.setdesc("GEcho Bad Msgs"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + // Dupe msgs + if(ge_version < 120) { + //uint _dupboard = (ge_version >= 110) ? gesetup->duparea : gesetup->olddupboard; + uint _dupboard = (ge_version >= 110) ? gesetup->reserved5 : gesetup->olddupboard; + if(_dupboard and _dupboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = _dupboard; + aa.aka = _aka[0]; + aa.setdesc("GEcho Dupe Msgs (HMB)"); + aa.setautoid("ECHO_DUPES"); + AddNewArea(aa); + } + } + + // Recovery + if(gesetup->recoveryboard and gesetup->recoveryboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = gesetup->recoveryboard; + aa.aka = _aka[0]; + aa.setdesc("GEcho Recovered Msgs (HMB)"); + aa.setautoid("ECHO_RECOVERED"); + AddNewArea(aa); + } + + // Received msgs + uint _rcvdboard = (ge_version >= 110) ? gesetup->rcvdarea : gesetup->oldrcvdboard; + if(_rcvdboard and _rcvdboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = _rcvdboard; + aa.aka = _aka[0]; + aa.setdesc("GEcho Received Netmail (HMB)"); + aa.setautoid("NET_RECEIVED"); + AddNewArea(aa); + } + else if(not strblank(gesetup->rcvdmailpath)) { + aa.reset(); + aa.msgbase = _fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = _aka[0]; + aa.setpath(gesetup->rcvdmailpath); + aa.setdesc("GEcho Received Netmail"); + aa.setautoid("NET_RECEIVED"); + AddNewArea(aa); + } + + // Sent msgs + uint _sentboard = (ge_version >= 110) ? gesetup->sentarea : gesetup->oldsentboard; + if(gesetup->oldsentboard and gesetup->oldsentboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.board = _sentboard; + aa.aka = _aka[0]; + aa.setdesc("GEcho Sent Netmail (HMB)"); + aa.setautoid("NET_SENT"); + AddNewArea(aa); + } + else if(not strblank(gesetup->sentmailpath)) { + aa.reset(); + aa.msgbase = _fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = _aka[0]; + aa.setpath(gesetup->sentmailpath); + aa.setdesc("GEcho Sent Netmail"); + aa.setautoid("NET_SENT"); + AddNewArea(aa); + } + + // Personal mail boards + for(n=0; n= 110) ? gesetup->persmailarea[u] : gesetup->oldpersmailboard[u]; + if(_persmailboard and _persmailboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka = _aka[0]; + aa.board = _persmailboard; + Desc desc; + sprintf(desc, "GEcho PM for %s", gesetup->username[u]); + aa.setdesc(desc); + sprintf(desc, "ECHO_PM%u", u); + aa.setautoid(desc); + AddNewArea(aa); + } + } + + // Personal mail + if(not strblank(gesetup->persmail_path)) { + aa.reset(); + aa.msgbase = _fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka = _aka[0]; + aa.setpath(gesetup->persmail_path); + aa.setdesc("GEcho Personal Mail"); + aa.setautoid("ECHO_PERSONAL"); + AddNewArea(aa); + } + + // User netmail boards + for(n=0; n= 110) ? gesetup->userarea[u] : gesetup->olduserboard[u]; + if(_userboard and _userboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = _aka[0]; + aa.board = _userboard; + Desc desc; + sprintf(desc, "GEcho Netmail for %s", gesetup->username[u]); + aa.setdesc(desc); + sprintf(desc, "NET_USER%u", u); + aa.setautoid(desc); + AddNewArea(aa); + } + } + + // AKA net areas + for(n=0; n<_AKAS; n++) { + int a = _AKAS - n - 1; + uint _akaboard = (ge_version >= 110) ? gesetup->akaarea[a] : gesetup->oldakaboard[a]; + if(_aka[a].net and _akaboard and _akaboard < 201) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = _aka[a]; + aa.board = _akaboard; + Desc desc; + sprintf(desc, "GEcho Netmail, %s", _aka[a].make_string(abuf)); + aa.setdesc(desc); + sprintf(desc, "NET_AKA%u", a); + aa.setautoid(desc); + AddNewArea(aa); + } + } + + // Set the JAM message base path + if(*gesetup->jampath) + PathCopy(jampath, gesetup->jampath); + + + // -------------------------------------------------------------- + + MakePathname(file, gepath, "areafile.ge"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(&ahdr, sizeof(AREAFILE_HDR), 1, fp); + uint arearecsize = (ahdr.maxconnections * sizeof(CONNECTION)) + ahdr.recsize; + + fseek(fp, (long)ahdr.hdrsize, SEEK_SET); // Allow for changed struct + + area = (AREAFILE_GE*)throw_malloc(arearecsize); + + if(area) { + while(fread(area, arearecsize, 1, fp) == 1) { + if(not (area->options & (PASSTHRU|REMOVED))) { + + memset(((byte*)area)+ahdr.recsize, 0, arearecsize-ahdr.recsize); + + aa.reset(); + + switch(area->areaformat) { + case FORMAT_HMB: + if(area->areanumber and area->areanumber < 201) { + aa.msgbase = GMB_HUDSON; + aa.board = area->areanumber; + break; + } + continue; + case FORMAT_SDM: + if(not strblank(area->path)) { + aa.msgbase = _fidomsgtype; + aa.setpath(area->path); + break; + } + continue; + case FORMAT_JAM: + if(not strblank(area->path)) { + aa.msgbase = GMB_JAM; + aa.setpath(area->path); + break; + } + continue; + case FORMAT_SQUISH: + if(not strblank(area->path)) { + aa.msgbase = GMB_SQUISH; + aa.setpath(area->path); + break; + } + continue; + case FORMAT_PCB: + aa.msgbase = GMB_PCBOARD; + aa.board = area->areanumber; + aa.setpath(area->path); + break; + case FORMAT_WC: + aa.msgbase = GMB_WILDCAT; + aa.board = area->areanumber; + aa.setpath(area->path); + break; + default: + if(ge_version >= 102) + continue; + if(area->areanumber and area->areanumber < 201) { + aa.msgbase = GMB_HUDSON; + aa.board = area->areanumber; + } + else if((area->options & SDM) and not strblank(area->path)) { + aa.msgbase = _fidomsgtype; + aa.setpath(area->path); + } + } + + aa.groupid = area->group + ((ge_version >= 120) ? 0x8001 : 0); + if(_aka[area->pkt_origin].net) + aa.aka = _aka[area->pkt_origin]; + switch(area->areatype) { + case NETMAIL: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case BADECHO: + case ECHOMAIL: + case PERSONAL: + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + aa.setdesc(area->comment); + aa.setechoid(area->name); + aa.setorigin(area->originlinenr ? gesetup->originline[area->originlinenr-1] : area->originline); + AddNewArea(aa); + } + } + throw_free(area); + } + + fclose(fp); + } + } + else + cout << "* Error: GEcho system file revision level " << sysrev << " is not supported - Skipping." << endl; + } + throw_free(gesetup); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxhpt.cpp b/goldlib/gcfg/gxhpt.cpp new file mode 100644 index 0000000..13655bd --- /dev/null +++ b/goldlib/gcfg/gxhpt.cpp @@ -0,0 +1,445 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Fidoconfig +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +static bool lame = false; + + +// ------------------------------------------------------------------ + +bool gareafile::ReadHPTLine(FILE* f, string* s, bool add=false, int state=0) { + + string str; + char buf[81]; + + if(fgets(buf, 81, f) == NULL) + return false; // eof + + str = buf; + + if(buf[strlen(buf)-1] != '\n') { + while(fgets(buf, 81, f) != NULL) { + str += buf; + if(buf[strlen(buf)-1] == '\n') + break; + } + } + + string::iterator ptr = str.begin(); + + // state 0: normal state + // 1: between "" + // 2: end + // 3: whitespace + while((ptr != str.end()) and (state != 2)) { + switch(*ptr) { + case '\\': + if(lame) + break; + if(ptr == str.end()-1) { + str.erase(ptr); + const char *p = strskip_wht(str.c_str()); + if(add) + *s += p; + else + *s = p; + ReadHPTLine(f, s, true, state); + return true; + } else + switch(ptr[1]) { + case ' ': + case '\t': + { + string::iterator i = ptr; + while((i != str.end()) and isspace(*i)) + ++i; + if(*i != '#') + break; + } + case '#': + case NUL: + case '\n': + str.erase(ptr, str.end()); + { + const char *p = strskip_wht(str.c_str()); + if(add) + *s += p; + else + *s = p; + } + ReadHPTLine(f, s, true, state); + return true; + default: + break; + } + ++ptr; + break; + case '\"': + state = 1; + break; + case '#': + if(state != 1) { + str.erase(ptr, str.end()); + state = 2; + } + break; + default: + break; + } + ++ptr; + } + + if(not str.empty() and (*(str.end()-1) == '\n')) + str.erase(str.end()-1); + + const char *p = strskip_wht(str.c_str()); + + if(add) + *s += p; + else + *s = p; + + return true; +} + + +// ------------------------------------------------------------------ + +void gareafile::replace_slashes(char **key) { + + if(lame) + return; + + char* p = *key; + + while(*p) { + if(*p == '\\') { + + int size = 1; + int chr = p[1]; + + if(isxdigit(p[1])) { + if(isxdigit(p[2])) { + size = 2; + sscanf(p, "\\%02x", &chr); + } + else + sscanf(p, "\\%1x", &chr); + } + strcpy(p, p+size); + *p = chr; + if(chr == NUL) + break; + } + ++p; + } +} + + +// ------------------------------------------------------------------ + +void gareafile::gettok(char** key, char** val) { + + char* p = strskip_wht(*val); + + // Get the keyword + switch(*p) { + + // Strip "double" quotes + case '\"': + *key = ++p; + do { + p = strskip_to(p, '\"'); + if(not *p or (*(p-1) != '\\')) + break; + else + p++; + } while(*p); + break; + + // Strip 'single' quotes + case '\'': + *key = ++p; + do { + p = strskip_to(p, '\''); + if(not *p or (*(p-1) != '\\')) + break; + else + p++; + } while(*p); + break; + + // Strip round brackets + case '(': /*)*/ + *key = ++p; + p = strskip_to(p, /*(*/ ')'); + break; + + // Get straight keyword + default: + *key = p; + while(*p and not isspace(*p)) + p++; + } + + // Nul-terminate keyword + if(*p) + *p++ = NUL; + + // Skip whitespace if any + p = strskip_wht(p); + + // Get the value + *val = p; + + replace_slashes(key); +} + + +// ------------------------------------------------------------------ + +void gareafile::ReadHPTFile(char* path, char* file, char* options, char* origin, int group) { + + const word CRC_ADDRESS = 0xFDD6; + const word CRC_INCLUDE = 0x379B; + const word CRC_NETAREA = 0xD2D7; + const word CRC_LOCALAREA = 0xAEC1; + const word CRC_ECHOAREA = 0x0D63; + const word CRC_DUPEAREA = 0xD8B9; + const word CRC_BADAREA = 0x8DA5; + const word CRC_SYSOP = 0x967F; + const word CRC_VERSION = 0xF78F; + + AreaCfg aa; + Path buf2; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + aa.reset(); + + string s; + while(ReadHPTLine(fp, &s)) { + + if(not s.empty()) { + + char *alptr = throw_xstrdup(s.c_str()); + char *ptr = alptr; + + aa.type = 0xFF; + + char* key; + char* val = ptr; + gettok(&key, &val); + switch(strCrc16(key)) { + case CRC_VERSION: + replace_slashes(&val); + { + int ver_maj, ver_min; + sscanf(val, "%d.%d", &ver_maj, &ver_min); + if((ver_maj != 0) and (ver_min != 15)) { + cout << "* Error: Unknown fidoconfig version " << ver_maj << '.' << ver_min << " - Skipping." << endl; + throw_xfree(alptr); + goto skip_config; + } + } + break; + case CRC_ADDRESS: + replace_slashes(&val); + CfgAddress(val); + break; + case CRC_SYSOP: + replace_slashes(&val); + CfgUsername(val); + break; + case CRC_INCLUDE: + replace_slashes(&val); + strxcpy(buf2, val, sizeof(buf2)); + MakePathname(buf2, path, buf2); + ReadHPTFile(path, buf2, options, origin, group); + break; + case CRC_NETAREA: + aa.type = GMB_NET; + break; + case CRC_LOCALAREA: + aa.type = GMB_LOCAL; + break; + case CRC_ECHOAREA: + case CRC_DUPEAREA: + case CRC_BADAREA: + aa.type = GMB_ECHO; + break; + } + + if(aa.type != 0xFF) { + + // Get echoid + gettok(&key, &val); + aa.setechoid(key); + + // Get path + gettok(&key, &val); + strxcpy(buf2, key, sizeof(buf2)); + + // If not pass-through + if(not strieql("Passthrough", buf2)) { + + aa.setpath(MapPath(buf2)); + aa.msgbase = fidomsgtype; + aa.groupid = group; + + gettok(&key, &val); + + while(*key == '-' || strieql(key, "Squish") || strieql(key, "Jam")) { + + if(strieql(key, "Squish")) + aa.msgbase = GMB_SQUISH; + else if(strieql(key, "Jam")) + aa.msgbase = GMB_JAM; + else { + + char *opt = key + 1; + + if(strieql(opt, "p") or strieql(opt, "$m") or strieql(opt, "lr") + or strieql(opt, "lw") or strieql(opt, "tinysb") + or strieql(opt, "dupeCheck") or strieql(opt, "dupehistory") + or strieql(opt, "r") or strieql(opt, "w") + or strieql(opt, "l")) { + + gettok(&key, &val); + } + else if(strieql(opt, "a")) { + + gettok(&key, &val); + CfgAddress(key); + aa.aka.set(key); + } + else if(strieql(opt, "h") or strieql(opt, "manual") + or strieql(opt, "nopause") or strieql(opt, "mandatory") + or strieql(opt, "dosfile") or strieql(opt, "ccoff")) { + } + else if (strieql(opt, "g")) { + + gettok(&key, &val); + + if(isalpha(*key)) + aa.groupid = toupper(*key); + } + else if (strieql(opt, "d")) { + + gettok(&key, &val); + aa.setdesc(key); + } + } + + gettok(&key, &val); + } + + switch(aa.type) { + case GMB_NET: + aa.attr = attribsnet; + break; + case GMB_ECHO: + aa.attr = attribsecho; + break; + case GMB_LOCAL: + aa.attr = attribslocal; + break; + } + aa.setorigin(origin); + AddNewArea(aa); + } + + aa.reset(); + } + throw_xfree(alptr); + } + } + +skip_config: + fclose(fp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from HPT (echomail processor) + +void gareafile::ReadHPT(char* tag) { + + char origin[80]; + char options[80]; + word defaultgroup = 0; + Path file, path; + + lame = false; + *origin = NUL; + *file = NUL; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') + strcpy(file, ptr); + else { + if(toupper(*(++ptr)) == 'G') { + if(*(++ptr) == '=') + ptr++; + if(*ptr == '#') + defaultgroup = (word)(atoi(ptr+1)+0x8000u); + else + defaultgroup = (word)(isupper(*ptr) ? *ptr : 0); + } + else if(strieql(ptr, "lame")) + lame = true; + } + ptr = strtok(NULL, " \t"); + } + + if(not *file and ((ptr = getenv("FIDOCONFIG"))!=NULL)) + strcpy(file, ptr); + + extractdirname(path, file); + + if(*squishuserpath == NUL) + PathCopy(squishuserpath, path); + + ReadHPTFile(path, file, options, origin, defaultgroup); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gximail4.cpp b/goldlib/gcfg/gximail4.cpp new file mode 100644 index 0000000..9bee973 --- /dev/null +++ b/goldlib/gcfg/gximail4.cpp @@ -0,0 +1,160 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from IMail 1.60 +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read IMail IMAIL.CF and IMAIL.AR + +void gareafile::ReadIMail160(char* options, char* file, char* impath) { + + AreaCfg aa; + FILE* fp; + im_config_type* CF; + areas_record_type AR; + + CF = new im_config_type; throw_new(CF); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(CF, sizeof(im_config_type), 1, fp); + fclose(fp); + + if(*jampath == NUL) + PathCopy(jampath, MapPath(CF->echojam)); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(CF->quickbbs)); + + // Fido netmail + if(not strblank(CF->netmail)) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = CAST(ftn_addr, CF->aka[0]); + aa.setpath(CF->netmail); + aa.setdesc("IMAIL Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + MakePathname(file, impath, "IMAIL.AR"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(&AR, sizeof(areas_record_type), 1, fp) == 1) { + + if(AR.active and (not AR.deleted)) { + + aa.reset(); + + switch(AR.msg_base_type & BASEMASK) { + + case MSGTYPE_SDM: + aa.msgbase = fidomsgtype; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_SQUISH: + aa.msgbase = GMB_SQUISH; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_JAM: + aa.msgbase = GMB_JAM; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_HUDSON: + aa.msgbase = GMB_HUDSON; + if((AR.brd >= 1) and (AR.brd <= 200)) + aa.board = AR.brd; + else { + cout << "* Warning: Invalid board " << AR.brd << " (" << AR.aname << ") in IMAIL.AR - Skipping." << endl; + continue; + } + break; + + case MSGTYPE_PASSTH: + default: + // Passthrough or unknown msgbase type + continue; + } + + switch(AR.msg_base_type & TYPEMASK) { + + case MSGTYPE_LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + + case MSGTYPE_NET: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + + case MSGTYPE_ECHO: + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + if(AR.o_addr) + aa.aka = CAST(ftn_addr, CF->aka[AR.o_addr-1]); + + aa.groupid = (char)toupper(AR.group); + + aa.setdesc(AR.comment); + aa.setechoid(AR.aname); + aa.setorigin(AR.origin); + + AddNewArea(aa); + } + } + + fclose(fp); + } + } + + throw_delete(CF); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gximail5.cpp b/goldlib/gcfg/gximail5.cpp new file mode 100644 index 0000000..40685b4 --- /dev/null +++ b/goldlib/gcfg/gximail5.cpp @@ -0,0 +1,170 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from IMail 1.7x +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#undef MAXPATH +#undef MAXDRIVE +#undef MAXDIR +#undef MAXFILE +#undef MAXEXT + +#undef except + +#include + + +// ------------------------------------------------------------------ +// Read IMail IMAIL.CF and IMAIL.AR + +void gareafile::ReadIMail170(char* options, char* file, char* impath) { + + AreaCfg aa; + FILE* fp; + im_config_type* CF; + areas_record_type AR; + + CF = new im_config_type; throw_new(CF); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(CF, sizeof(im_config_type), 1, fp); + fclose(fp); + + if(*jampath == NUL) + PathCopy(jampath, MapPath(CF->echojam)); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(CF->quickbbs)); + + // Fido netmail + if(not strblank(CF->netmail)) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = CAST(ftn_addr, CF->aka[0]); + aa.setpath(CF->netmail); + aa.setdesc("IMAIL Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + MakePathname(file, impath, "IMAIL.AR"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(&AR, sizeof(areas_record_type), 1, fp) == 1) { + + if(AR.active and (not AR.deleted)) { + + aa.reset(); + + switch(AR.msg_base_type & BASEMASK) { + + case MSGTYPE_SDM: + aa.msgbase = fidomsgtype; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_SQUISH: + aa.msgbase = GMB_SQUISH; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_JAM: + aa.msgbase = GMB_JAM; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_HUDSON: + aa.msgbase = GMB_HUDSON; + if((AR.brd >= 1) and (AR.brd <= 200)) + aa.board = AR.brd; + else { + cout << "* Warning: Invalid board " << AR.brd << " (" << AR.aname << ") in IMAIL.AR - Skipping." << endl; + continue; + } + break; + + case MSGTYPE_PASSTH: + default: + // Passthrough or unknown msgbase type + continue; + } + + switch(AR.msg_base_type & TYPEMASK) { + + case MSGTYPE_LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + + case MSGTYPE_NET: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + + case MSGTYPE_ECHO: + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + if(AR.o_addr) + aa.aka = CAST(ftn_addr, CF->aka[AR.o_addr-1]); + + aa.groupid = AR.grp + 0x8000u; + + aa.setdesc(AR.comment); + aa.setechoid(AR.aname); + aa.setorigin(AR.origin); + + AddNewArea(aa); + } + } + + fclose(fp); + } + } + + throw_delete(CF); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gximail6.cpp b/goldlib/gcfg/gximail6.cpp new file mode 100644 index 0000000..a307491 --- /dev/null +++ b/goldlib/gcfg/gximail6.cpp @@ -0,0 +1,228 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from IMail 1.85 (and newer) +// ------------------------------------------------------------------ + +// The IM_STRUCT.H header from 1.85 and newer is restricted, so we +// cannot distribute it. Sorry. + +//#define HAVE_IM18X + +#include +#include +#include + +#ifdef HAVE_IM18X +#include +#include +#endif + + +// ------------------------------------------------------------------ +// Read IMail IMAIL.CF and IMAIL.AR + +#ifdef HAVE_IM18X +void gareafile::ReadIMail185(char* options, char* file, char* impath) { + + AreaCfg aa; + FILE* fp; + im_config_type* CF; + mail_area_type AR; + + CF = new im_config_type; throw_new(CF); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(CF, sizeof(im_config_type), 1, fp); + fclose(fp); + + if(*jampath == NUL) + PathCopy(jampath, MapPath(CF->echojam)); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(CF->quickbbs)); + + // Fido netmail + if(not strblank(CF->netmail)) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = CAST(ftn_addr, CF->aka[0]); + aa.setpath(CF->netmail); + aa.setdesc("IMAIL Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + MakePathname(file, impath, "imail.ar"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(&AR, sizeof(mail_area_type), 1, fp) == 1) { + + if(AR.active and (not AR.deleted)) { + + aa.reset(); + + switch(AR.msg_base_type & BASEMASK) { + + case MSGTYPE_SDM: + aa.msgbase = fidomsgtype; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_SQUISH: + aa.msgbase = GMB_SQUISH; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_JAM: + aa.msgbase = GMB_JAM; + strcpy(aa.path, AR.msg_path); + break; + + case MSGTYPE_HUDSON: + aa.msgbase = GMB_HUDSON; + if((AR.brd >= 1) and (AR.brd <= 200)) + aa.board = AR.brd; + else { + cout << "* Warning: Invalid board " << AR.brd << " (" << AR.aname << ") in IMAIL.AR - Skipping." << endl; + continue; + } + break; + + case MSGTYPE_PASSTH: + default: + // Passthrough or unknown msgbase type + continue; + } + + switch(AR.msg_base_type & TYPEMASK) { + + case MSGTYPE_LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + + case MSGTYPE_NET: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + + case MSGTYPE_ECHO: + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + if(AR.o_addr) + aa.aka = CAST(ftn_addr, CF->aka[AR.o_addr-1]); + + aa.groupid = AR.grp + 0x8000u; + + aa.setdesc(AR.comment); + aa.setechoid(AR.aname); + aa.setorigin(AR.origin); + + AddNewArea(aa); + } + } + + fclose(fp); + } + } + + throw_delete(CF); +} +#endif + + +// ------------------------------------------------------------------ + +void gareafile::ReadIMail(char* tag) { + + FILE* fp; + char* ptr; + byte imver[2]; + byte imstructver[2]; + char options[80]; + Path impath, file; + + *file = NUL; + *impath = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(impath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*impath == NUL) { + ptr = getenv("IMAIL"); + if(ptr) + AddBackslash(strcpy(impath, ptr)); + } + if(*impath == NUL) + strcpy(impath, areapath); + + MakePathname(file, impath, "imail.cf"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + fread(imver, 2, 1, fp); + fread(imstructver, 2, 1, fp); + fclose(fp); + if((imver[0] >= 1) and (imver[1] >= 60) and (imstructver[0] >= 4)) { + switch(imstructver[0]) { + case 4: + ReadIMail160(options, file, impath); + return; + case 5: + ReadIMail170(options, file, impath); + return; + #ifdef HAVE_IM18X + case 6: + ReadIMail185(options, file, impath); + return; + #endif + } + } + cout << "* Error: IMAIL " << imver[0] << '.' << setfill('0') << setw(2) << imver[1] << " (structure revision " << imstructver[0] << '.' << setfill('0') << setw(2) << imstructver[1] << ") is not supported - Skipping." << endl; + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxinter.cpp b/goldlib/gcfg/gxinter.cpp new file mode 100644 index 0000000..3162b76 --- /dev/null +++ b/goldlib/gcfg/gxinter.cpp @@ -0,0 +1,223 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from InterMail 2.26+ +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadInterMail(char* tag) { + + Path _path; + char options[80]; + + *_path = NUL; + strcpy(options, tag); + + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(_path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*_path == NUL) { + ptr = getenv("IM"); + if(ptr) + PathCopy(_path, ptr); + } + if(*_path == NUL) + strcpy(_path, areapath); + + const char* _file = AddPath(_path, "fd.sys"); + + gfile fp; + fp.fopen(_file, "rb"); + if(fp.isopen()) { + + _ctl* ctl = (_ctl*)throw_calloc(1, sizeof(_ctl)); + + if(not quiet) + cout << "* Reading " << _file << endl; + + fp.fread(ctl, sizeof(_ctl)); + + if(not memcmp(ctl->fingerprint, "JoHo", 5) and (ctl->sysrev == IM_THISREV)) { + + fp.fclose(); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(ctl->e.qbase)); + + AreaCfg aa; + + aa.reset(); + aa.aka = CAST(ftn_addr, ctl->t.newaka[0]); + aa.type = GMB_NET; + aa.msgbase = GMB_OPUS; + aa.attr.pvt(ctl->e.msgbits & MSGPRIVATE); + aa.attr.cra(ctl->e.msgbits & MSGCRASH); + aa.attr.k_s(ctl->e.msgbits & MSGKILL); + aa.attr.r_o(ctl->e.netfolderflags & EDREADONLY); + aa.setpath(ctl->s.mailpath); + aa.setdesc("InterMail Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + + aa.reset(); + aa.aka = CAST(ftn_addr, ctl->t.newaka[ctl->e.dupes.useaka]); + aa.type = GMB_ECHO; + switch(ctl->e.dupes.ftype) { + case F_MSG: aa.msgbase = GMB_OPUS; break; + case F_HUDSON: aa.msgbase = GMB_HUDSON; break; + case F_PCB15: aa.msgbase = GMB_PCBOARD; break; + case F_JAM: aa.msgbase = GMB_JAM; break; + } + aa.attr.r_o(ctl->e.dupes.behave & EDREADONLY); + aa.board = ctl->e.dupes.board; + aa.setpath(ctl->e.dupes.path); + aa.setdesc(ctl->e.dupes.title); + aa.setechoid(ctl->e.dupes.areatag); + aa.setorigin(ctl->e.origin[ctl->e.dupes.origin]); + AddNewArea(aa); + + aa.reset(); + aa.aka = CAST(ftn_addr, ctl->t.newaka[ctl->e.badecho.useaka]); + aa.type = GMB_ECHO; + switch(ctl->e.badecho.ftype) { + case F_MSG: aa.msgbase = GMB_OPUS; break; + case F_HUDSON: aa.msgbase = GMB_HUDSON; break; + case F_PCB15: aa.msgbase = GMB_PCBOARD; break; + case F_JAM: aa.msgbase = GMB_JAM; break; + } + aa.attr.r_o(ctl->e.badecho.behave & EDREADONLY); + aa.board = ctl->e.badecho.board; + aa.setpath(ctl->e.badecho.path); + aa.setdesc(ctl->e.badecho.title); + aa.setechoid(ctl->e.badecho.areatag); + aa.setorigin(ctl->e.origin[ctl->e.badecho.origin]); + AddNewArea(aa); + + _file = AddPath(ctl->s.systempath, "imfolder.cfg"); + if(fexist(_file)) { + + _file = AddPath(ctl->s.systempath, "imfolder.cfg"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + + if(not quiet) + cout << "* Reading " << _file << endl; + + FOLDER* _folder = (FOLDER*)throw_calloc(1, sizeof(FOLDER)); + + while(fp.fread(_folder, sizeof(FOLDER)) == 1) { + + aa.reset(); + switch(_folder->ftype) { + case F_MSG: aa.msgbase = GMB_OPUS; break; + case F_HUDSON: aa.msgbase = GMB_HUDSON; break; + case F_PCB15: aa.msgbase = GMB_PCBOARD; break; + case F_JAM: aa.msgbase = GMB_JAM; break; + default: continue; + } + long _behave = _folder->behave; + if(not (DELETED & _behave)) { + aa.aka = CAST(ftn_addr, ctl->t.newaka[_folder->useaka]); + if(_behave & F_NETMAIL) + aa.type = GMB_NET; + else if(_behave & LOCAL) + aa.type = GMB_LOCAL; + else if(_behave & ECHOMAIL) + aa.type = GMB_ECHO; + aa.board = _folder->board; + aa.setpath(_folder->path); + aa.attr.pvt(_behave & PRIVATE); + aa.attr.r_o(_behave & READONLY); + aa.setechoid(_folder->areatag); + aa.setdesc(_folder->title); + aa.setorigin(ctl->e.origin[_folder->origin]); + AddNewArea(aa); + } + } + throw_free(_folder); + fp.fclose(); + } + } + else { + + _file = AddPath(ctl->s.systempath, "folder.cfg"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + + if(not quiet) + cout << "* Reading " << _file << endl; + + OLDFOLDER* _folder = (OLDFOLDER*)throw_calloc(1, sizeof(OLDFOLDER)); + + while(fp.fread(_folder, sizeof(OLDFOLDER)) == 1) { + long _behave = _folder->behave; + if(not (DELETED & _behave)) { + + aa.reset(); + aa.aka = CAST(ftn_addr, ctl->t.newaka[_folder->useaka]); + if(_behave & F_NETMAIL) + aa.type = GMB_NET; + else if(_behave & LOCAL) + aa.type = GMB_LOCAL; + else if(_behave & ECHOMAIL) + aa.type = GMB_ECHO; + aa.msgbase = (_behave & BOARDTYPE) ? GMB_HUDSON : GMB_OPUS; + if(aa.msgbase == GMB_HUDSON) + aa.board = _folder->board; + else + aa.setpath(_folder->path); + aa.attr.pvt(_behave & PRIVATE); + aa.attr.r_o(_behave & READONLY); + aa.setdesc(_folder->title); + aa.setorigin(ctl->e.origin[_folder->origin]); + AddNewArea(aa); + } + } + throw_free(_folder); + fp.fclose(); + } + } + } + else { + cout << "* Error: InterMail revision " << setfill('0') << setw(4) << hex << ctl->sysrev << "h is not supported - Skipping." << endl; + } + throw_free(ctl); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxlora.cpp b/goldlib/gcfg/gxlora.cpp new file mode 100644 index 0000000..ca24cb8 --- /dev/null +++ b/goldlib/gcfg/gxlora.cpp @@ -0,0 +1,202 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from LoraBBS (2.33 and 2.40). +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadLoraBBS(char* tag) { + + Path _path; + *_path = NUL; + char options[80]; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(_path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*_path == NUL) { + ptr = getenv("LORA"); + if(ptr) + AddBackslash(strcpy(_path, ptr)); + } + if(*_path == NUL) { + ptr = getenv("LORABBS"); + if(ptr) + AddBackslash(strcpy(_path, ptr)); + } + if(*_path == NUL) + strcpy(_path, areapath); + + gfile fp; + const char* _file = AddPath(_path, "config.dat"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + + if(not quiet) + cout << "* Reading " << _file << endl; + + _configuration* cfg = (_configuration*)throw_calloc(1, sizeof(_configuration)); + fp.fread(cfg, sizeof(_configuration)); + fp.fclose(); + + //CfgUsername(cfg->sysop); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->quick_msgpath)); + if(*goldbasepath == NUL) + PathCopy(goldbasepath, MapPath(cfg->quick_msgpath)); + + AreaCfg aa; + + // Netmail *.MSG + if(not strblank(cfg->netmail_dir)) { + aa.reset(); + aa.msgbase = GMB_OPUS; + aa.type = GMB_NET; + aa.aka = CAST(ftn_addr, cfg->alias[0]); + aa.setpath(cfg->netmail_dir); + aa.setdesc("LoraBBS Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // Bad *.MSG + if(not strblank(cfg->bad_msgs)) { + aa.reset(); + aa.msgbase = GMB_OPUS; + aa.type = GMB_ECHO; + aa.aka = CAST(ftn_addr, cfg->alias[0]); + aa.setpath(cfg->bad_msgs); + aa.setdesc("LoraBBS Bad Echo"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + // Dupes *.MSG + if(not strblank(cfg->dupes)) { + aa.reset(); + aa.msgbase = GMB_OPUS; + aa.type = GMB_ECHO; + aa.aka = CAST(ftn_addr, cfg->alias[0]); + aa.setpath(cfg->dupes); + aa.setdesc("LoraBBS Duplicate Msgs"); + aa.setautoid("ECHO_DUPES"); + AddNewArea(aa); + } + + // Personal mail *.MSG + if(cfg->save_my_mail and not strblank(cfg->my_mail)) { + aa.reset(); + aa.msgbase = GMB_OPUS; + aa.type = GMB_ECHO; + aa.aka = CAST(ftn_addr, cfg->alias[0]); + aa.setpath(cfg->my_mail); + aa.setdesc("LoraBBS Personal Mail"); + aa.setautoid("ECHO_PERSONAL"); + AddNewArea(aa); + } + + _file = AddPath(_path, "sysmsg.dat"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + fp.setvbuf(NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << _file << endl; + + _sysmsg* sysmsg = (_sysmsg*)throw_calloc(1, sizeof(_sysmsg)); + + while(fp.fread(sysmsg, sizeof(_sysmsg)) == 1) { + + if(sysmsg->passthrough) + continue; + + aa.reset(); + + if(sysmsg->gold_board) { + aa.msgbase = GMB_GOLDBASE; + aa.board = sysmsg->gold_board; + } + else if(sysmsg->quick_board) { + aa.msgbase = GMB_HUDSON; + aa.board = sysmsg->quick_board; + } + else if(sysmsg->pip_board) { + // Not supported (yet) + continue; + } + else if(sysmsg->squish) { + aa.msgbase = GMB_SQUISH; + aa.setpath(sysmsg->msg_path); + } + else { + aa.msgbase = GMB_OPUS; + aa.setpath(sysmsg->msg_path); + } + + if(sysmsg->netmail) { + aa.type = GMB_NET; + aa.attr = attribsnet; + } + else if(sysmsg->echomail) { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + else { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + + aa.attr.pvt(sysmsg->doprivate); + + aa.aka = CAST(ftn_addr, cfg->alias[sysmsg->use_alias]); + + aa.setdesc(sysmsg->msg_name); + aa.setechoid(sysmsg->echotag); + aa.setorigin(sysmsg->origin); + + AddNewArea(aa); + } + throw_free(sysmsg); + fp.fclose(); + } + throw_free(cfg); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxmax3.cpp b/goldlib/gcfg/gxmax3.cpp new file mode 100644 index 0000000..303bca9 --- /dev/null +++ b/goldlib/gcfg/gxmax3.cpp @@ -0,0 +1,246 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Maximus 3.xx +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read areas from Maximus 3.xx + +void gareafile::ReadMaximus3(char* mxpath, char* areafile, char* options) { + + FILE* fp; + AreaCfg aa; + Path prmfile; + + MakePathname(prmfile, mxpath, "max.prm"); + + fp = fsopen(prmfile, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << areafile << endl; + + m_pointers* prmp = (m_pointers*)throw_calloc(1, sizeof(m_pointers)); + m_pointers& prm = *prmp; + fread(prmp, sizeof(m_pointers), 1, fp); + long heapsz = fsize(fp) - prm.heap_offset; + char* offsets = (char*)throw_calloc(1, (uint)heapsz); + fread(offsets, (uint)heapsz, 1, fp); + fclose(fp); + + if(*squishuserpath == NUL) + strcat(PathCopy(squishuserpath, PRM(user_file)), ".bbs"); + + strcpy(stpcpy(areafile, PRM(marea_name)), ".dat"); + + fp = fsopen(areafile, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 32000); + + if(not quiet) + cout << "* Reading " << areafile << endl; + + long areasize = fsize(fp)-4; + + dword marea_id; + fread(&marea_id, sizeof(dword), 1, fp); + if(marea_id == MAREA_ID) { + + int arearecsize = 1024; + char* arearec = (char*)throw_malloc(arearecsize); + _msgarea* area = (_msgarea*)arearec; + + while(areasize > 0) { + + // Get the record sizes + fread(arearec, 6, 1, fp); + + // Expand the allocation if necessary + int needsize = area->cbArea + (area->num_override*sizeof(_ovride)) + area->cbHeap; + if(needsize > arearecsize) { + arearecsize = needsize; + arearec = (char*)throw_realloc(arearec, arearecsize); + area = (_msgarea*)arearec; + } + + // Get the rest of this record + fread(arearec+6, needsize-6, 1, fp); + areasize -= needsize; + + // Setup zstr heap pointer + char* zstrheap = arearec + (needsize - area->cbHeap); + #define ZSTR(s) (zstrheap+area->s) + + if(area->attribs & MA_DIVBEGIN) + continue; + + if(strblank(ZSTR(path))) + continue; + + aa.reset(); + switch(area->type) { + case MSGTYPE_SQUISH: + aa.msgbase = GMB_SQUISH; + break; + case MSGTYPE_SDM: + aa.msgbase = fidomsgtype; + break; + default: + continue; + } + + if(ZSTR(path)[1] != ':') { + Path areapath; + strcpy(stpcpy(areapath, mxpath), ZSTR(path)); + aa.setpath(areapath); + } + else { + aa.setpath(ZSTR(path)); + } + + aa.aka = CAST(ftn_addr, area->primary); + aa.setdesc(*ZSTR(descript) ? ZSTR(descript) : ZSTR(name)); + aa.setechoid(ZSTR(echo_tag)); + aa.setorigin(ZSTR(origin)); + if(area->attribs & (MA_ECHO|MA_CONF)) { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + else if(area->attribs & MA_NET) { + aa.type = GMB_NET; + aa.attr = attribsnet; + } + else { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + + if(area->attribs & MA_READONLY) + aa.attr.r_o1(); + + AddNewArea(aa); + } + + throw_free(arearec); + + fclose(fp); + } + } + + throw_free(offsets); + throw_free(prmp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from Maximus BBS + +void gareafile::ReadMaximus(char* tag) { + + char options[80]; + int is_maximus3 = false; + Path maximuspath, mxpath, areafile, path; + char* ptr; + + *maximuspath = NUL; + char* mptr = getenv("MAXIMUS"); + if(mptr) + extractdirname(maximuspath, mptr); + + *mxpath = NUL; + ptr = maximuspath; + if(ptr) + AddBackslash(strcpy(mxpath, ptr)); + else + strcpy(mxpath, areapath); + + // Get the path or filename from the parameters + *path = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + + // If no path or file was given, try the env.var + if(*path == NUL) { + ptr = maximuspath; + if(ptr) + AddBackslash(strcpy(path, ptr)); + else + strcpy(path, areapath); + } + + // Is it a directory? + if(is_dir(path)) { + // Yes, so we use it + strcpy(mxpath, path); + MakePathname(areafile, mxpath, "marea.dat"); + if(fexist(areafile)) + is_maximus3 = true; + else + MakePathname(areafile, mxpath, "area.dat"); + } // Is it a file? + else if(fexist(path)) { + // Yes, so we split it up to get the path + strcpy(areafile, path); + extractdirname(mxpath, path); + } + else { + // Nonsense path or file given, so use defaults. (We ought to warn, but we are lazy..) + ptr = maximuspath; + if(ptr) + AddBackslash(strcpy(mxpath, ptr)); + else + strcpy(mxpath, areapath); + MakePathname(areafile, mxpath, "marea.dat"); + if(fexist(areafile)) + is_maximus3 = true; + else + MakePathname(areafile, mxpath, "area.dat"); + } + + if(*squishuserpath == NUL) + PathCopy(squishuserpath, mxpath); + + if(is_maximus3) + ReadMaximus3(mxpath, areafile, options); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxme2.cpp b/goldlib/gcfg/gxme2.cpp new file mode 100644 index 0000000..b940b00 --- /dev/null +++ b/goldlib/gcfg/gxme2.cpp @@ -0,0 +1,110 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from ME2 +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ +// Read AREADESC.ME2 and AREAS.BBS + +void gareafile::ReadME2(char* tag) { + + AreaCfg aa; + FILE* fp; + Path file; + char* ptr; + char* ptr2; + char* desc; + char* group; + char* echoid; + char buf[256], options[80]; + + if(*tag) { + ptr2 = strskip_wht(tag); + if(*ptr2) { + ptr = ptr2; + ptr2 = strskip_txt(ptr2); + if(*ptr2) *ptr2++ = NUL; + strcpy(options, ptr2); + strcpy(file, ptr); + + MakePathname(file, areapath, file); + + fp = fsopen(file, "rt", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fgets(buf, 255, fp)) { + + ptr = strbtrim(buf); + if(*ptr and *ptr != '*' and *ptr != ';') { + if(strnieql(ptr, "LOCAL", 5) and (ptr[5] == ' ' or ptr[5] == HT)) { + + // Found local area - add it + aa.reset(); + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + aa.msgbase = fidomsgtype; + ptr = strskip_wht(ptr+5); + ptr2 = strskip_to(++ptr, '\''); + if(*ptr2) *ptr2++ = NUL; + aa.setdesc(ptr); + ptr = strskip_wht(ptr2); + ptr2 = strskip_to(++ptr2, '\''); + if(*ptr2) *ptr2 = NUL; + aa.setpath(ptr); + AddNewArea(aa); + } + else { + ptr2 = strskip_txt(ptr); + if(*ptr2) *ptr2++ = NUL; + echoid = ptr; + ptr2 = strskip_wht(ptr2); + ptr = ++ptr2; + ptr2 = strskip_to(ptr2, '\''); + if(*ptr2) *ptr2++ = NUL; + desc = ptr; + ptr = strskip_wht(ptr2); + ptr2 = strskip_to(++ptr, '\''); + if(*ptr2) *ptr2 = NUL; + group = ptr; + sprintf(file, "%-33s%-5s", desc, group); + echolist.AddDesc(echoid, file); + } + } + } + ReadAreasBBS(options); + } + } + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxopus.cpp b/goldlib/gcfg/gxopus.cpp new file mode 100644 index 0000000..eeeca2d --- /dev/null +++ b/goldlib/gcfg/gxopus.cpp @@ -0,0 +1,159 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Opus 1.1x/1.7x +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#undef _NORMAL +#include // Structures for Opus 1.1x SYSTEM??.DAT + + +// ------------------------------------------------------------------ +// Read Opus + +void gareafile::ReadOpus(char* tag) { + + FILE* fp; + AreaCfg aa; + char* ptr; + _msgsys msgsys; + _systemdat sysdat; + Path oppath, file; + char buf[256], options[80]; + + *oppath = NUL; + strcpy(options, tag); + + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(oppath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*oppath == NUL) { + ptr = getenv("OPUS"); + if(ptr) + AddBackslash(strcpy(oppath, ptr)); + } + if(*oppath == NUL) + strcpy(oppath, areapath); + + MakePathname(file, oppath, "sysmsg.dat"); + + if(fexist(file)) { + + // Found Opus 1.7x config files + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(&msgsys, sizeof(_msgsys), 1, fp) == 1) { + + aa.reset(); + + memset(buf, 0, sizeof(buf)); + fread(buf, msgsys.Path_Len, 1, fp); + aa.setpath(buf); + memset(buf, 0, sizeof(buf)); + fread(buf, msgsys.Title_Len, 1, fp); + aa.setdesc(buf); + fread(buf, msgsys.Barricade_Len, 1, fp); + memset(buf, 0, sizeof(buf)); + fread(buf, msgsys.Origin_Len, 1, fp); + aa.setorigin(buf); + fseek(fp, (long)msgsys.Domain_Len, SEEK_CUR); + fseek(fp, (long)msgsys.Menu_Len, SEEK_CUR); + fseek(fp, (long)msgsys.Vol_Len, SEEK_CUR); + fseek(fp, (long)msgsys.Help_Len, SEEK_CUR); + fseek(fp, (long)msgsys.Scan_Len*(long)sizeof(struct _ascan), SEEK_CUR); + fseek(fp, (long)msgsys.Other_Len, SEEK_CUR); + + aa.msgbase = fidomsgtype; + aa.type = ((msgsys.Attrib & SYSMAIL) ? GMB_NET : (msgsys.Attrib & _ECHOMAIL) ? GMB_ECHO : GMB_LOCAL); + aa.attr = ((msgsys.Attrib & SYSMAIL) ? attribsnet : (msgsys.Attrib & _ECHOMAIL) ? attribsecho : attribslocal); + aa.setechoid(*msgsys.Echo_Name ? msgsys.Echo_Name : msgsys.Area_Name); + + if(msgsys.Net) { + aa.aka.zone = msgsys.Zone; + aa.aka.net = msgsys.Net; + aa.aka.node = msgsys.Node; + aa.aka.point = msgsys.Point; + } + + AddNewArea(aa); + } + + fclose(fp); + } + } + else { + + // Try for the old 1.1x files + + gposixdir d(oppath); + const gdirentry *de; + if(d.ok) { + while((de = d.nextentry("system*.dat", true)) != NULL) { + + MakePathname(file, oppath, de->name.c_str()); + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(&sysdat, sizeof(_systemdat), 1, fp); + if(*sysdat.msgpath and *sysdat.msgtitle) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.setpath(sysdat.msgpath); + aa.setdesc(sysdat.msgtitle); + aa.setechoid(sysdat.EchoName); + aa.type = ((sysdat.attrib & SYSMAIL) ? GMB_NET : (sysdat.attrib & _ECHOMAIL) ? GMB_ECHO : GMB_LOCAL); + aa.attr = ((sysdat.attrib & SYSMAIL) ? attribsnet : (sysdat.attrib & _ECHOMAIL) ? attribsecho : attribslocal); + AddNewArea(aa); + } + + fclose(fp); + } + } + } + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxpcb.cpp b/goldlib/gcfg/gxpcb.cpp new file mode 100644 index 0000000..d6310ab --- /dev/null +++ b/goldlib/gcfg/gxpcb.cpp @@ -0,0 +1,361 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from PCBoard. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadPCBoard(char* tag) { + + AreaCfg aa; + Path _path; + char _options[80]; + Path _usersidxpath; + Path _userspath; + Path _cnamespath; + Path _fidopath; + + PcbFidoArea* areap = NULL; + PcbFidoDirectories* dirp = NULL; + PcbFidoAddress* akap = NULL; + int akanumrecs = 0; + int numareas = 0; + + PcbDirectories* dir3 = NULL; + PcbAreasDat* area3 = NULL; + PcbAkasDat* aka3 = NULL; + PcbOriginsDat* origin3 = NULL; + + word fido_version = 0; + + *_fidopath = NUL; + strcpy(_path, pcboardpath); + strcpy(_options, tag); + + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(_path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*_path == NUL) { + ptr = getenv("PCBOARD"); + if(ptr) + AddBackslash(strcpy(_path, ptr)); + } + if(*_path == NUL) + strcpy(_path, areapath); + + if(*pcboardpath == NUL) + strcpy(pcboardpath, _path); + + gfile fp; + const char* _file = AddPath(_path, "pcboard.dat"); + fp.fopen(_file, "rt"); + if(fp.isopen()) { + + if(not quiet) + cout << "* Reading " << _file << endl; + + int _line = 0; + + char _buf[256]; + while(fp.fgets(_buf, sizeof(_buf))) { + _line++; + switch(_line) { + case 28: // Location of User INDEX Files + strxcpy(_usersidxpath, strbtrim(_buf), GMAXPATH); + break; + case 29: // Name/Location of USERS File + strxcpy(_userspath, strbtrim(_buf), GMAXPATH); + break; + case 31: // Name/Location of CNAMES File + strxcpy(_cnamespath, strbtrim(_buf), GMAXPATH); + break; + case 324: // Path to FidoNet config files + strxcpy(_fidopath, strbtrim(_buf), GMAXPATH); + break; + } + } + + fp.fclose(); + + if(*_fidopath) { + const char* _file = AddPath(_fidopath, "pcbfido.cfg"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + + if(not quiet) + cout << "* Reading " << _file << endl; + + // Get configuration file version + fp.fread(&fido_version, 2); + + if(fido_version == 2) { + + word numrecs = 0; + + // Get areas + fp.fread(&numrecs, 2); + numareas = numrecs; + areap = (PcbFidoArea*)throw_calloc(1+numrecs, sizeof(PcbFidoArea)); + fp.fread(areap, sizeof(PcbFidoArea), numrecs); + + // Skip archivers + fp.fseek(sizeof(PcbFidoArchivers), SEEK_CUR); + + // Get directories + dirp = (PcbFidoDirectories*)throw_calloc(1, sizeof(PcbFidoDirectories)); + fp.fread(dirp, sizeof(PcbFidoDirectories)); + + // Skip EMSI profile + fp.fseek(sizeof(PcbFidoEmsiData), SEEK_CUR); + + // Get akas + fp.fread(&numrecs, 2); + akanumrecs = numrecs; + akap = (PcbFidoAddress*)throw_calloc(1+numrecs, sizeof(PcbFidoAddress)); + fp.fread(akap, sizeof(PcbFidoAddress), numrecs); + int akano = 0; + while(akano < numrecs) { + CfgAddress(akap[akano].nodestr); + akano++; + } + } + else if(fido_version == 3) { + + dir3 = (PcbDirectories*)throw_calloc(1, sizeof(PcbDirectories)); + fp.fread(dir3, sizeof(PcbDirectories)); + fp.fclose(); + + _file = AddPath(_fidopath, "areas.dat"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + if(not quiet) + cout << "* Reading " << _file << endl; + word cfgver = 0; + fp.fread(&cfgver, 2); + if(cfgver == 3) { + word numrecs = (word)(fp.filelength() / sizeof(PcbAreasDat)); + area3 = (PcbAreasDat*)throw_calloc(1+numrecs, sizeof(PcbAreasDat)); + fp.fread(area3, sizeof(PcbAreasDat), numrecs); + numareas = numrecs; + } + fp.fclose(); + } + + _file = AddPath(_fidopath, "akas.dat"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + if(not quiet) + cout << "* Reading " << _file << endl; + word cfgver = 0; + fp.fread(&cfgver, 2); + if(cfgver == 3) { + word numrecs = (word)(fp.filelength() / sizeof(PcbAkasDat)); + akanumrecs = numrecs; + aka3 = (PcbAkasDat*)throw_calloc(1+numrecs, sizeof(PcbAkasDat)); + fp.fread(aka3, sizeof(PcbAkasDat), numrecs); + int akano = 0; + while(akano < numrecs) { + char abuf[40]; + CfgAddress(aka3[akano].addr.make_string(abuf)); + akano++; + } + } + fp.fclose(); + } + + _file = AddPath(_fidopath, "origins.dat"); + fp.fopen(_file, "rb"); + if(fp.isopen()) { + if(not quiet) + cout << "* Reading " << _file << endl; + word cfgver = 0; + fp.fread(&cfgver, 2); + if(cfgver == 3) { + word numrecs = (word)(fp.filelength() / sizeof(PcbOriginsDat)); + origin3 = (PcbOriginsDat*)throw_calloc(1+numrecs, sizeof(PcbOriginsDat)); + fp.fread(origin3, sizeof(PcbOriginsDat), numrecs); + } + fp.fclose(); + } + } + + fp.fclose(); + } + + Path netmailpath; + *netmailpath = NUL; + if(dirp) + strcpy(netmailpath, dirp->outgoing_msg); + else if(dir3) + strcpy(netmailpath, dir3->outgoing_msg); + if(*netmailpath) { + aa.reset(); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + if(fido_version == 2) + aa.aka.reset(akap[0].nodestr); + else if(fido_version == 3) { + for(int n=0; nname and *_cnames->msgfile) { + aa.reset(); + aa.msgbase = GMB_PCBOARD; + switch(_cnamesadd->conftype) { + case PCBCONFTYPE_EMAIL: + case PCBCONFTYPE_USENETMOD: + aa.type = GMB_EMAIL; + aa.attr = attribsemail; + break; + case PCBCONFTYPE_USENETJUNK: + case PCBCONFTYPE_USENETPUB: + aa.type = GMB_NEWSGROUP; + aa.attr = attribsnews; + break; + case PCBCONFTYPE_FIDOCONF: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + case PCBCONFTYPE_NORMAL: + default: + if(_cnames->echomail) { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + else { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + } + if(_cnamesadd->readonly) + aa.attr.r_o1(); + if(_cnames->privmsgs) + aa.attr.pvt1(); + aa.board = confno; + aa.setpath(_cnames->msgfile); + char namebuf[61]; + strcpy(stpcpy(namebuf, _cnames->name), _cnamesadd->name2); + aa.setdesc(namebuf); + strchg(namebuf, ' ', '_'); + aa.setechoid(namebuf); + int areano = 0; + while(areano < numareas) { + if(fido_version == 2) { + if(areap[areano].pcbconference == confno) { + strchg(areap[areano].areaname, ' ', '_'); + aa.setechoid(areap[areano].areaname); + aa.aka.set(areap[areano].defaultaka); + aa.setorigin(areap[areano].origin); + aa.setpath(areap[areano].messages); + break; + } + } + else if(fido_version == 3) { + if(area3[areano].confno == confno) { + aa.setechoid(area3[areano].areatag); + aa.aka = aka3[area3[areano].aka].addr; + aa.setorigin(origin3[area3[areano].origin].origin); + break; + } + } + areano++; + } + if(strieql(aa.echoid, "NETMAIL")) { + aa.type = GMB_NET; + aa.attr = attribsnet; + } + AddNewArea(aa); + } + confno++; + } + + throw_free(_cnamesadd); + throw_free(_cnames); + + fp2.fclose(); + } + + fp.fclose(); + } + } + + throw_free(origin3); + throw_free(area3); + throw_free(dir3); + throw_free(aka3); + throw_free(areap); + throw_free(dirp); + throw_free(akap); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxportal.cpp b/goldlib/gcfg/gxportal.cpp new file mode 100644 index 0000000..5fa8e81 --- /dev/null +++ b/goldlib/gcfg/gxportal.cpp @@ -0,0 +1,179 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Portal of Power configuration reader. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadPortal(char* tag) { + + FILE* fp; + char* ptr; + char* ptr2; + AreaCfg aa; + int poptask = 0; + Path path, file; + char options[80]; + + *file = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*file == NUL) { + ptr = getenv("POPCMDLINE"); + if(ptr) { + while(*ptr) { + if(strnieql(ptr, "-T", 2)) + poptask = atoi(ptr+2); + else if(strnieql(ptr, "-H", 2)) { + ptr2 = strskip_txt(strcpy(path, ptr+2)); + *ptr2 = NUL; + AddBackslash(path); + } + else if(*ptr != '-' and *ptr != '/') { + ptr2 = strskip_txt(strcpy(file, ptr)); + *ptr2 = NUL; + } + ptr = strskip_wht(strskip_txt(ptr)); + } + } + } + if(*path == NUL) + strcpy(path, areapath); + + ConfigP popcfg = new ConfigT; throw_new(popcfg); + + if(*file == NUL) { + if(poptask) + sprintf(file, "portal%02u.cfg", poptask); + else + strcpy(file, "portal.cfg"); + MakePathname(file, path, file); + } + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + + fread(popcfg, sizeof(ConfigT), 1, fp); + fclose(fp); + + // Netmail + if(popcfg->MailScanner.NetMailBoard and popcfg->MailScanner.NetMailBoard < 201) { + aa.reset(); + aa.aka = CAST(ftn_addr, popcfg->Adresses[popcfg->MainAdrNum]); + aa.msgbase = GMB_HUDSON; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.board = popcfg->MailScanner.NetMailBoard; + strcpy(aa.desc, "Portal Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + else if(not strblank(popcfg->MailScanner.NetMailDir)) { + aa.reset(); + aa.aka = CAST(ftn_addr, popcfg->Adresses[popcfg->MainAdrNum]); + aa.msgbase = fidomsgtype; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.setpath(popcfg->MailScanner.NetMailDir); + aa.setdesc("Portal Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + // *.MSG badmsgs + if(not strblank(popcfg->MailScanner.BadMsgs)) { + aa.reset(); + aa.aka = CAST(ftn_addr, popcfg->Adresses[popcfg->MainAdrNum]); + aa.msgbase = fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.setpath(popcfg->MailScanner.BadMsgs); + aa.setdesc("Portal Bad Msgs"); + aa.setautoid("ECHO_BAD"); + AddNewArea(aa); + } + + // *.MSG dupes + if(not strblank(popcfg->MailScanner.SaveDupesDir)) { + aa.reset(); + aa.aka = CAST(ftn_addr, popcfg->Adresses[popcfg->MainAdrNum]); + aa.msgbase = fidomsgtype; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.setpath(popcfg->MailScanner.SaveDupesDir); + aa.setdesc("Portal Saved Dupes"); + aa.setautoid("ECHO_DUPES"); + AddNewArea(aa); + } + + AreasTypeP poparea = new AreasTypeT; throw_new(poparea); + + MakePathname(file, path, "portal.are"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + + while(fread(poparea, sizeof(AreasTypeT), 1, fp) == 1) { + + if(*poparea->Directory != 0) { + + aa.reset(); + aa.aka = CAST(ftn_addr, poparea->UsedAka ? popcfg->Adresses[popcfg->MainAdrNum] : popcfg->Adresses[poparea->UsedAka]); + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.msgbase = fidomsgtype; + aa.setdesc(STRNP2C(poparea->Description)); + aa.setechoid(STRNP2C(poparea->EchoNames[0])); + aa.setorigin(STRNP2C(poparea->Origin)); + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_delete(poparea); + } + + throw_delete(popcfg); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxprobrd.cpp b/goldlib/gcfg/gxprobrd.cpp new file mode 100644 index 0000000..0c026c2 --- /dev/null +++ b/goldlib/gcfg/gxprobrd.cpp @@ -0,0 +1,157 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from ProBoard. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadProBoard(char* tag) { + + FILE* fp; + AreaCfg aa; + char options[80]; + Path file, path; + + *path = NUL; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("PB"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + if(*path == NUL) + strcpy(path, areapath); + + Config* cfg = (Config*)throw_calloc(1, sizeof(Config)); + MakePathname(file, path, "config.pro"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(cfg, sizeof(Config), 1, fp); + + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->msgpath)); + + fclose(fp); + } + + MakePathname(file, path, "aka.pro"); + uint akasz = (uint)GetFilesize(file); + ftn_addr* aka = (ftn_addr*)throw_calloc(1, akasz+sizeof(ftn_addr)); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(aka, akasz, 1, fp); + fclose(fp); + } + + MsgAreas* area = (MsgAreas*)throw_calloc(1, sizeof(MsgAreas)); + MakePathname(file, path, "msgareas.pb"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(area, sizeof(MsgAreas), 1, fp) == 1) { + aa.reset(); + switch(area->msgkind) { + case MSGKIND_LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case MSGKIND_NET: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case MSGKIND_ECHO: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + case MSGKIND_PVTECHO: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.attr.pvt1(); + break; + } + if(area->msgtype == MSGTYPE_PVT) + aa.attr.pvt1(); + switch(area->msgbasetype) { + case MSGBASE_HUDSON: + aa.msgbase = GMB_HUDSON; + aa.board = area->areanum; + break; + case MSGBASE_SQUISH: + aa.msgbase = GMB_SQUISH; + aa.setpath(MapPath(area->path)); + break; + case MSGBASE_SDM: + aa.msgbase = GMB_OPUS; + aa.setpath(MapPath(area->path)); + break; + case MSGBASE_JAM: + aa.msgbase = GMB_JAM; + aa.setpath(MapPath(area->path)); + break; + } + aa.aka = aka[area->aka]; + aa.setdesc(area->name); + aa.setechoid(area->echotag); + aa.setorigin(area->origin); + AddNewArea(aa); + } + + fclose(fp); + } + + throw_free(area); + throw_free(aka); + throw_free(cfg); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxqecho.cpp b/goldlib/gcfg/gxqecho.cpp new file mode 100644 index 0000000..a2ddfd4 --- /dev/null +++ b/goldlib/gcfg/gxqecho.cpp @@ -0,0 +1,109 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1999 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from QEcho (by Eugene Sorochinsky) +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadQEchoFile(char* file, char* options, char* origin) { + + AreaCfg aa; + char buf[512]; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fgets(buf, sizeof(buf), fp)) { + + char* ptr = strtok(buf, " \t"); + aa.reset(); + aa.groupid = atoi(ptr); + + if((ptr = strtok(NULL, " \t")) != NULL) { + if(*ptr == '*') { + // skip ExpireDays + if((ptr = strtok(NULL, " \t")) == NULL) + continue; + if((ptr = strtok(NULL, " \t")) == NULL) + continue; + } + aa.type = GMB_ECHO; + aa.setechoid(ptr); + if((ptr = strtok(NULL, " \t")) != NULL) + if(not strieql("Passthrough", ptr)) { + aa.setpath(MapPath(ptr)); + aa.msgbase = GMB_JAM; + if((ptr = strtok(NULL, " \t")) != NULL) + if((*ptr == '*') and ((ptr = strtok(NULL, " \t")) != NULL)) { + CfgAddress(ptr); + aa.aka.set(ptr); + aa.attr = attribsecho; + aa.setorigin(origin); + AddNewArea(aa); + } + } + } + } + fclose(fp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from QEcho (echomail processor) + +void gareafile::ReadQEcho(char* tag) { + + char origin[80]; + char options[80]; + Path file; + + *origin = NUL; + *file = NUL; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') + strcpy(file, ptr); + ptr = strtok(NULL, " \t"); + } + + if(not *file) + strcpy(file, "/etc/qecho/AreaList"); + + ReadQEchoFile(file, options, origin); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxqfront.cpp b/goldlib/gcfg/gxqfront.cpp new file mode 100644 index 0000000..63ca23a --- /dev/null +++ b/goldlib/gcfg/gxqfront.cpp @@ -0,0 +1,105 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from QFront. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadQFront(char* tag) { + + FILE* fp; + AreaCfg aa; + char options[80]; + Path file, path; + + *path = NUL; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("QFRONT"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + if(*path == NUL) + strcpy(path, areapath); + + OriginLineRecord* origin = (OriginLineRecord*)throw_calloc(1, sizeof(OriginLineRecord)); + MakePathname(file, path, "qorigin.dat"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + if(not quiet) + cout << "* Reading " << file << endl; + fread(origin, sizeof(OriginLineRecord), 1, fp); + for(int n=0; nOriginLine[n]); + fclose(fp); + } + + EchoMailConferenceRecord* area = (EchoMailConferenceRecord*)throw_calloc(1, sizeof(EchoMailConferenceRecord)); + MakePathname(file, path, "qechos.dat"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + while(fread(area, sizeof(EchoMailConferenceRecord), 1, fp) == 1) { + if(not area->Deleted) { + aa.reset(); + aa.type = GMB_ECHO; + aa.attr = attribsecho; + STRNP2C(area->AreaName); + aa.board = area->ConfNum; + aa.msgbase = GMB_PCBOARD; + aa.setechoid(area->AreaName); + aa.setorigin(origin->OriginLine[area->OriginLine]); + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_free(origin); + throw_free(area); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxquick.cpp b/goldlib/gcfg/gxquick.cpp new file mode 100644 index 0000000..7f6eaa8 --- /dev/null +++ b/goldlib/gcfg/gxquick.cpp @@ -0,0 +1,264 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from QuickBBS (old and new) +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read QuickBBS 2.60 (old) area config + +void gareafile::ReadQ260(char* qbpath, char* origin, char* options) { + + AreaCfg aa; + FILE* fp; + Path file; + Q260BrdRecP brd; + Q260CfgRecP cfg; + + cfg = new Q260CfgRecT; throw_new(cfg); + + brd = cfg->Boards; + + MakePathname(file, qbpath, "config.bbs"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(cfg, sizeof(Q260CfgRecT), 1, fp); + + STRNP2C(cfg->OriginLine); + + for(int n=0; n<200; n++) { + + if(*brd[n].Name) { + + aa.reset(); + + aa.board = n + 1; + aa.msgbase = GMB_HUDSON; + aa.setdesc(STRNP2C(brd[n].Name)); + aa.setorigin(*cfg->OriginLine ? cfg->OriginLine : origin); + + if(cfg->UseAka[n] == 0) { + aa.aka.zone = cfg->MatrixZone; + aa.aka.net = cfg->MatrixNet; + aa.aka.node = cfg->MatrixNode; + aa.aka.point = cfg->MatrixPoint; + } + else { + aa.aka.zone = cfg->AkaZone[cfg->UseAka[n]-1]; + aa.aka.net = cfg->AkaNet[cfg->UseAka[n]-1]; + aa.aka.node = cfg->AkaNode[cfg->UseAka[n]-1]; + aa.aka.point = cfg->AkaPoint[cfg->UseAka[n]-1]; + } + + switch(brd[n].Typ) { + case 0: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case 1: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + switch(brd[n].Kinds) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + case 3: + aa.attr.r_o1(); + break; + } + + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_delete(cfg); +} + + +// ------------------------------------------------------------------ +// Read QuickBBS 2.76.G2 (new) area config + +void gareafile::ReadQ276(char* qbpath, char* origin, char* options) { + + AreaCfg aa; + FILE* fp; + Path file; + Q276BrdRecP brd; + Q276CfgRecP cfg; + + brd = new Q276BrdRecT; throw_new(brd); + cfg = new Q276CfgRecT; throw_new(cfg); + + MakePathname(file, qbpath, "quickcfg.dat"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(cfg, sizeof(Q276CfgRecT), 1, fp); + + STRNP2C(cfg->MsgPath); + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(cfg->MsgPath)); + + fclose(fp); + } + + MakePathname(file, qbpath, "MSGCFG.DAT"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + int _recs = (int)(filelength(fileno(fp)) / sizeof(Q276BrdRecT)); + int _fmt = (_recs > 200) ? GMB_GOLDBASE : GMB_HUDSON; + + for(int n=0; n<_recs; n++) { + + fread(brd, sizeof(Q276BrdRecT), 1, fp); + + if(*brd->Name) { + + aa.reset(); + + aa.board = n + 1; + aa.msgbase = _fmt; + //aa.groupid = brd->Group; + aa.setorigin(*brd->OriginLine ? STRNP2C(brd->OriginLine) : origin); + + aa.aka.zone = cfg->MatrixZone[brd->Aka]; + aa.aka.net = cfg->MatrixNet[brd->Aka]; + aa.aka.node = cfg->MatrixNode[brd->Aka]; + aa.aka.point = cfg->MatrixPoint[brd->Aka]; + + aa.setdesc(STRNP2C(brd->Name)); + + switch(brd->Typ) { + case 0: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case 1: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + switch(brd->Kinds) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + case 3: + aa.attr.r_o1(); + break; + } + + AddNewArea(aa); + } + } + + fclose(fp); + } + + throw_delete(cfg); + throw_delete(brd); +} + + +// ------------------------------------------------------------------ +// Read QuickBBS (old or new) configuration + +void gareafile::ReadQuickBBS(char* tag) { + + char* ptr; + Path qbpath; + char origin[80], options[80]; + + ptr = getenv("QUICKBBS"); + if(ptr == NULL) + ptr = getenv("QBBS"); + if(ptr) + AddBackslash(strcpy(qbpath, ptr)); + else + strcpy(qbpath, areapath); + + // Read AREAS.BBS + *qbpath = NUL; + *origin = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + if(is_dir(ptr) and (*qbpath == NUL)) + AddBackslash(strcpy(qbpath, ptr)); + else + GetAreasBBS(ptr, origin, options); + } + ptr = strtok(NULL, " \t"); + } + + // Detect general version range of QuickBBS + if(fexist(AddPath(qbpath, "quickcfg.dat"))) + ReadQ276(qbpath, origin, options); + else + ReadQ260(qbpath, origin, options); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxra.cpp b/goldlib/gcfg/gxra.cpp new file mode 100644 index 0000000..469c1b1 --- /dev/null +++ b/goldlib/gcfg/gxra.cpp @@ -0,0 +1,212 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from RemoteAccess 0.xx - 1.xx, 2.0x, 2.5x +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read RemoteAccess MESSAGES.RA + +void gareafile::ReadRemoteAccess(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + Path rapath, file; + char origin[80], options[80]; + + *rapath = NUL; + *origin = NUL; + + CONFIGrecord* config = (CONFIGrecord*)throw_calloc(1, sizeof(CONFIGrecord)); + if(config) { + + ptr = getenv("RA"); + if(ptr) + AddBackslash(strcpy(rapath, ptr)); + else + strcpy(rapath, areapath); + + // Read AREAS.BBS + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + if(is_dir(ptr) and (*rapath == NUL)) + AddBackslash(strcpy(rapath, ptr)); + else + GetAreasBBS(ptr, origin, options); + } + ptr = strtok(NULL, " \t"); + } + + MakePathname(file, rapath, "config.ra"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(config, sizeof(CONFIGrecord), 1, fp); + fclose(fp); + + if(config->VersionID >= 0x200) + if(ra2usersbbs == 0) + ra2usersbbs = 2; + + STRNP2C(config->MsgBasePath); + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(config->MsgBasePath)); + } + + MakePathname(file, rapath, "messages.ra"); + if(not fexist(file)) + if(*config->SysPath) + strnp2cc(rapath, config->SysPath, sizeof(Path)); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + if(config->VersionID >= 0x200) { + MESSAGErecord* area = new MESSAGErecord; throw_new(area); + int n=0; + while(fread(area, sizeof(MESSAGErecord), 1, fp) == 1) { + n++; + if(*area->Name) { + aa.reset(); + aa.aka = CAST(ftn_addr, config->Address[area->AkaAddress]); + switch(area->Typ) { + case LocalMail: // Local + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case NetMail: // Netmail + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: // Echomail + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + switch(area->MsgKinds) { + case Both: + case Private: + aa.attr.pvt1(); + break; + case Public: + aa.attr.pvt0(); + break; + case ROnly: + aa.attr.r_o1(); + break; + } + if(area->Group) + aa.groupid = (char)(area->Group+'A'-1); + aa.setdesc(STRNP2C(area->Name)); + STRNP2C(area->OriginLine); + strchg(area->OriginLine, '@', '0'); + aa.setorigin(area->OriginLine); + + if(area->Attribute & 0x80) { + aa.setpath(STRNP2C(area->JAMbase)); + aa.msgbase = GMB_JAM; + AddNewArea(aa); + } + else { + if(config->VersionID >= 0x210) + aa.board = area->AreaNum; + else + aa.board = n; + aa.msgbase = GMB_HUDSON; + AddNewArea(aa); + } + } + } + throw_delete(area); + } + else { + _messagesra* area = new _messagesra; throw_new(area); + for(int n=0; n<200; n++) { + fread(area, sizeof(_messagesra), 1, fp); + if(*area->name) { + aa.reset(); + aa.msgbase = GMB_HUDSON; + aa.board = n+1; + aa.aka = CAST(ftn_addr, config->Address[area->akaaddress]); + switch(area->type) { + case LocalMail: // Local + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case NetMail: // Netmail + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: // Echomail + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + switch(area->msgkinds) { + case Both: + case Private: + aa.attr.pvt1(); + break; + case Public: + aa.attr.pvt0(); + break; + case ROnly: + aa.attr.r_o1(); + break; + } + aa.setdesc(STRNP2C(area->name)); + STRNP2C(area->originline); + strchg(area->originline, '@', '0'); + aa.setorigin(area->originline); + AddNewArea(aa); + } + } + throw_delete(area); + } + + fclose(fp); + } + + throw_free(config); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxraecho.cpp b/goldlib/gcfg/gxraecho.cpp new file mode 100644 index 0000000..b0a4aea --- /dev/null +++ b/goldlib/gcfg/gxraecho.cpp @@ -0,0 +1,138 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from RA-ECHO (1.00 - 1.xx) +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read Ra-Echo AREAS.RAE + +void gareafile::ReadRaEcho(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + long raesize; + char options[80]; + Path repath, file; + int raever, areano; + TRaEchoArea101 area; + + *repath = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(repath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*repath == NUL) { + ptr = getenv("RAECHO"); + if(ptr) + AddBackslash(strcpy(repath, ptr)); + } + if(*repath == NUL) + strcpy(repath, areapath); + + MakePathname(file, repath, "areas.rae"); + + raesize = GetFilesize(file); + raever = 0; + if(raesize == -1) { + // Determine RA-ECHO version... + if((raesize%(long)sizeof(TRaEchoArea100)) == 0) + raever = sizeof(TRaEchoArea100); + else if((raesize%(long)sizeof(TRaEchoArea101)) == 0) + raever = sizeof(TRaEchoArea101); + } + if(raever == 0) { + if(not quiet) + cout << "* Could not determine version of RA-ECHO - skipping." << endl; + return; + } + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + areano = 1; + while(fread(&area, raever, 1, fp) == 1) { + + if(*area.echoid) { + aa.reset(); + STRNP2C(area.desc); + STRNP2C(area.path); + STRNP2C(area.echoid); + STRNP2C(area.origin); + if(area.isopus and *area.path and stricmp(area.path, "P")) { + aa.msgbase = fidomsgtype; + aa.setpath(area.path); + } + else if(areano <= 200) { + aa.msgbase = GMB_HUDSON; + aa.board = areano; + } + if(aa.msgbase) { + aa.aka = area.addr; + switch(area.type) { + case RAE_LOCAL: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case RAE_NET: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case RAE_ECHO: + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + aa.setdesc(area.desc); + aa.setechoid(area.echoid); + aa.setorigin(area.origin); + AddNewArea(aa); + } + } + + areano++; + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxsquish.cpp b/goldlib/gcfg/gxsquish.cpp new file mode 100644 index 0000000..d3f29b3 --- /dev/null +++ b/goldlib/gcfg/gxsquish.cpp @@ -0,0 +1,220 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Squish +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadSquishFile(char* path, char* file, char* options, char* origin, int group) { + + const word CRC_ADDRESS = 0xFDD6; + const word CRC_ORIGIN = 0x4CE5; + const word CRC_INCLUDE = 0x379B; + const word CRC_AREASBBS = 0xF77C; + const word CRC_NETAREA = 0x8F1C; + const word CRC_ECHOAREA = 0x0D63; + const word CRC_LOCALAREA = 0xAEC1; + const word CRC_DUPEAREA = 0xD8B9; + const word CRC_BADAREA = 0x8DA5; + + AreaCfg aa; + char buf[512]; + Path buf2; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + aa.reset(); + + while(fgets(buf, sizeof(buf), fp)) { + + char* ptr = strskip_wht(strtrim(buf)); + if(*ptr != ';' and *ptr) { + + aa.type = 0xFF; + + char* key; + char* val = ptr; + switch(getkeyvalcrc(&key, &val)) { + case CRC_ADDRESS: + CfgAddress(val); + break; + case CRC_ORIGIN: + strcpy(origin, val); + break; + case CRC_INCLUDE: + strxcpy(buf2, val, sizeof(buf2)); + MakePathname(buf2, path, buf2); + ReadSquishFile(path, buf2, options, origin, group); + break; + case CRC_AREASBBS: + strcpy(buf2, val); + MakePathname(buf2, path, buf2); + if(striinc("/NOCHK", options) or striinc("-NOCHK", options)) + strcat(buf2, " /NOCHK"); + ReadAreasBBS(buf2); + break; + case CRC_NETAREA: + aa.type = GMB_NET; + break; + case CRC_ECHOAREA: + case CRC_DUPEAREA: + case CRC_BADAREA: + aa.type = GMB_ECHO; + break; + case CRC_LOCALAREA: + aa.type = GMB_LOCAL; + break; + } + + if(aa.type != 0xFF) { + + // Get echoid + getkeyval(&key, &val); + aa.setechoid(key); + + // Get path + getkeyval(&key, &val); + strxcpy(buf2, key, sizeof(buf2)); + aa.setpath(MapPath(buf2)); + + // If not pass-through + if(not striinc("-0", val)) { + + aa.msgbase = fidomsgtype; + aa.groupid = group; + char* p = val; + + while(*p) { + if(strnieql(p, "-$", 2)) { + aa.msgbase = GMB_SQUISH; + p += 2; + if((tolower(*p) == 'g') and isalpha(p[1])) + aa.groupid = toupper(p[1]); + else if(tolower(*p) == 'n') { + key = ++p; + getkeyval(&key, &p); + aa.setdesc(key); + continue; + } + } + else if(strnieql(p, "-f", 2)) { + aa.msgbase = fidomsgtype; + p += 2; + } + else if(strnieql(p, "-p", 2)) { + aa.aka = primary_aka; + aa.aka.set(p+2); + } + p = strskip_wht(strskip_txt(p)); + } + + switch(aa.type) { + case GMB_LOCAL: + aa.attr = attribslocal; + break; + case GMB_NET: + aa.attr = attribsnet; + break; + case GMB_ECHO: + aa.attr = attribsecho; + break; + } + aa.setorigin(origin); + AddNewArea(aa); + } + + aa.reset(); + } + } + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from Squish (echomail processor) + +void gareafile::ReadSquish(char* tag) { + + char origin[80]; + char options[80]; + word defaultgroup = 0; + Path file, path; + + *origin = NUL; + *file = NUL; + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + strcpy(file, ptr); + if(is_dir(file)) { + AddBackslash(file); + strcat(file, "squish.cfg"); + } + } + else { + if(toupper(*(++ptr)) == 'G') { + if(*(++ptr) == '=') + ptr++; + if(*ptr == '#') + defaultgroup = (word)(atoi(ptr+1)+0x8000u); + else + defaultgroup = (word)(isupper(*ptr) ? *ptr : 0); + } + } + ptr = strtok(NULL, " \t"); + } + + if(not *file and ((ptr = getenv("SQUISH"))!=NULL)) { + strcpy(file, ptr); + if(is_dir(file)) { + AddBackslash(file); + strcat(file, "squish.cfg"); + } + } + + extractdirname(path, file); + + if(*squishuserpath == NUL) + PathCopy(squishuserpath, path); + + ReadSquishFile(path, file, options, origin, defaultgroup); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxsuper.cpp b/goldlib/gcfg/gxsuper.cpp new file mode 100644 index 0000000..9dcece6 --- /dev/null +++ b/goldlib/gcfg/gxsuper.cpp @@ -0,0 +1,187 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from SuperBBS +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read SuperBBS + +void gareafile::ReadSuperBBS(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + Path sbpath, file; + char origin[80], options[80]; + + ExtraConfigP sconfig = new ExtraConfigT; throw_new(sconfig); + ConfigRecordP config = new ConfigRecordT; throw_new(config); + MsgBoardRecordP boards = new MsgBoardRecordT; throw_new(boards); + + *sbpath = NUL; + *origin = NUL; + + ptr = getenv("SUPERBBS"); + if(ptr == NULL) + ptr = getenv("SBBS"); + if(ptr) + AddBackslash(strcpy(sbpath, ptr)); + else + strcpy(sbpath, areapath); + + // Read AREAS.BBS + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + if(is_dir(ptr) and (*sbpath == NUL)) + AddBackslash(strcpy(sbpath, ptr)); + else + GetAreasBBS(ptr, origin, options); + } + ptr = strtok(NULL, " \t"); + } + + MakePathname(file, sbpath, "config.bbs"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(config, sizeof(ConfigRecordT), 1, fp); + STRNP2C(config->OriginLine); + fclose(fp); + + MakePathname(file, sbpath, "sconfig.bbs"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(sconfig, sizeof(ExtraConfigT), 1, fp); + fclose(fp); + + STRNP2C(sconfig->MsgBasePath); + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(sconfig->MsgBasePath)); + + // Is it 1.16 or later? + if(sconfig->VersionNumber >= 0x0110) { + + MakePathname(file, sbpath, "boards.bbs"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + for(int n=0; n<200; n++) { + + fread(boards, sizeof(MsgBoardRecordT), 1, fp); + + if(*boards->Name) { + + aa.reset(); + + aa.board = n + 1; + aa.msgbase = GMB_HUDSON; + aa.groupid = boards->Group; + aa.setorigin(*config->OriginLine ? config->OriginLine : origin); + + aa.setdesc(STRNP2C(boards->Name)); + + switch(boards->Typ) { + case 0: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case 1: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + switch(boards->Kinds) { + case 1: + aa.attr.pvt1(); + break; + case 0: + case 2: + aa.attr.pvt0(); + break; + case 3: + aa.attr.r_o1(); + break; + } + + // Is it 1.17 or newer? + if(sconfig->VersionNumber >= 0x0111) { + // This doesn't work in 1.16 + aa.aka.zone = sconfig->AkaZone [boards->UseAka]; + aa.aka.net = sconfig->AkaNet [boards->UseAka]; + aa.aka.node = sconfig->AkaNode [boards->UseAka]; + aa.aka.point = sconfig->AkaPoint[boards->UseAka]; + } + else { + // But this does + aa.aka.zone = sconfig->AkaZone [config->UseAka[n]]; + aa.aka.net = sconfig->AkaNet [config->UseAka[n]]; + aa.aka.node = sconfig->AkaNode [config->UseAka[n]]; + aa.aka.point = sconfig->AkaPoint[config->UseAka[n]]; + } + + AddNewArea(aa); + } + } + + fclose(fp); + } + } + else { + cout << "* Error: Unsupported version of SuperBBS: " << + (word)(sconfig->VersionNumber >> 8) << '.' << (word)(sconfig->VersionNumber & 0xFF) << endl; + } + } + } + + throw_delete(boards); + throw_delete(config); + throw_delete(sconfig); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gcfg/gxtimed.cpp b/goldlib/gcfg/gxtimed.cpp new file mode 100644 index 0000000..6b959f3 --- /dev/null +++ b/goldlib/gcfg/gxtimed.cpp @@ -0,0 +1,246 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from timEd. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::nullastbackslash(char* val) { + + char* ptr = strrchr(val, '\\'); + if(ptr == NULL) + ptr = strrchr(val, '/'); + if(ptr) + *ptr = NUL; +} + + +// ------------------------------------------------------------------ + +void gareafile::ReadTimedFile(char* path, char* file, char* options, char* origin) { + + const word CRC_ADDRESS = 0xFDD6; + const word CRC_NAME = 0x3B63; + const word CRC_ORIGIN = 0x4CE5; + const word CRC_INCLUDE = 0x379B; + const word CRC_HUDSONPATH = 0x52A7; + const word CRC_JAMLOG = 0x9135; + const word CRC_SQUISHCFG = 0x11B4; + const word CRC_FASTECHOCFG = 0xA013; + const word CRC_GECHOCFG = 0xF230; + const word CRC_IMAILCFG = 0xFFB5; + const word CRC_FMAILCFG = 0x3AB6; + const word CRC_XMAILCFG = 0xA091; + const word CRC_LASTREAD = 0x87DB; + const word CRC_SQUISHOFFSET = 0xF55B; + const word CRC_NETAREA = 0x8F1C; + const word CRC_ECHOAREA = 0x0D63; + const word CRC_LOCALAREA = 0xAEC1; + + AreaCfg aa; + char buf[512]; + char buf2[256]; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + aa.reset(); + + while(fgets(buf, sizeof(buf), fp)) { + + char* ptr = strskip_wht(strtrim(buf)); + if(*ptr != ';' and *ptr) { + + aa.type = 0xFF; + + char* key; + char* val = ptr; + switch(getkeyvalcrc(&key, &val)) { + case CRC_ADDRESS: + CfgAddress(val); + break; + case CRC_NAME: + CfgUsername(val); + break; + case CRC_ORIGIN: + strcpy(origin, val); + break; + case CRC_INCLUDE: + strcpy(buf2, val); + MakePathname(buf2, path, buf2); + ReadTimedFile(path, buf2, options, origin); + break; + case CRC_HUDSONPATH: + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(val)); + break; + case CRC_JAMLOG: + if(*jampath == NUL) + PathCopy(jampath, MapPath(val)); + break; + case CRC_SQUISHCFG: + sprintf(buf2, "-c%s", val); + ReadSquish(buf2); + break; + case CRC_FASTECHOCFG: + nullastbackslash(val); + ReadFastecho(val); + break; + case CRC_GECHOCFG: + nullastbackslash(val); + ReadGEcho(val); + break; + case CRC_IMAILCFG: + nullastbackslash(val); + ReadIMail(val); + break; + case CRC_XMAILCFG: + nullastbackslash(val); + ReadXMail(val); + break; + case CRC_FMAILCFG: + nullastbackslash(val); + ReadFMail(val); + break; + case CRC_LASTREAD: + strcpy(fidolastread, val); + break; + case CRC_SQUISHOFFSET: + squishuserno = atoi(val); + break; + case CRC_NETAREA: + aa.type = GMB_NET; + break; + case CRC_ECHOAREA: + aa.type = GMB_ECHO; + break; + case CRC_LOCALAREA: + aa.type = GMB_LOCAL; + break; + } + + if(aa.type != 0xFF) { + + // Get description + getkeyval(&key, &val); + aa.setdesc(key); + + // Get echoid + getkeyval(&key, &val); + aa.setechoid(key); + + // Get path or board number + getkeyval(&key, &val); + aa.setpath(key); + aa.board = atoi(key); + + if(striinc("-$", val)) + aa.msgbase = GMB_SQUISH; + else if(striinc("-J", val)) + aa.msgbase = GMB_JAM; + else if(striinc("-H", val)) + aa.msgbase = GMB_HUDSON; + else + aa.msgbase = fidomsgtype; + + const char* ptr2 = striinc("-p", val); + if(ptr2) { + aa.aka = primary_aka; + aa.aka.set(ptr2+2); + } + + switch(aa.type) { + case GMB_LOCAL: + aa.attr = attribslocal; + break; + case GMB_NET: + aa.attr = attribsnet; + break; + case GMB_ECHO: + aa.attr = attribsecho; + break; + } + aa.setorigin(origin); + AddNewArea(aa); + + aa.reset(); + } + } + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from timEd + +void gareafile::ReadTimed(char* tag) { + + char origin[80]; + char options[80]; + Path file, path, timedcfg; + + *path = NUL; + *origin = NUL; + strcpy(timedcfg, "timed.cfg"); + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + } + else { + if(toupper(*(++ptr)) == 'C') { + if(*(++ptr) == '=') + ptr++; + strcpy(timedcfg, ptr); + } + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("TIMED"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + + MakePathname(file, path, timedcfg); + + ReadTimedFile(path, file, options, origin); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxtmail.cpp b/goldlib/gcfg/gxtmail.cpp new file mode 100644 index 0000000..363c1ba --- /dev/null +++ b/goldlib/gcfg/gxtmail.cpp @@ -0,0 +1,158 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from Terminate Mail (TMAIL). +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadTmailFile(char* file, char* options, char* origin) { + + const word CRC_NAME = 0x3B63; + const word CRC_ADDRESS = 0xFDD6; + const word CRC_NETMAIL = 0xE42E; + const word CRC_AREAFILE = 0xB487; + const word CRC_ORIGIN = 0x4CE5; + const word CRC_ECHOFILE = 0x3EAA; + const word CRC_DESC = 0x8A2A; + + AreaCfg aa; + char buf[512]; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + aa.reset(); + + while(fgets(buf, sizeof(buf), fp)) { + + char* ptr = strskip_wht(strtrim(buf)); + if(*ptr != '%' and *ptr) { + + aa.type = 0xFF; + + char* key; + char* val = ptr; + switch(getkeyvalcrc(&key, &val)) { + case CRC_NAME: + CfgUsername(val); + break; + case CRC_ADDRESS: + CfgAddress(val); + break; + case CRC_NETMAIL: + aa.reset(); + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.msgbase = fidomsgtype; + aa.setdesc("Terminate Netmail"); + aa.setautoid("NETMAIL"); + adjustpath(val); + aa.setpath(val); + aa.setorigin(origin); + AddNewArea(aa); + break; + case CRC_AREAFILE: + adjustpath(val); + ReadAreasBBS(val); + break; + case CRC_ORIGIN: + strcpy(origin, val); + break; + case CRC_ECHOFILE: + adjustpath(val); + ReadEcholist(val); + break; + case CRC_DESC: + getkeyval(&key, &val); + ptr = key; + getkeyval(&key, &val); + strchg(key, '_', ' '); + strtrim(key); + SetAreaDesc(ptr, key); + break; + } + } + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from TMAIL + +void gareafile::ReadTmail(char* tag) { + + char origin[80]; + char options[80]; + Path file, path, tmailcfg; + + *path = NUL; + *origin = NUL; + strcpy(tmailcfg, "tmail.cfg"); + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + } + else { + if(toupper(*(++ptr)) == 'C') { + if(*(++ptr) == ':') + ptr++; + strcpy(tmailcfg, ptr); + } + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("TMAIL"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + + MakePathname(file, path, tmailcfg); + if(not fexist(file)) { + strcpy(tmailcfg, "tm.cfg"); + MakePathname(file, path, tmailcfg); + } + + strcpy(pathprefix, path); + ReadTmailFile(file, options, origin); + *pathprefix = NUL; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxts.cpp b/goldlib/gcfg/gxts.cpp new file mode 100644 index 0000000..291ba66 --- /dev/null +++ b/goldlib/gcfg/gxts.cpp @@ -0,0 +1,153 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from TosScan 1.00 (and FrontDoor) +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include // Structures for FrontDoor fd.sys+folder.sys / setup.fd+folder.fd +#include // Structures for TosScan areafile.fd + + +// ------------------------------------------------------------------ +// Read TosScan AREAFILE.FD + +void gareafile::ReadTosScan(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + word sysrev; + FD_Editor* editor; + FD_Shared* shared; + Path tspath, file; + TS_Areafile* areafile; + char buf[256], options[80]; + + *tspath = NUL; + editor = new FD_Editor; throw_new(editor); + shared = new FD_Shared; throw_new(shared); + areafile = new TS_Areafile; throw_new(areafile); + + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(tspath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*tspath == NUL) { + ptr = getenv("FD"); + if(ptr) + AddBackslash(strcpy(tspath, ptr)); + } + if(*tspath == NUL) + strcpy(tspath, areapath); + + if(fexist(AddPath(tspath, "areafile.fd"))) { + + if(fexist(AddPath(tspath, "setup.fd"))) + MakePathname(file, tspath, "setup.fd"); + else + MakePathname(file, tspath, "fd.sys"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(buf, 5, 1, fp); + if(streql(buf, "JoHo")) { // Check to see that it is v1.99b or higher + fread(&sysrev, sizeof(word), 1, fp); + // This probably ought to be if(sysrev == FD_THISREV).. + fseek(fp, 4, SEEK_CUR); // Seek past CRC32 + fseek(fp, sizeof(FD_Mailer), SEEK_CUR); // Seek past some data + fread(editor, sizeof(FD_Editor), 1, fp); + fread(shared, sizeof(FD_Shared), 1, fp); + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(editor->qbase)); + aa.reset(); + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.msgbase = fidomsgtype; + aa.attr.r_o(editor->netfolderflags & EDREADONLY); + aa.attr.pvt(editor->msgbits & MSGPRIVATE); + aa.attr.cra(editor->msgbits & MSGCRASH); + aa.attr.k_s(editor->msgbits & MSGKILL); + aa.setpath(shared->mailpath); + aa.setdesc("FrontDoor Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + fclose(fp); + } + + MakePathname(file, tspath, "areafile.fd"); + + fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + fseek(fp, 4L, SEEK_SET); // Skip CRC32 + + while(fread(areafile, sizeof(TS_Areafile), 1, fp) == 1) { + if(not (areafile->deleted or areafile->passthru) and not strblank(areafile->echoname) and (areafile->board ? areafile->board < 201 : 1)) { + aa.reset(); + aa.groupid = (char)toupper(areafile->groupid); + aa.aka = shared->aka[areafile->akano]; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + if(areafile->board) { + aa.msgbase = GMB_HUDSON; + aa.board = areafile->board; + } + else { + aa.msgbase = fidomsgtype; + aa.setpath(areafile->path); + } + aa.setdesc(areafile->desc); + aa.setechoid(areafile->echoname); + aa.setorigin(editor->origin[areafile->origno-1]); + AddNewArea(aa); + } + } + fclose(fp); + } + } + + throw_delete(areafile); + throw_delete(editor); + throw_delete(shared); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxwmail.cpp b/goldlib/gcfg/gxwmail.cpp new file mode 100644 index 0000000..5994cea --- /dev/null +++ b/goldlib/gcfg/gxwmail.cpp @@ -0,0 +1,182 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from WMail +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Read areas from WMail 2.2 + +void gareafile::ReadWMail(char* tag) { + + int fh; + AreaCfg aa; + char* ptr; + PWmailPrm wmprm; + PAreasPrm arprm; + char options[80]; + Path file, path; + + *path = NUL; + wmprm = new TWmailPrm; throw_new(wmprm); + arprm = new TAreasPrm; throw_new(arprm); + + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(path, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) { + ptr = getenv("WMAIL"); + if(ptr) + AddBackslash(strcpy(path, ptr)); + } + if(*path == NUL) + strcpy(path, areapath); + + sprintf(file, "%swmail.prm", path); + fh = sopen(file, O_RDONLY|O_BINARY, sharemode, S_STDRD); + if(fh != -1) { + + if(not quiet) + cout << "* Reading " << file << endl; + + read(fh, wmprm, sizeof(TWmailPrm)); + + // The *.MSG netmail area + aa.reset(); + aa.aka = wmprm->aka[0].addr; + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.msgbase = fidomsgtype; + STRNP2C(wmprm->dir.mail); + aa.setpath(wmprm->dir.mail); + aa.setdesc("WMail Netmail"); + aa.setechoid("NETMAIL"); + AddNewArea(aa); + + // The *.MSG badmsg area + if(*(wmprm->dir.badecho)) { + aa.reset(); + aa.aka = wmprm->aka[0].addr; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.msgbase = fidomsgtype; + STRNP2C(wmprm->dir.badecho); + aa.setpath(wmprm->dir.badecho); + aa.setdesc("WMail Bad Msgs Area"); + aa.setechoid("ECHO_BAD"); + AddNewArea(aa); + } + + // The *.MSG dupe area + if(*(wmprm->dir.dupes)) { + aa.reset(); + aa.aka = wmprm->aka[0].addr; + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.msgbase = fidomsgtype; + STRNP2C(wmprm->dir.dupes); + aa.setpath(wmprm->dir.dupes); + aa.setdesc("WMail Dupes Area"); + aa.setechoid("ECHO_DUPES"); + AddNewArea(aa); + } + + for(int n=0; n<10; n++) + STRNP2C(wmprm->origin[n]); + + close(fh); + } + + sprintf(file, "%sareas.prm", path); + fh = sopen(file, O_RDONLY|O_BINARY, sharemode, S_STDRD); + if(fh != -1) { + + if(not quiet) + cout << "* Reading " << file << endl; + + // All the echomail areas + while(read(fh, arprm, sizeof(TAreasPrm)) == sizeof(TAreasPrm)) { + if(arprm->tipo < 4) { + aa.reset(); + switch(arprm->tipo) { + case 1: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case 2: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + break; + case 3: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + } + STRNP2C(arprm->path); + aa.setpath(arprm->path); + aa.board = atoi(aa.path); + if(aa.board and aa.board <= 200) + aa.msgbase = GMB_HUDSON; + else + aa.msgbase = fidomsgtype; + STRNP2C(arprm->titolo); + STRNP2C(arprm->tag); + aa.setdesc(arprm->titolo); + aa.setechoid(arprm->tag); + if(arprm->def_attr & 0x01) + aa.attr.pvt1(); + if(arprm->def_attr & 0x02) + aa.attr.cra1(); + if(arprm->def_attr & 0x08) + aa.attr.att1(); + if(arprm->def_attr & 0x80) + aa.attr.k_s1(); + aa.setorigin(wmprm->origin[arprm->wmorigin-1]); + aa.aka = wmprm->aka[arprm->aka].addr; + AddNewArea(aa); + } + } + + close(fh); + } + + throw_delete(wmprm); + throw_delete(arprm); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxwtr.cpp b/goldlib/gcfg/gxwtr.cpp new file mode 100644 index 0000000..ebf83d5 --- /dev/null +++ b/goldlib/gcfg/gxwtr.cpp @@ -0,0 +1,202 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from WaterGate 0.93 (and newer) +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +uint gareafile::gettype(uint msgtype, const byte wtrtype) { + + switch(wtrtype) { + case 1: return msgtype; + case 2: return GMB_SQUISH; + case 3: return GMB_JAM; + case 4: return GMB_WILDCAT; + } + return 0; +} + + +// ------------------------------------------------------------------ +// Read WaterGate v0.93 + +void gareafile::ReadWtrGteFile(char* options, FILE* fp) { + + AreaCfg aa; + ConfigRecord* _tmp = new ConfigRecord; throw_new(_tmp); + ConfigRecord& c = *_tmp; + fread(&c, sizeof(ConfigRecord), 1, fp); + + strp2c(c.systemdir); MapPath(c.systemdir); + strp2c(c.origins[0]); + strp2c(c.origins[1]); + + if(*jampath == NUL) + PathCopy(jampath, c.systemdir); + + if(c.fidonetmailtype) { + aa.reset(); + aa.msgbase = gettype(c.opusdateformat ? GMB_OPUS : GMB_FTS1, c.fidonetmailtype); + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = CAST(ftn_addr, c.nodenrs[0]); + aa.setpath(strp2c(c.fidonetmailpath)); + aa.setdesc("WaterGate Netmail"); + aa.setautoid("NETMAIL"); + AddNewArea(aa); + } + + if(c.fidobadareatype) { + aa.reset(); + aa.msgbase = gettype(c.opusdateformat ? GMB_OPUS : GMB_FTS1, c.fidobadareatype); + aa.type = GMB_ECHO; + aa.attr = attribsecho; + aa.aka = CAST(ftn_addr, c.nodenrs[0]); + aa.setpath(strp2c(c.fidobadpath)); + aa.setdesc("WaterGate Badmail"); + aa.setautoid("BADMAIL"); + AddNewArea(aa); + } + + if(c.fidodupeareatype) { + aa.reset(); + aa.msgbase = gettype(c.opusdateformat ? GMB_OPUS : GMB_FTS1, c.fidodupeareatype); + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.aka = CAST(ftn_addr, c.nodenrs[0]); + aa.setpath(strp2c(c.fidodupepath)); + aa.setdesc("WaterGate Dupemail"); + aa.setautoid("DUPEMAIL"); + AddNewArea(aa); + } + + FILE* fp2; + Path file; + + MakePathname(file, c.systemdir, "areabase.tdb"); + fp2 = fsopen(file, "rb", sharemode); + if(fp2) { + char header[26]; + + if(not quiet) + cout << "* Reading " << file << endl; + + fread(header, 26, 1, fp2); + strp2c(header); + + if(streql(header, AreaBaseHeader)) { + AreaBaseRecord* ar = new AreaBaseRecord; throw_new(ar); + + while(fread(ar, sizeof(AreaBaseRecord), 1, fp2) == 1) { + if(not ar->deleted and ar->fidomsgstyle) { + aa.reset(); + switch(ar->areatype) { + case 0: aa.type = GMB_ECHO; aa.attr = attribsecho; break; + case 1: aa.type = GMB_NET; aa.attr = attribsnet; break; + case 2: aa.type = GMB_LOCAL; aa.attr = attribslocal; break; + case 3: aa.type = GMB_EMAIL; aa.attr = attribsemail; break; + default: + continue; + } + + aa.msgbase = gettype(c.opusdateformat ? GMB_OPUS : GMB_FTS1, ar->fidomsgstyle); + if(in_range(ar->originaka, (byte) 1, (byte) 20)) + aa.aka = CAST(ftn_addr, c.nodenrs[ar->originaka-1]); + aa.setpath(strp2c(ar->fidomsgpath)); + aa.setdesc(strp2c(ar->comment)); + aa.setautoid(strp2c(ar->areaname_F)); + switch(ar->originnr) { + case 0: aa.setorigin(strp2c(ar->origin)); break; + case 1: aa.setorigin(c.origins[0]); break; + case 2: aa.setorigin(c.origins[1]); break; + } + AddNewArea(aa); + } + } + throw_delete(ar); + } + else + cout << "* Error: WaterGate Areabase \"" << header << "\" is not supported - Skipping." << endl; + + fclose(fp2); + } + + throw_delete(_tmp); +} + + +// ------------------------------------------------------------------ + +void gareafile::ReadWtrGte(char* tag) { + + FILE* fp; + char* ptr; + char options[80]; + Path wtrpath, file; + + *file = NUL; + *wtrpath = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(wtrpath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*wtrpath == NUL) { + ptr = getenv("WTRGATE"); + if(ptr) + AddBackslash(strcpy(wtrpath, ptr)); + } + if(*wtrpath == NUL) + strcpy(wtrpath, areapath); + + MakePathname(file, wtrpath, "wtrcfg.tdb"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + char header[26]; + if(not quiet) + printf(NL "* Reading %s", file); + fread(header, 26, 1, fp); strp2c(header); + + if(streql(header, ConfigHeader)) + ReadWtrGteFile(options, fp); + else + cout << "* Error: WaterGate \"" << header << "\" is not supported - Skipping." << endl; + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxxbbs.cpp b/goldlib/gcfg/gxxbbs.cpp new file mode 100644 index 0000000..310f8f1 --- /dev/null +++ b/goldlib/gcfg/gxxbbs.cpp @@ -0,0 +1,195 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from AdeptXBBS +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#ifdef __OS2__ + +#define INCL_BASE +#include + +#include + + +// ------------------------------------------------------------------ + +void gareafile::ReadAdeptXbbsFile(char* path, char* file, char* options) { + + const word CRC_ADDRESS = 0xFDD6; + const word CRC_AREABEGIN = 0x44D7; + const word CRC_AREAEND = 0xBDEF; + const word CRC_DESC = 0x8A2A; + const word CRC_FLAGS = 0xF81A; + const word CRC_NAME = 0x3B63; + const word CRC_NUMBER = 0x2FBC; + const word CRC_ORIGIN = 0x4CE5; + const word CRC_PATH = 0x0212; + const word CRC_USENET = 0xD087; + + AreaCfg aa; + ulong flags; + char buf[512]; + char name[256]; + char usenet[256]; + Path apath; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + aa.reset(); + + while(fgets(buf, sizeof(buf), fp)) { + + char* ptr = strskip_wht(strtrim(buf)); + if(*ptr != ';' and *ptr) { + + char* key; + char* val = ptr; + switch(getkeyvalcrc(&key, &val)) { + case CRC_AREABEGIN: + aa.reset(); + sprintf(apath, "%sMessage_Bases\\", path); + *usenet = NUL; + break; + case CRC_AREAEND: + aa.setechoid(*usenet ? usenet : name); + sprintf(buf, "%s%s", apath, name); + aa.setpath((aa.msgbase & GMB_FIDO) ? apath : buf); + AddNewArea(aa); + aa.reset(); + break; + case CRC_ADDRESS: + aa.aka.set(val); + break; + case CRC_DESC: + aa.setdesc(val); + break; + case CRC_FLAGS: + flags = atol(val); + if(flags & (M_NET | M_EMAIL)) { + if(flags & M_EMAIL) { + aa.type = GMB_NET|GMB_EMAIL; + aa.attr = attribsemail; + } + else { + aa.type = GMB_NET; + aa.attr = attribsnet; + } + } + else if(flags & (M_ECHO | M_GROUP | M_USENET)) { + if(flags & M_USENET) { + aa.type = GMB_ECHO|GMB_NEWSGROUP; + aa.attr = attribsnews; + } + else { + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + } + else { + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + } + if(flags & M_SQUISH) + aa.msgbase = GMB_SQUISH; + else if(flags & M_FIDO) + aa.msgbase = GMB_OPUS; + else if(flags & M_JAM) + aa.msgbase = GMB_JAM; + else + aa.msgbase = GMB_ADEPTXBBS; + break; + case CRC_USENET: + strcpy(usenet, val); + break; + case CRC_NAME: + strcpy(name, val); + break; + case CRC_NUMBER: + aa.board = atoi(val); + break; + case CRC_ORIGIN: + aa.setorigin(val); + break; + case CRC_PATH: + PathCopy(apath, val); + break; + } + } + } + + fclose(fp); + } +} + +#endif + + +// ------------------------------------------------------------------ +// Read areas from AdeptXBBS + +void gareafile::ReadAdeptXBBS(char* tag) { + + #ifdef __OS2__ + + char options[80]; + Path file, path, cfg; + + *path = NUL; + strcpy(cfg, "System\\Message_Areas"); + strcpy(options, tag); + char* ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') + AddBackslash(strcpy(path, ptr)); + ptr = strtok(NULL, " \t"); + } + if(*path == NUL) + strcpy(path, areapath); + + strcpy(stpcpy(file, path), cfg); + + if(strblank(adeptxbbspath)) + strcpy(adeptxbbspath, path); + + ReadAdeptXbbsFile(path, file, options); + + #else + + NW(tag); + + #endif +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gcfg/gxxmail.cpp b/goldlib/gcfg/gxxmail.cpp new file mode 100644 index 0000000..da2c0fe --- /dev/null +++ b/goldlib/gcfg/gxxmail.cpp @@ -0,0 +1,236 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Read areas from XMail +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Clip a long filename to DOS compatible 8 chars + +char* gareafile::ClipDosFilename(char* __file) { + + // Only work on strings longer than 8 chars + uint _len = strlen(__file); + if(_len > 8) { + + // Point to last char before NUL + char* _ptr = __file + _len - 1; + + // Find the last slash, if any + while(_len and not isslash(*_ptr)) + _ptr--, _len--; + + // Point to first char after the slash, if any + if(isslash(*_ptr)) + _ptr++; + + // Cut filename if too long + if(strlen(_ptr) > 8) + _ptr[8] = NUL; + } + + // Return pointer to the filename + return __file; +} + + +// ------------------------------------------------------------------ + +void gareafile::ReadxMailFile(char* file, char* options) { + + const word CRC_SYSOP = 0x967F; + const word CRC_NODEADR = 0x4B51; + const word CRC_AKA = 0x13A4; + const word CRC_NETMAIL = 0xE42E; + const word CRC_ORIGIN = 0x4CE5; + const word CRC_MESSAGEBASE = 0x213E; + + AreaCfg aa; + char buf[512]; + + FILE* fp = fsopen(file, "rb", sharemode); + if(fp) { + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + aa.reset(); + + while(fgets(buf, sizeof(buf), fp)) { + + char* ptr = strskip_wht(strtrim(buf)); + if(*ptr != ';' and *ptr) { + + char* key; + char* val = ptr; + switch(getkeyvalcrc(&key, &val)) { + case CRC_SYSOP: + //CfgUsername(val); + break; + case CRC_NODEADR: + case CRC_AKA: + CfgAddress(val); + break; + case CRC_NETMAIL: + aa.reset(); + aa.type = GMB_NET; + aa.attr = attribsnet; + aa.msgbase = fidomsgtype; + aa.setdesc("xMail Netmail"); + aa.setautoid("NETMAIL"); + aa.setpath(val); + AddNewArea(aa); + break; + case CRC_ORIGIN: + CfgOrigin(val); + break; + case CRC_MESSAGEBASE: + if(*hudsonpath == NUL) + PathCopy(hudsonpath, MapPath(val)); + break; + } + } + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ +// Read areas from XMail + +void gareafile::ReadXMail(char* tag) { + + AreaCfg aa; + FILE* fp; + char* ptr; + int areano; + char options[80]; + Path xmailpath, file; + EchoAreaRec area; + + *xmailpath = NUL; + strcpy(options, tag); + ptr = strtok(tag, " \t"); + while(ptr) { + if(*ptr != '-') { + AddBackslash(strcpy(xmailpath, ptr)); + break; + } + ptr = strtok(NULL, " \t"); + } + if(*xmailpath == NUL) { + ptr = getenv("XM"); + if(ptr) + AddBackslash(strcpy(xmailpath, ptr)); + } + if(*xmailpath == NUL) + strcpy(xmailpath, areapath); + + MakePathname(file, xmailpath, "xmail.cfg"); + ReadxMailFile(file, options); + + MakePathname(file, xmailpath, "areas.xm"); + fp = fsopen(file, "rb", sharemode); + if(fp) { + + setvbuf(fp, NULL, _IOFBF, 8192); + + if(not quiet) + cout << "* Reading " << file << endl; + + areano = 1; + while(fread(&area, sizeof(EchoAreaRec), 1, fp) == 1) { + + if(*area.Name) { + + aa.reset(); + STRNP2C(area.MsgDirectory); + + switch(area.StoreType) { + case FmtHudson: + aa.msgbase = GMB_HUDSON; + aa.board = areano; + break; + case FmtMsg: + aa.msgbase = fidomsgtype; + aa.setpath(ClipDosFilename(area.MsgDirectory)); + break; + case FmtSquish: + aa.msgbase = GMB_SQUISH; + aa.setpath(ClipDosFilename(area.MsgDirectory)); + break; + case FmtJam: + aa.msgbase = GMB_JAM; + aa.setpath(ClipDosFilename(area.MsgDirectory)); + break; + default: + // Passthrough or unknown + continue; + } + + aa.setdesc(STRNP2C(area.Descr)); + aa.setechoid(STRNP2C(area.Name)); + aa.setorigin(STRNP2C(area.OriginLine)); + + aa.aka.zone = area.AreaAddress.Zone; + aa.aka.net = area.AreaAddress.Net; + aa.aka.node = area.AreaAddress.Node; + aa.aka.point = area.AreaAddress.Point; + + switch(area.MailType) { + case Localmail: + aa.type = GMB_LOCAL; + aa.attr = attribslocal; + break; + case Netmail: + aa.type = GMB_NET; + aa.attr = attribsnet; + break; + case Echomail: + default: + aa.type = GMB_ECHO; + aa.attr = attribsecho; + } + + AddNewArea(aa); + } + + areano++; + } + + fclose(fp); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/glibc/Makefile b/goldlib/glibc/Makefile new file mode 100644 index 0000000..c23a6ae --- /dev/null +++ b/goldlib/glibc/Makefile @@ -0,0 +1,9 @@ +# -*- makefile -*- + +TOP=../.. +TARGET=glibc +INCS=-I$(TOP)/goldlib/glibc +CFLAGS=-DHAVE_CONFIG_H + +include $(TOP)/GNUmakef.inc +include $(TOP)/GNUmakef.lib diff --git a/goldlib/glibc/config.h b/goldlib/glibc/config.h new file mode 100644 index 0000000..c4e123d --- /dev/null +++ b/goldlib/glibc/config.h @@ -0,0 +1,14 @@ +/* This is handmade generic config.h */ + +#if !defined WINDOWS32 && defined _WIN32 +#define WINDOWS32 1 +#endif + +#define HAVE_DIRENT_H 1 +#define STDC_HEADERS 1 +#define HAVE_UNISTD_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRCOLL 1 + +#define __P(protos) protos diff --git a/goldlib/glibc/dummy.c b/goldlib/glibc/dummy.c new file mode 100644 index 0000000..bff43d2 --- /dev/null +++ b/goldlib/glibc/dummy.c @@ -0,0 +1,3 @@ +/* dummy file used to produce empty library if no files to be build */ + +char cvs_id[]="$Id$"; diff --git a/goldlib/glibc/fnmatch.c b/goldlib/glibc/fnmatch.c new file mode 100644 index 0000000..2d6f6af --- /dev/null +++ b/goldlib/glibc/fnmatch.c @@ -0,0 +1,385 @@ +/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if HAVE_CONFIG_H +# include +#endif + +/* Enable GNU extensions in fnmatch.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#include +#include +#include + +#if HAVE_STRING_H +# include +#else +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) +/* Solaris 2.5 has a bug: must be included before . */ +# include +# include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined _LIBC || !defined __GNU_LIBRARY__ + + +# if defined STDC_HEADERS || !defined isascii +# define ISASCII(c) 1 +# else +# define ISASCII(c) isascii(c) +# endif + +#ifdef isblank +# define ISBLANK(c) (ISASCII (c) && isblank (c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif +#ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +#else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +#endif + +#define ISPRINT(c) (ISASCII (c) && isprint (c)) +#define ISDIGIT(c) (ISASCII (c) && isdigit (c)) +#define ISALNUM(c) (ISASCII (c) && isalnum (c)) +#define ISALPHA(c) (ISASCII (c) && isalpha (c)) +#define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) +#define ISLOWER(c) (ISASCII (c) && islower (c)) +#define ISPUNCT(c) (ISASCII (c) && ispunct (c)) +#define ISSPACE(c) (ISASCII (c) && isspace (c)) +#define ISUPPER(c) (ISASCII (c) && isupper (c)) +#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) + +# define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 1. */ +# ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +# else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +# endif + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif +# else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +# if !defined _LIBC && !defined getenv +extern char *getenv (); +# endif + +# ifndef errno +extern int errno; +# endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +int +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + register const char *p = pattern, *n = string; + register char c; + +/* Note that this evaluates C many times. */ +# ifdef _LIBC +# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) +# else +# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) +# endif + + while ((c = *p++) != '\0') + { + c = FOLD (c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_FILE_NAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + if (c == '\0') + /* Trailing \ loses. */ + return FNM_NOMATCH; + c = FOLD (c); + } + if (FOLD (*n) != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++) + { + if ((flags & FNM_FILE_NAME) && *n == '/') + /* A slash does not match a wildcard under FNM_FILE_NAME. */ + return FNM_NOMATCH; + else if (c == '?') + { + /* A ? needs to match one character. */ + if (*n == '\0') + /* There isn't another character; no match. */ + return FNM_NOMATCH; + else + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + less than three characters. */ + ++n; + } + } + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + c1 = FOLD (c1); + for (--p; *n != '\0'; ++n) + if ((c == '[' || FOLD (*n) == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + static int posixly_correct; + register int not; + char cold; + + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + + if (*n == '\0') + return FNM_NOMATCH; + + if (*n == '.' && (flags & FNM_PERIOD) && + (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + if (*n == '/' && (flags & FNM_FILE_NAME)) + /* `/' cannot be matched. */ + return FNM_NOMATCH; + + not = (*p == '!' || (posixly_correct < 0 && *p == '^')); + if (not) + ++p; + + c = *p++; + for (;;) + { + int fn = FOLD (*n); + + if (!(flags & FNM_NOESCAPE) && c == '\\') + { + if (*p == '\0') + return FNM_NOMATCH; + c = FOLD (*p++); + + if (c == fn) + goto matched; + } + else if (c == '[' && *p == ':') + { + /* Leave room for the null. */ + char str[CHAR_CLASS_MAX_LENGTH + 1]; + size_t c1 = 0; +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) + wctype_t wt; +# endif + + for (;;) + { + if (c1 == CHAR_CLASS_MAX_LENGTH) + /* The name is too long and therefore the pattern + is ill-formed. */ + return FNM_NOMATCH; + + c = *++p; + if (c == ':' && p[1] == ']') + { + p += 2; + break; + } + str[c1++] = 'c'; + } + str[c1] = '\0'; + +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) + wt = IS_CHAR_CLASS (str); + if (wt == 0) + /* Invalid character class name. */ + return FNM_NOMATCH; + + if (__iswctype (__btowc (*n), wt)) + goto matched; +# else + if ((STREQ (str, "alnum") && ISALNUM (*n)) + || (STREQ (str, "alpha") && ISALPHA (*n)) + || (STREQ (str, "blank") && ISBLANK (*n)) + || (STREQ (str, "cntrl") && ISCNTRL (*n)) + || (STREQ (str, "digit") && ISDIGIT (*n)) + || (STREQ (str, "graph") && ISGRAPH (*n)) + || (STREQ (str, "lower") && ISLOWER (*n)) + || (STREQ (str, "print") && ISPRINT (*n)) + || (STREQ (str, "punct") && ISPUNCT (*n)) + || (STREQ (str, "space") && ISSPACE (*n)) + || (STREQ (str, "upper") && ISUPPER (*n)) + || (STREQ (str, "xdigit") && ISXDIGIT (*n))) + goto matched; +# endif + } + else if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + else if (FOLD (c) == fn) + goto matched; + + cold = c; + c = *p++; + + if (c == '-' && *p != ']') + { + /* It is a range. */ + char cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + + if (cold <= fn && fn <= FOLD (cend)) + goto matched; + + c = *p++; + } + if (c == ']') + break; + } + + if (!not) + return FNM_NOMATCH; + break; + + matched: + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + { + if (*p == '\0') + return FNM_NOMATCH; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + else if (c == '[' && *p == ':') + { + do + if (*++p == '\0') + return FNM_NOMATCH; + while (*p != ':' || p[1] == ']'); + p += 2; + c = *p; + } + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD (*n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; + +# undef FOLD +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/goldlib/glibc/fnmatch.h b/goldlib/glibc/fnmatch.h new file mode 100644 index 0000000..eb99617 --- /dev/null +++ b/goldlib/glibc/fnmatch.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _FNMATCH_H +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 || defined _WIN32 +# if !defined __GLIBC__ || !defined __P +# undef __P +# define __P(protos) protos +# endif +#else /* Not C++ or ANSI C. */ +# undef __P +# define __P(protos) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + +#ifndef const +# if (defined __STDC__ && __STDC__) || defined __cplusplus +# define __const const +# else +# define __const +# endif +#endif + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE +# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* This value is returned if the implementation does not support + `fnmatch'. Since this is not the case here it will never be + returned but the conformance test suites still require the symbol + to be defined. */ +#ifdef _XOPEN_SOURCE +# define FNM_NOSYS (-1) +#endif + +/* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((__const char *__pattern, __const char *__string, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/goldlib/glibc/glibc.all b/goldlib/glibc/glibc.all new file mode 100644 index 0000000..095b72a --- /dev/null +++ b/goldlib/glibc/glibc.all @@ -0,0 +1,4 @@ +regex c all emx cyg +fnmatch c all cyg +glob c all cyg +dummy c all nov bcd bco bcx wcn wco wcx lnx djg rsx diff --git a/goldlib/glibc/glob.c b/goldlib/glibc/glob.c new file mode 100644 index 0000000..c30d8e4 --- /dev/null +++ b/goldlib/glibc/glob.c @@ -0,0 +1,1388 @@ +/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined _AIX && !defined __GNUC__ + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Enable GNU extensions in glob.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#include +#include +#include + +/* Outcomment the following line for production quality code. */ +/* #define NDEBUG 1 */ +#include + +#include /* Needed on stupid SunOS for assert. */ + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GLOB_INTERFACE_VERSION 1 +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include +# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + +#if defined STDC_HEADERS || defined __GNU_LIBRARY__ +# include +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +# ifndef POSIX +# ifdef _POSIX_VERSION +# define POSIX +# endif +# endif +#endif + +#if !defined _AMIGA && !defined VMS && !defined WINDOWS32 +# include +#endif + +#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(val) errno = (val) +#endif + +#ifndef NULL +# define NULL 0 +#endif + + +#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +# ifdef HAVE_VMSDIR_H +# include "vmsdir.h" +# endif /* HAVE_VMSDIR_H */ +#endif + + +/* In GNU systems, defines this macro for us. */ +#ifdef _D_NAMLEN +# undef NAMLEN +# define NAMLEN(d) _D_NAMLEN(d) +#endif + +/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available + if the `d_type' member for `struct dirent' is available. */ +#ifdef _DIRENT_HAVE_D_TYPE +# define HAVE_D_TYPE 1 +#endif + + +#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +# define REAL_DIR_ENTRY(dp) 1 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* POSIX */ + +#if defined STDC_HEADERS || defined __GNU_LIBRARY__ +# include +# include +# define ANSI_STRING +#else /* No standard headers. */ + +extern char *getenv (); + +# ifdef HAVE_STRING_H +# include +# define ANSI_STRING +# else +# include +# endif +# ifdef HAVE_MEMORY_H +# include +# endif + +extern char *malloc (), *realloc (); +extern void free (); + +extern void qsort (); +extern void abort (), exit (); + +#endif /* Standard headers. */ + +#ifdef HAVE_GETLOGIN_R +extern int getlogin_r __P ((char *, size_t)); +#else +extern char *getlogin __P ((void)); +#endif + +#ifndef ANSI_STRING + +# ifndef bzero +extern void bzero (); +# endif +# ifndef bcopy +extern void bcopy (); +# endif + +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define strrchr rindex +/* memset is only used for zero here, but let's be paranoid. */ +# define memset(s, better_be_zero, n) \ + ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) +#endif /* Not ANSI_STRING. */ + +#if !defined HAVE_STRCOLL && !defined _LIBC +# define strcoll strcmp +#endif + +#if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1 +# define HAVE_MEMPCPY 1 +# undef mempcpy +# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len) +#endif + +#ifndef __GNU_LIBRARY__ +# ifdef __GNUC__ +__inline +# endif +# ifndef __SASC +# ifdef WINDOWS32 +static void * +# else +static char * +# endif +my_realloc (p, n) + char *p; + unsigned int n; +{ + /* These casts are the for sake of the broken Ultrix compiler, + which warns of illegal pointer combinations otherwise. */ + if (p == NULL) + return (char *) malloc (n); + return (char *) realloc (p, n); +} +# define realloc my_realloc +# endif /* __SASC */ +#endif /* __GNU_LIBRARY__ */ + + +#if !defined __alloca && !defined __GNU_LIBRARY__ + +# ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +# else /* Not GCC. */ +# ifdef HAVE_ALLOCA_H +# include +# else /* Not HAVE_ALLOCA_H. */ +# ifndef _AIX +# ifdef WINDOWS32 +# include +# else +extern char *alloca (); +# endif /* WINDOWS32 */ +# endif /* Not _AIX. */ +# endif /* sparc or HAVE_ALLOCA_H. */ +# endif /* GCC. */ + +# define __alloca alloca + +#endif + +#ifndef __GNU_LIBRARY__ +# define __stat stat +# ifdef STAT_MACROS_BROKEN +# undef S_ISDIR +# endif +# ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +# endif +#endif + +#ifdef _LIBC +# undef strdup +# define strdup(str) __strdup (str) +# define sysconf(id) __sysconf (id) +# define closedir(dir) __closedir (dir) +# define opendir(name) __opendir (name) +# define readdir(str) __readdir (str) +# define getpwnam_r(name, bufp, buf, len, res) \ + __getpwnam_r (name, bufp, buf, len, res) +# ifndef __stat +# define __stat(fname, buf) __xstat (_STAT_VER, fname, buf) +# endif +#endif + +#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) +# undef size_t +# define size_t unsigned int +#endif + +/* Some system header files erroneously define these. + We want our own definitions from to take precedence. */ +#ifndef __GNU_LIBRARY__ +# undef FNM_PATHNAME +# undef FNM_NOESCAPE +# undef FNM_PERIOD +#endif +#include + +/* Some system header files erroneously define these. + We want our own definitions from to take precedence. */ +#ifndef __GNU_LIBRARY__ +# undef GLOB_ERR +# undef GLOB_MARK +# undef GLOB_NOSORT +# undef GLOB_DOOFFS +# undef GLOB_NOCHECK +# undef GLOB_APPEND +# undef GLOB_NOESCAPE +# undef GLOB_PERIOD +#endif +#include + +static +#if __GNUC__ - 0 >= 2 +inline +#endif +const char *next_brace_sub __P ((const char *begin)); +static int glob_in_dir __P ((const char *pattern, const char *directory, + int flags, + int (*errfunc) (const char *, int), + glob_t *pglob)); +static int prefix_array __P ((const char *prefix, char **array, size_t n)); +static int collated_compare __P ((const __ptr_t, const __ptr_t)); + + +/* Find the end of the sub-pattern in a brace expression. We define + this as an inline function if the compiler permits. */ +static +#if __GNUC__ - 0 >= 2 +inline +#endif +const char * +next_brace_sub (begin) + const char *begin; +{ + unsigned int depth = 0; + const char *cp = begin; + + while (1) + { + if (depth == 0) + { + if (*cp != ',' && *cp != '}' && *cp != '\0') + { + if (*cp == '{') + ++depth; + ++cp; + continue; + } + } + else + { + while (*cp != '\0' && (*cp != '}' || depth > 0)) + { + if (*cp == '}') + --depth; + ++cp; + } + if (*cp == '\0') + /* An incorrectly terminated brace expression. */ + return NULL; + + continue; + } + break; + } + + return cp; +} + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +int +glob (pattern, flags, errfunc, pglob) + const char *pattern; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + const char *filename; + const char *dirname; + size_t dirlen; + int status; + int oldcount; + + if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) + { + __set_errno (EINVAL); + return -1; + } + + if (flags & GLOB_BRACE) + { + const char *begin = strchr (pattern, '{'); + if (begin != NULL) + { + /* Allocate working buffer large enough for our work. Note that + we have at least an opening and closing brace. */ + int firstc; + char *alt_start; + const char *p; + const char *next; + const char *rest; + size_t rest_len; +#ifdef __GNUC__ + char onealt[strlen (pattern) - 1]; +#else + char *onealt = (char *) malloc (strlen (pattern) - 1); + if (onealt == NULL) + { + if (!(flags & GLOB_APPEND)) + globfree (pglob); + return GLOB_NOSPACE; + } +#endif + + /* We know the prefix for all sub-patterns. */ +#ifdef HAVE_MEMPCPY + alt_start = mempcpy (onealt, pattern, begin - pattern); +#else + memcpy (onealt, pattern, begin - pattern); + alt_start = &onealt[begin - pattern]; +#endif + + /* Find the first sub-pattern and at the same time find the + rest after the closing brace. */ + next = next_brace_sub (begin + 1); + if (next == NULL) + { + /* It is an illegal expression. */ +#ifndef __GNUC__ + free (onealt); +#endif + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + } + + /* Now find the end of the whole brace expression. */ + rest = next; + while (*rest != '}') + { + rest = next_brace_sub (rest + 1); + if (rest == NULL) + { + /* It is an illegal expression. */ +#ifndef __GNUC__ + free (onealt); +#endif + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + } + } + /* Please note that we now can be sure the brace expression + is well-formed. */ + rest_len = strlen (++rest) + 1; + + /* We have a brace expression. BEGIN points to the opening {, + NEXT points past the terminator of the first element, and END + points past the final }. We will accumulate result names from + recursive runs for each brace alternative in the buffer using + GLOB_APPEND. */ + + if (!(flags & GLOB_APPEND)) + { + /* This call is to set a new vector, so clear out the + vector so we can append to it. */ + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + firstc = pglob->gl_pathc; + + p = begin + 1; + while (1) + { + int result; + + /* Construct the new glob expression. */ +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); +#else + memcpy (alt_start, p, next - p); + memcpy (&alt_start[next - p], rest, rest_len); +#endif + + result = glob (onealt, + ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) + | GLOB_APPEND), errfunc, pglob); + + /* If we got an error, return it. */ + if (result && result != GLOB_NOMATCH) + { +#ifndef __GNUC__ + free (onealt); +#endif + if (!(flags & GLOB_APPEND)) + globfree (pglob); + return result; + } + + if (*next == '}') + /* We saw the last entry. */ + break; + + p = next + 1; + next = next_brace_sub (p); + assert (next != NULL); + } + +#ifndef __GNUC__ + free (onealt); +#endif + + if (pglob->gl_pathc != firstc) + /* We found some entries. */ + return 0; + else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) + return GLOB_NOMATCH; + } + } + + /* Find the filename. */ + filename = strrchr (pattern, '/'); +#if defined __MSDOS__ || defined WINDOWS32 + /* The case of "d:pattern". Since `:' is not allowed in + file names, we can safely assume that wherever it + happens in pattern, it signals the filename part. This + is so we could some day support patterns like "[a-z]:foo". */ + if (filename == NULL) + filename = strchr (pattern, ':'); +#endif /* __MSDOS__ || WINDOWS32 */ + if (filename == NULL) + { + /* This can mean two things: a simple name or "~name". The later + case is nothing but a notation for a directory. */ + if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') + { + dirname = pattern; + dirlen = strlen (pattern); + + /* Set FILENAME to NULL as a special flag. This is ugly but + other solutions would require much more code. We test for + this special case below. */ + filename = NULL; + } + else + { + filename = pattern; +#ifdef _AMIGA + dirname = ""; +#else + dirname = "."; +#endif + dirlen = 0; + } + } + else if (filename == pattern) + { + /* "/pattern". */ + dirname = "/"; + dirlen = 1; + ++filename; + } + else + { + char *newp; + dirlen = filename - pattern; +#if defined __MSDOS__ || defined WINDOWS32 + if (*filename == ':' + || (filename > pattern + 1 && filename[-1] == ':')) + { + char *drive_spec; + + ++dirlen; + drive_spec = (char *) __alloca (dirlen + 1); +#ifdef HAVE_MEMPCPY + *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; +#else + memcpy (drive_spec, pattern, dirlen); + drive_spec[dirlen] = '\0'; +#endif + /* For now, disallow wildcards in the drive spec, to + prevent infinite recursion in glob. */ + if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) + return GLOB_NOMATCH; + /* If this is "d:pattern", we need to copy `:' to DIRNAME + as well. If it's "d:/pattern", don't remove the slash + from "d:/", since "d:" and "d:/" are not the same.*/ + } +#endif + newp = (char *) __alloca (dirlen + 1); +#ifdef HAVE_MEMPCPY + *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; +#else + memcpy (newp, pattern, dirlen); + newp[dirlen] = '\0'; +#endif + dirname = newp; + ++filename; + + if (filename[0] == '\0' +#if defined __MSDOS__ || defined WINDOWS32 + && dirname[dirlen - 1] != ':' + && (dirlen < 3 || dirname[dirlen - 2] != ':' + || dirname[dirlen - 1] != '/') +#endif + && dirlen > 1) + /* "pattern/". Expand "pattern", appending slashes. */ + { + int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + if (val == 0) + pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) + | (flags & GLOB_MARK)); + return val; + } + } + + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + + oldcount = pglob->gl_pathc; + +#ifndef VMS + if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') + { + if (dirname[1] == '\0' || dirname[1] == '/') + { + /* Look up home directory. */ + const char *home_dir = getenv ("HOME"); +# ifdef _AMIGA + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "SYS:"; +# else +# ifdef WINDOWS32 + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "c:/users/default"; /* poor default */ +# else + if (home_dir == NULL || home_dir[0] == '\0') + { + int success; + char *name; +# if defined HAVE_GETLOGIN_R || defined _LIBC + size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1; + + if (buflen == 0) + /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try + a moderate value. */ + buflen = 20; + name = (char *) __alloca (buflen); + + success = getlogin_r (name, buflen) >= 0; +# else + success = (name = getlogin ()) != NULL; +# endif + if (success) + { + struct passwd *p; +# if defined HAVE_GETPWNAM_R || defined _LIBC + size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX); + char *pwtmpbuf; + struct passwd pwbuf; + + if (pwbuflen == -1) + /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. + Try a moderate value. */ + pwbuflen = 1024; + pwtmpbuf = (char *) __alloca (pwbuflen); + + success = (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) + >= 0); +# else + p = getpwnam (name); + success = p != NULL; +# endif + if (success) + home_dir = p->pw_dir; + } + } + if (home_dir == NULL || home_dir[0] == '\0') + { + if (flags & GLOB_TILDE_CHECK) + return GLOB_NOMATCH; + else + home_dir = "~"; /* No luck. */ + } +# endif /* WINDOWS32 */ +# endif + /* Now construct the full directory. */ + if (dirname[1] == '\0') + dirname = home_dir; + else + { + char *newp; + size_t home_len = strlen (home_dir); + newp = (char *) __alloca (home_len + dirlen); +# ifdef HAVE_MEMPCPY + mempcpy (mempcpy (newp, home_dir, home_len), + &dirname[1], dirlen); +# else + memcpy (newp, home_dir, home_len); + memcpy (&newp[home_len], &dirname[1], dirlen); +# endif + dirname = newp; + } + } +# if !defined _AMIGA && !defined WINDOWS32 + else + { + char *end_name = strchr (dirname, '/'); + const char *user_name; + const char *home_dir; + + if (end_name == NULL) + user_name = dirname + 1; + else + { + char *newp; + newp = (char *) __alloca (end_name - dirname); +# ifdef HAVE_MEMPCPY + *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) + = '\0'; +# else + memcpy (newp, dirname + 1, end_name - dirname); + newp[end_name - dirname - 1] = '\0'; +# endif + user_name = newp; + } + + /* Look up specific user's home directory. */ + { + struct passwd *p; +# if defined HAVE_GETPWNAM_R || defined _LIBC + size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); + char *pwtmpbuf; + struct passwd pwbuf; + + if (buflen == -1) + /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a + moderate value. */ + buflen = 1024; + pwtmpbuf = (char *) __alloca (buflen); + + if (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0) + home_dir = p->pw_dir; + else + home_dir = NULL; +# else + p = getpwnam (user_name); + if (p != NULL) + home_dir = p->pw_dir; + else + home_dir = NULL; +# endif + } + /* If we found a home directory use this. */ + if (home_dir != NULL) + { + char *newp; + size_t home_len = strlen (home_dir); + size_t rest_len = end_name == NULL ? 0 : strlen (end_name); + newp = (char *) __alloca (home_len + rest_len + 1); +# ifdef HAVE_MEMPCPY + *((char *) mempcpy (mempcpy (newp, home_dir, home_len), + end_name, rest_len)) = '\0'; +# else + memcpy (newp, home_dir, home_len); + memcpy (&newp[home_len], end_name, rest_len); + newp[home_len + rest_len] = '\0'; +# endif + dirname = newp; + } + else + if (flags & GLOB_TILDE_CHECK) + /* We have to regard it as an error if we cannot find the + home directory. */ + return GLOB_NOMATCH; + } +# endif /* Not Amiga && not WINDOWS32. */ + } +#endif /* Not VMS. */ + + /* Now test whether we looked for "~" or "~NAME". In this case we + can give the answer now. */ + if (filename == NULL) + { + struct stat st; + + /* Return the directory if we don't check for error or if it exists. */ + if ((flags & GLOB_NOCHECK) + || (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (dirname, &st) + : __stat (dirname, &st)) == 0 + && S_ISDIR (st.st_mode))) + { + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + 1 + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + return GLOB_NOSPACE; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + +#if defined HAVE_STRDUP || defined _LIBC + pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname); +#else + { + size_t len = strlen (dirname) + 1; + char *dircopy = malloc (len); + if (dircopy != NULL) + pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname, + len); + } +#endif + if (pglob->gl_pathv[pglob->gl_pathc] == NULL) + { + free (pglob->gl_pathv); + return GLOB_NOSPACE; + } + pglob->gl_pathv[++pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + + return 0; + } + + /* Not found. */ + return GLOB_NOMATCH; + } + + if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) + { + /* The directory name contains metacharacters, so we + have to glob for the directory, and then glob for + the pattern in each directory found. */ + glob_t dirs; + register int i; + + status = glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) + | GLOB_NOSORT | GLOB_ONLYDIR), + errfunc, &dirs); + if (status != 0) + return status; + + /* We have successfully globbed the preceding directory name. + For each name we found, call glob_in_dir on it and FILENAME, + appending the results to PGLOB. */ + for (i = 0; i < dirs.gl_pathc; ++i) + { + int old_pathc; + +#ifdef SHELL + { + /* Make globbing interruptible in the bash shell. */ + extern int interrupt_state; + + if (interrupt_state) + { + globfree (&dirs); + globfree (&files); + return GLOB_ABORTED; + } + } +#endif /* SHELL. */ + + old_pathc = pglob->gl_pathc; + status = glob_in_dir (filename, dirs.gl_pathv[i], + ((flags | GLOB_APPEND) + & ~(GLOB_NOCHECK | GLOB_ERR)), + errfunc, pglob); + if (status == GLOB_NOMATCH) + /* No matches in this directory. Try the next. */ + continue; + + if (status != 0) + { + globfree (&dirs); + globfree (pglob); + return status; + } + + /* Stick the directory on the front of each name. */ + if (prefix_array (dirs.gl_pathv[i], + &pglob->gl_pathv[old_pathc], + pglob->gl_pathc - old_pathc)) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + } + + flags |= GLOB_MAGCHAR; + + /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls. + But if we have not found any matching entry and thie GLOB_NOCHECK + flag was set we must return the list consisting of the disrectory + names followed by the filename. */ + if (pglob->gl_pathc == oldcount) + { + /* No matches. */ + if (flags & GLOB_NOCHECK) + { + size_t filename_len = strlen (filename) + 1; + char **new_pathv; + struct stat st; + + /* This is an pessimistic guess about the size. */ + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + dirs.gl_pathc + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + { + globfree (&dirs); + return GLOB_NOSPACE; + } + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (i = 0; i < dirs.gl_pathc; ++i) + { + const char *dir = dirs.gl_pathv[i]; + size_t dir_len = strlen (dir); + + /* First check whether this really is a directory. */ + if (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0 + || !S_ISDIR (st.st_mode)) + /* No directory, ignore this entry. */ + continue; + + pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1 + + filename_len); + if (pglob->gl_pathv[pglob->gl_pathc] == NULL) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc], + dir, dir_len), + "/", 1), + filename, filename_len); +#else + memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len); + pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/'; + memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1], + filename, filename_len); +#endif + ++pglob->gl_pathc; + } + + pglob->gl_pathv[pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + + /* Now we know how large the gl_pathv vector must be. */ + new_pathv = (char **) realloc (pglob->gl_pathv, + ((pglob->gl_pathc + 1) + * sizeof (char *))); + if (new_pathv != NULL) + pglob->gl_pathv = new_pathv; + } + else + return GLOB_NOMATCH; + } + + globfree (&dirs); + } + else + { + status = glob_in_dir (filename, dirname, flags, errfunc, pglob); + if (status != 0) + return status; + + if (dirlen > 0) + { + /* Stick the directory on the front of each name. */ + int ignore = oldcount; + + if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs) + ignore = pglob->gl_offs; + + if (prefix_array (dirname, + &pglob->gl_pathv[ignore], + pglob->gl_pathc - ignore)) + { + globfree (pglob); + return GLOB_NOSPACE; + } + } + } + + if (flags & GLOB_MARK) + { + /* Append slashes to directory names. */ + int i; + struct stat st; + for (i = oldcount; i < pglob->gl_pathc; ++i) + if (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st) + : __stat (pglob->gl_pathv[i], &st)) == 0 + && S_ISDIR (st.st_mode)) + { + size_t len = strlen (pglob->gl_pathv[i]) + 2; + char *new = realloc (pglob->gl_pathv[i], len); + if (new == NULL) + { + globfree (pglob); + return GLOB_NOSPACE; + } + strcpy (&new[len - 2], "/"); + pglob->gl_pathv[i] = new; + } + } + + if (!(flags & GLOB_NOSORT)) + { + /* Sort the vector. */ + int non_sort = oldcount; + + if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount) + non_sort = pglob->gl_offs; + + qsort ((__ptr_t) &pglob->gl_pathv[non_sort], + pglob->gl_pathc - non_sort, + sizeof (char *), collated_compare); + } + + return 0; +} + + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +void +globfree (pglob) + register glob_t *pglob; +{ + if (pglob->gl_pathv != NULL) + { + register int i; + for (i = 0; i < pglob->gl_pathc; ++i) + if (pglob->gl_pathv[i] != NULL) + free ((__ptr_t) pglob->gl_pathv[i]); + free ((__ptr_t) pglob->gl_pathv); + } +} + + +/* Do a collated comparison of A and B. */ +static int +collated_compare (a, b) + const __ptr_t a; + const __ptr_t b; +{ + const char *const s1 = *(const char *const * const) a; + const char *const s2 = *(const char *const * const) b; + + if (s1 == s2) + return 0; + if (s1 == NULL) + return 1; + if (s2 == NULL) + return -1; + return strcoll (s1, s2); +} + + +/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's + elements in place. Return nonzero if out of memory, zero if successful. + A slash is inserted between DIRNAME and each elt of ARRAY, + unless DIRNAME is just "/". Each old element of ARRAY is freed. */ +static int +prefix_array (dirname, array, n) + const char *dirname; + char **array; + size_t n; +{ + register size_t i; + size_t dirlen = strlen (dirname); +#if defined __MSDOS__ || defined WINDOWS32 + int sep_char = '/'; +# define DIRSEP_CHAR sep_char +#else +# define DIRSEP_CHAR '/' +#endif + + if (dirlen == 1 && dirname[0] == '/') + /* DIRNAME is just "/", so normal prepending would get us "//foo". + We want "/foo" instead, so don't prepend any chars from DIRNAME. */ + dirlen = 0; +#if defined __MSDOS__ || defined WINDOWS32 + else if (dirlen > 1) + { + if (dirname[dirlen - 1] == '/') + /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */ + --dirlen; + else if (dirname[dirlen - 1] == ':') + { + /* DIRNAME is "d:". Use `:' instead of `/'. */ + --dirlen; + sep_char = ':'; + } + } +#endif + + for (i = 0; i < n; ++i) + { + size_t eltlen = strlen (array[i]) + 1; + char *new = (char *) malloc (dirlen + 1 + eltlen); + if (new == NULL) + { + while (i > 0) + free ((__ptr_t) array[--i]); + return 1; + } + +#ifdef HAVE_MEMPCPY + { + char *endp = (char *) mempcpy (new, dirname, dirlen); + *endp++ = DIRSEP_CHAR; + mempcpy (endp, array[i], eltlen); + } +#else + memcpy (new, dirname, dirlen); + new[dirlen] = DIRSEP_CHAR; + memcpy (&new[dirlen + 1], array[i], eltlen); +#endif + free ((__ptr_t) array[i]); + array[i] = new; + } + + return 0; +} + + +/* We must not compile this function twice. */ +#if !defined _LIBC || !defined NO_GLOB_PATTERN_P +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +int +__glob_pattern_p (pattern, quote) + const char *pattern; + int quote; +{ + register const char *p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) + { + case '?': + case '*': + return 1; + + case '\\': + if (quote && p[1] != '\0') + ++p; + break; + + case '[': + open = 1; + break; + + case ']': + if (open) + return 1; + break; + } + + return 0; +} +# ifdef _LIBC +weak_alias (__glob_pattern_p, glob_pattern_p) +# endif +#endif + + +/* Like `glob', but PATTERN is a final pathname component, + and matches are searched for in DIRECTORY. + The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. + The GLOB_APPEND flag is assumed to be set (always appends). */ +static int +glob_in_dir (pattern, directory, flags, errfunc, pglob) + const char *pattern; + const char *directory; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + __ptr_t stream = NULL; + + struct globlink + { + struct globlink *next; + char *name; + }; + struct globlink *names = NULL; + size_t nfound; + int meta; + int save; + + meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)); + if (meta == 0) + { + if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)) + /* We need not do any tests. The PATTERN contains no meta + characters and we must not return an error therefore the + result will always contain exactly one name. */ + flags |= GLOB_NOCHECK; + else + { + /* Since we use the normal file functions we can also use stat() + to verify the file is there. */ + struct stat st; + size_t patlen = strlen (pattern); + size_t dirlen = strlen (directory); + char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); + +# ifdef HAVE_MEMPCPY + mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), + "/", 1), + pattern, patlen + 1); +# else + memcpy (fullname, directory, dirlen); + fullname[dirlen] = '/'; + memcpy (&fullname[dirlen + 1], pattern, patlen + 1); +# endif + if (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (fullname, &st) + : __stat (fullname, &st)) == 0) + /* We found this file to be existing. Now tell the rest + of the function to copy this name into the result. */ + flags |= GLOB_NOCHECK; + } + + nfound = 0; + } + else + { + if (pattern[0] == '\0') + { + /* This is a special case for matching directories like in + "*a/". */ + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->name = (char *) malloc (1); + if (names->name == NULL) + goto memory_error; + names->name[0] = '\0'; + names->next = NULL; + nfound = 1; + meta = 0; + } + else + { + stream = ((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_opendir) (directory) + : (__ptr_t) opendir (directory)); + if (stream == NULL) + { + if ((errfunc != NULL && (*errfunc) (directory, errno)) + || (flags & GLOB_ERR)) + return GLOB_ABORTED; + nfound = 0; + meta = 0; + } + else + { + int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) + | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) +#if defined _AMIGA || defined VMS + | FNM_CASEFOLD +#endif + ); + nfound = 0; + flags |= GLOB_MAGCHAR; + + while (1) + { + const char *name; + size_t len; + struct dirent *d = ((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_readdir) (stream) + : readdir ((DIR *) stream)); + if (d == NULL) + break; + if (! REAL_DIR_ENTRY (d)) + continue; + +#ifdef HAVE_D_TYPE + /* If we shall match only directories use the information + provided by the dirent call if possible. */ + if ((flags & GLOB_ONLYDIR) + && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR) + continue; +#endif + + name = d->d_name; + + if (fnmatch (pattern, name, fnm_flags) == 0) + { + struct globlink *new = (struct globlink *) + __alloca (sizeof (struct globlink)); + len = NAMLEN (d); + new->name = (char *) malloc (len + 1); + if (new->name == NULL) + goto memory_error; +#ifdef HAVE_MEMPCPY + *((char *) mempcpy ((__ptr_t) new->name, name, len)) + = '\0'; +#else + memcpy ((__ptr_t) new->name, name, len); + new->name[len] = '\0'; +#endif + new->next = names; + names = new; + ++nfound; + } + } + } + } + } + + if (nfound == 0 && (flags & GLOB_NOCHECK)) + { + size_t len = strlen (pattern); + nfound = 1; + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->next = NULL; + names->name = (char *) malloc (len + 1); + if (names->name == NULL) + goto memory_error; +#ifdef HAVE_MEMPCPY + *((char *) mempcpy (names->name, pattern, len)) = '\0'; +#else + memcpy (names->name, pattern, len); + names->name[len] = '\0'; +#endif + } + + if (nfound != 0) + { + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + + nfound + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + goto memory_error; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (; names != NULL; names = names->next) + pglob->gl_pathv[pglob->gl_pathc++] = names->name; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + + pglob->gl_flags = flags; + } + + save = errno; + if (stream != NULL) + { + if (flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir) (stream); + else + closedir ((DIR *) stream); + } + __set_errno (save); + + return nfound == 0 ? GLOB_NOMATCH : 0; + + memory_error: + { + int save = errno; + if (flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir) (stream); + else + closedir ((DIR *) stream); + __set_errno (save); + } + while (names != NULL) + { + if (names->name != NULL) + free ((__ptr_t) names->name); + names = names->next; + } + return GLOB_NOSPACE; +} + +#endif /* Not ELIDE_CODE. */ diff --git a/goldlib/glibc/glob.h b/goldlib/glibc/glob.h new file mode 100644 index 0000000..ac7bc82 --- /dev/null +++ b/goldlib/glibc/glob.h @@ -0,0 +1,194 @@ +/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GLOB_H +#define _GLOB_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#undef __ptr_t +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 || defined _WIN32 +# if !defined __GLIBC__ || !defined __P +# undef __P +# undef __PMT +# define __P(protos) protos +# define __PMT(protos) protos +# if !defined __GNUC__ || __GNUC__ < 2 +# undef __const +# define __const const +# endif +# endif +# define __ptr_t void * +#else /* Not C++ or ANSI C. */ +# undef __P +# undef __PMT +# define __P(protos) () +# define __PMT(protos) () +# undef __const +# define __const +# define __ptr_t char * +#endif /* C++ or ANSI C. */ + +/* We need `size_t' for the following definitions. */ +#ifndef __size_t +# if defined __GNUC__ && __GNUC__ >= 2 +typedef __SIZE_TYPE__ __size_t; +# else +/* This is a guess. */ +typedef unsigned long int __size_t; +# endif +#else +/* The GNU CC stddef.h version defines __size_t as empty. We need a real + definition. */ +# undef __size_t +# define __size_t size_t +#endif + +/* Bits set in the FLAGS argument to `glob'. */ +#define GLOB_ERR (1 << 0)/* Return on read errors. */ +#define GLOB_MARK (1 << 1)/* Append a slash to each name. */ +#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */ +#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */ +#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */ +#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */ +#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */ +#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */ + +#if (!defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _BSD_SOURCE \ + || defined _GNU_SOURCE) +# define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */ +# define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */ +# define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */ +# define GLOB_NOMAGIC (1 << 11)/* If no magic chars, return the pattern. */ +# define GLOB_TILDE (1 << 12)/* Expand ~user and ~ to home directories. */ +# define GLOB_ONLYDIR (1 << 13)/* Match only directories. */ +# define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error + if the user name is not available. */ +# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ + GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE| \ + GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK) +#else +# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ + GLOB_PERIOD) +#endif + +/* Error returns from `glob'. */ +#define GLOB_NOSPACE 1 /* Ran out of memory. */ +#define GLOB_ABORTED 2 /* Read error. */ +#define GLOB_NOMATCH 3 /* No matches found. */ +#define GLOB_NOSYS 4 /* Not implemented. */ +#ifdef _GNU_SOURCE +/* Previous versions of this file defined GLOB_ABEND instead of + GLOB_ABORTED. Provide a compatibility definition here. */ +# define GLOB_ABEND GLOB_ABORTED +#endif + +/* Structure describing a globbing run. */ +#if !defined _AMIGA && !defined VMS /* Buggy compiler. */ +struct stat; +#endif +typedef struct + { + __size_t gl_pathc; /* Count of paths matched by the pattern. */ + char **gl_pathv; /* List of matched pathnames. */ + __size_t gl_offs; /* Slots to reserve in `gl_pathv'. */ + int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */ + + /* If the GLOB_ALTDIRFUNC flag is set, the following functions + are used instead of the normal file access functions. */ + void (*gl_closedir) __PMT ((void *)); + struct dirent *(*gl_readdir) __PMT ((void *)); + __ptr_t (*gl_opendir) __PMT ((__const char *)); + int (*gl_lstat) __PMT ((__const char *, struct stat *)); + int (*gl_stat) __PMT ((__const char *, struct stat *)); + } glob_t; + +#ifdef _LARGEFILE64_SOURCE +struct stat64; +typedef struct + { + __size_t gl_pathc; + char **gl_pathv; + __size_t gl_offs; + int gl_flags; + + /* If the GLOB_ALTDIRFUNC flag is set, the following functions + are used instead of the normal file access functions. */ + void (*gl_closedir) __PMT ((void *)); + struct dirent64 *(*gl_readdir) __PMT ((void *)); + __ptr_t (*gl_opendir) __PMT ((__const char *)); + int (*gl_lstat) __PMT ((__const char *, struct stat64 *)); + int (*gl_stat) __PMT ((__const char *, struct stat64 *)); + } glob64_t; +#endif + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +#if _FILE_OFFSET_BITS != 64 +extern int glob __P ((__const char *__pattern, int __flags, + int (*__errfunc) (__const char *, int), + glob_t *__pglob)); + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +extern void globfree __P ((glob_t *__pglob)); +#else +# if __GNUC__ >= 2 +extern int glob __P ((__const char *__pattern, int __flags, + int (*__errfunc) (__const char *, int), + glob_t *__pglob)) __asm__ ("glob64"); + +extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64"); +# else +# define glob glob64 +# define globfree globfree64 +# endif +#endif + +#ifdef _LARGEFILE64_SOURCE +extern int glob64 __P ((__const char *__pattern, int __flags, + int (*__errfunc) (__const char *, int), + glob64_t *__pglob)); + +extern void globfree64 __P ((glob64_t *__pglob)); +#endif + + +#ifdef _GNU_SOURCE +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. + + This function is not part of the interface specified by POSIX.2 + but several programs want to use it. */ +extern int __glob_pattern_p __P ((__const char *__pattern, int __quote)); +extern int glob_pattern_p __P ((__const char *__pattern, int __quote)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* glob.h */ diff --git a/goldlib/glibc/regex.c b/goldlib/glibc/regex.c new file mode 100644 index 0000000..ba01f73 --- /dev/null +++ b/goldlib/glibc/regex.c @@ -0,0 +1,5829 @@ +/* Extended regular expression matching and search library, + version 0.12. + (Implements POSIX draft P1003.2/D11.2, except for some of the + internationalization features.) + Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined _AIX && !defined REGEX_MALLOC + #pragma alloca +#endif + +#undef _GNU_SOURCE +#define _GNU_SOURCE + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifndef PARAMS +# if defined __GNUC__ || (defined __STDC__ && __STDC__) +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif /* GCC. */ +#endif /* Not PARAMS. */ + +#if defined STDC_HEADERS && !defined emacs +# include +#else +/* We need this for `regex.h', and perhaps for the Emacs include files. */ +# include +#endif + +#define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC) + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* Solaris 2.5 has a bug: must be included before . */ +# include +# include +#endif + +#ifdef _LIBC +/* We have to keep the namespace clean. */ +# define regfree(preg) __regfree (preg) +# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) +# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) +# define regerror(errcode, preg, errbuf, errbuf_size) \ + __regerror(errcode, preg, errbuf, errbuf_size) +# define re_set_registers(bu, re, nu, st, en) \ + __re_set_registers (bu, re, nu, st, en) +# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ + __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) +# define re_match(bufp, string, size, pos, regs) \ + __re_match (bufp, string, size, pos, regs) +# define re_search(bufp, string, size, startpos, range, regs) \ + __re_search (bufp, string, size, startpos, range, regs) +# define re_compile_pattern(pattern, length, bufp) \ + __re_compile_pattern (pattern, length, bufp) +# define re_set_syntax(syntax) __re_set_syntax (syntax) +# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ + __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) +# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) + +#define btowc __btowc +#endif + +/* This is for other GNU distributions with internationalized messages. */ +#if HAVE_LIBINTL_H || defined _LIBC +# include +#else +# define gettext(msgid) (msgid) +#endif + +#ifndef gettext_noop +/* This define is so xgettext can find the internationalizable + strings. */ +# define gettext_noop(String) String +#endif + +/* The `emacs' switch turns on certain matching commands + that make sense only in Emacs. */ +#ifdef emacs + +# include "lisp.h" +# include "buffer.h" +# include "syntax.h" + +#else /* not emacs */ + +/* If we are not linking with Emacs proper, + we can't use the relocating allocator + even if config.h says that we can. */ +# undef REL_ALLOC + +# if defined STDC_HEADERS || defined _LIBC +# include +# else +char *malloc (); +char *realloc (); +# endif + +/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. + If nothing else has been done, use the method below. */ +# ifdef INHIBIT_STRING_HEADER +# if !(defined HAVE_BZERO && defined HAVE_BCOPY) +# if !defined bzero && !defined bcopy +# undef INHIBIT_STRING_HEADER +# endif +# endif +# endif + +/* This is the normal way of making sure we have a bcopy and a bzero. + This is used in most programs--a few other programs avoid this + by defining INHIBIT_STRING_HEADER. */ +# ifndef INHIBIT_STRING_HEADER +# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC +# include +# ifndef bzero +# ifndef _LIBC +# define bzero(s, n) (memset (s, '\0', n), (s)) +# else +# define bzero(s, n) __bzero (s, n) +# endif +# endif +# else +# include +# ifndef memcmp +# define memcmp(s1, s2, n) bcmp (s1, s2, n) +# endif +# ifndef memcpy +# define memcpy(d, s, n) (bcopy (s, d, n), (d)) +# endif +# endif +# endif + +/* Define the syntax stuff for \<, \>, etc. */ + +/* This must be nonzero for the wordchar and notwordchar pattern + commands in re_match_2. */ +# ifndef Sword +# define Sword 1 +# endif + +# ifdef SWITCH_ENUM_BUG +# define SWITCH_ENUM_CAST(x) ((int)(x)) +# else +# define SWITCH_ENUM_CAST(x) (x) +# endif + +/* How many characters in the character set. */ +# define CHAR_SET_SIZE 256 + +# ifdef SYNTAX_TABLE + +extern char *re_syntax_table; + +# else /* not SYNTAX_TABLE */ + +static char re_syntax_table[CHAR_SET_SIZE]; + +static void +init_syntax_once () +{ + register int c; + static int done = 0; + + if (done) + return; + + bzero (re_syntax_table, sizeof re_syntax_table); + + for (c = 'a'; c <= 'z'; c++) + re_syntax_table[c] = Sword; + + for (c = 'A'; c <= 'Z'; c++) + re_syntax_table[c] = Sword; + + for (c = '0'; c <= '9'; c++) + re_syntax_table[c] = Sword; + + re_syntax_table['_'] = Sword; + + done = 1; +} + +# endif /* not SYNTAX_TABLE */ + +# define SYNTAX(c) re_syntax_table[c] + +#endif /* not emacs */ + +/* Get the interface, including the syntax bits. */ +#include "regex.h" + +/* isalpha etc. are used for the character classes. */ +#include + +/* Jim Meyering writes: + + "... Some ctype macros are valid only for character codes that + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when + using /bin/cc or gcc but without giving an ansi option). So, all + ctype uses should be through macros like ISPRINT... If + STDC_HEADERS is defined, then autoconf has verified that the ctype + macros don't need to be guarded with references to isascii. ... + Defining isascii to 1 should let any compiler worth its salt + eliminate the && through constant folding." + Solaris defines some of these symbols so we must undefine them first. */ + +#undef ISASCII +#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) +# define ISASCII(c) 1 +#else +# define ISASCII(c) isascii(c) +#endif + +#ifdef isblank +# define ISBLANK(c) (ISASCII (c) && isblank (c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif +#ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +#else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +#endif + +#undef ISPRINT +#define ISPRINT(c) (ISASCII (c) && isprint (c)) +#define ISDIGIT(c) (ISASCII (c) && isdigit (c)) +#define ISALNUM(c) (ISASCII (c) && isalnum (c)) +#define ISALPHA(c) (ISASCII (c) && isalpha (c)) +#define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) +#define ISLOWER(c) (ISASCII (c) && islower (c)) +#define ISPUNCT(c) (ISASCII (c) && ispunct (c)) +#define ISSPACE(c) (ISASCII (c) && isspace (c)) +#define ISUPPER(c) (ISASCII (c) && isupper (c)) +#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) + +#ifndef NULL +# define NULL (void *)0 +#endif + +/* We remove any previous definition of `SIGN_EXTEND_CHAR', + since ours (we hope) works properly with all combinations of + machines, compilers, `char' and `unsigned char' argument types. + (Per Bothner suggested the basic approach.) */ +#undef SIGN_EXTEND_CHAR +#if __STDC__ +# define SIGN_EXTEND_CHAR(c) ((signed char) (c)) +#else /* not __STDC__ */ +/* As in Harbison and Steele. */ +# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) +#endif + +/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we + use `alloca' instead of `malloc'. This is because using malloc in + re_search* or re_match* could cause memory leaks when C-g is used in + Emacs; also, malloc is slower and causes storage fragmentation. On + the other hand, malloc is more portable, and easier to debug. + + Because we sometimes use alloca, some routines have to be macros, + not functions -- `alloca'-allocated space disappears at the end of the + function it is called in. */ + +#ifdef REGEX_MALLOC + +# define REGEX_ALLOCATE malloc +# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) +# define REGEX_FREE free + +#else /* not REGEX_MALLOC */ + +/* Emacs already defines alloca, sometimes. */ +# ifndef alloca + +/* Make alloca work the best possible way. */ +# ifdef __GNUC__ +# define alloca __builtin_alloca +# else /* not __GNUC__ */ +# if HAVE_ALLOCA_H +# include +# endif /* HAVE_ALLOCA_H */ +# endif /* not __GNUC__ */ + +# endif /* not alloca */ + +# define REGEX_ALLOCATE alloca + +/* Assumes a `char *destination' variable. */ +# define REGEX_REALLOCATE(source, osize, nsize) \ + (destination = (char *) alloca (nsize), \ + memcpy (destination, source, osize)) + +/* No need to do anything to free, after alloca. */ +# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ + +#endif /* not REGEX_MALLOC */ + +/* Define how to allocate the failure stack. */ + +#if defined REL_ALLOC && defined REGEX_MALLOC + +# define REGEX_ALLOCATE_STACK(size) \ + r_alloc (&failure_stack_ptr, (size)) +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + r_re_alloc (&failure_stack_ptr, (nsize)) +# define REGEX_FREE_STACK(ptr) \ + r_alloc_free (&failure_stack_ptr) + +#else /* not using relocating allocator */ + +# ifdef REGEX_MALLOC + +# define REGEX_ALLOCATE_STACK malloc +# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) +# define REGEX_FREE_STACK free + +# else /* not REGEX_MALLOC */ + +# define REGEX_ALLOCATE_STACK alloca + +# define REGEX_REALLOCATE_STACK(source, osize, nsize) \ + REGEX_REALLOCATE (source, osize, nsize) +/* No need to explicitly free anything. */ +# define REGEX_FREE_STACK(arg) + +# endif /* not REGEX_MALLOC */ +#endif /* not using relocating allocator */ + + +/* True if `size1' is non-NULL and PTR is pointing anywhere inside + `string1' or just past its end. This works if PTR is NULL, which is + a good thing. */ +#define FIRST_STRING_P(ptr) \ + (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) + +/* (Re)Allocate N items of type T using malloc, or fail. */ +#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) +#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) +#define RETALLOC_IF(addr, n, t) \ + if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) +#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) + +#define BYTEWIDTH 8 /* In bits. */ + +#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +#undef MAX +#undef MIN +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +typedef char boolean; +#define false 0 +#define true 1 + +static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, + const char *string1, int size1, + const char *string2, int size2, + int pos, + struct re_registers *regs, + int stop)); + +/* These are the command codes that appear in compiled regular + expressions. Some opcodes are followed by argument bytes. A + command code can specify any interpretation whatsoever for its + arguments. Zero bytes may appear in the compiled regular expression. */ + +typedef enum +{ + no_op = 0, + + /* Succeed right away--no more backtracking. */ + succeed, + + /* Followed by one byte giving n, then by n literal bytes. */ + exactn, + + /* Matches any (more or less) character. */ + anychar, + + /* Matches any one char belonging to specified set. First + following byte is number of bitmap bytes. Then come bytes + for a bitmap saying which chars are in. Bits in each byte + are ordered low-bit-first. A character is in the set if its + bit is 1. A character too large to have a bit in the map is + automatically not in the set. */ + charset, + + /* Same parameters as charset, but match any character that is + not one of those specified. */ + charset_not, + + /* Start remembering the text that is matched, for storing in a + register. Followed by one byte with the register number, in + the range 0 to one less than the pattern buffer's re_nsub + field. Then followed by one byte with the number of groups + inner to this one. (This last has to be part of the + start_memory only because we need it in the on_failure_jump + of re_match_2.) */ + start_memory, + + /* Stop remembering the text that is matched and store it in a + memory register. Followed by one byte with the register + number, in the range 0 to one less than `re_nsub' in the + pattern buffer, and one byte with the number of inner groups, + just like `start_memory'. (We need the number of inner + groups here because we don't have any easy way of finding the + corresponding start_memory when we're at a stop_memory.) */ + stop_memory, + + /* Match a duplicate of something remembered. Followed by one + byte containing the register number. */ + duplicate, + + /* Fail unless at beginning of line. */ + begline, + + /* Fail unless at end of line. */ + endline, + + /* Succeeds if at beginning of buffer (if emacs) or at beginning + of string to be matched (if not). */ + begbuf, + + /* Analogously, for end of buffer/string. */ + endbuf, + + /* Followed by two byte relative address to which to jump. */ + jump, + + /* Same as jump, but marks the end of an alternative. */ + jump_past_alt, + + /* Followed by two-byte relative address of place to resume at + in case of failure. */ + on_failure_jump, + + /* Like on_failure_jump, but pushes a placeholder instead of the + current string position when executed. */ + on_failure_keep_string_jump, + + /* Throw away latest failure point and then jump to following + two-byte relative address. */ + pop_failure_jump, + + /* Change to pop_failure_jump if know won't have to backtrack to + match; otherwise change to jump. This is used to jump + back to the beginning of a repeat. If what follows this jump + clearly won't match what the repeat does, such that we can be + sure that there is no use backtracking out of repetitions + already matched, then we change it to a pop_failure_jump. + Followed by two-byte address. */ + maybe_pop_jump, + + /* Jump to following two-byte address, and push a dummy failure + point. This failure point will be thrown away if an attempt + is made to use it for a failure. A `+' construct makes this + before the first repeat. Also used as an intermediary kind + of jump when compiling an alternative. */ + dummy_failure_jump, + + /* Push a dummy failure point and continue. Used at the end of + alternatives. */ + push_dummy_failure, + + /* Followed by two-byte relative address and two-byte number n. + After matching N times, jump to the address upon failure. */ + succeed_n, + + /* Followed by two-byte relative address, and two-byte number n. + Jump to the address N times, then fail. */ + jump_n, + + /* Set the following two-byte relative address to the + subsequent two-byte number. The address *includes* the two + bytes of number. */ + set_number_at, + + wordchar, /* Matches any word-constituent character. */ + notwordchar, /* Matches any char that is not a word-constituent. */ + + wordbeg, /* Succeeds if at word beginning. */ + wordend, /* Succeeds if at word end. */ + + wordbound, /* Succeeds if at a word boundary. */ + notwordbound /* Succeeds if not at a word boundary. */ + +#ifdef emacs + ,before_dot, /* Succeeds if before point. */ + at_dot, /* Succeeds if at point. */ + after_dot, /* Succeeds if after point. */ + + /* Matches any character whose syntax is specified. Followed by + a byte which contains a syntax code, e.g., Sword. */ + syntaxspec, + + /* Matches any character whose syntax is not that specified. */ + notsyntaxspec +#endif /* emacs */ +} re_opcode_t; + +/* Common operations on the compiled pattern. */ + +/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ + +#define STORE_NUMBER(destination, number) \ + do { \ + (destination)[0] = (number) & 0377; \ + (destination)[1] = (number) >> 8; \ + } while (0) + +/* Same as STORE_NUMBER, except increment DESTINATION to + the byte after where the number is stored. Therefore, DESTINATION + must be an lvalue. */ + +#define STORE_NUMBER_AND_INCR(destination, number) \ + do { \ + STORE_NUMBER (destination, number); \ + (destination) += 2; \ + } while (0) + +/* Put into DESTINATION a number stored in two contiguous bytes starting + at SOURCE. */ + +#define EXTRACT_NUMBER(destination, source) \ + do { \ + (destination) = *(source) & 0377; \ + (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ + } while (0) + +#ifdef DEBUG +static void extract_number _RE_ARGS ((int *dest, unsigned char *source)); +static void +extract_number (dest, source) + int *dest; + unsigned char *source; +{ + int temp = SIGN_EXTEND_CHAR (*(source + 1)); + *dest = *source & 0377; + *dest += temp << 8; +} + +# ifndef EXTRACT_MACROS /* To debug the macros. */ +# undef EXTRACT_NUMBER +# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) +# endif /* not EXTRACT_MACROS */ + +#endif /* DEBUG */ + +/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. + SOURCE must be an lvalue. */ + +#define EXTRACT_NUMBER_AND_INCR(destination, source) \ + do { \ + EXTRACT_NUMBER (destination, source); \ + (source) += 2; \ + } while (0) + +#ifdef DEBUG +static void extract_number_and_incr _RE_ARGS ((int *destination, + unsigned char **source)); +static void +extract_number_and_incr (destination, source) + int *destination; + unsigned char **source; +{ + extract_number (destination, *source); + *source += 2; +} + +# ifndef EXTRACT_MACROS +# undef EXTRACT_NUMBER_AND_INCR +# define EXTRACT_NUMBER_AND_INCR(dest, src) \ + extract_number_and_incr (&dest, &src) +# endif /* not EXTRACT_MACROS */ + +#endif /* DEBUG */ + +/* If DEBUG is defined, Regex prints many voluminous messages about what + it is doing (if the variable `debug' is nonzero). If linked with the + main program in `iregex.c', you can enter patterns and strings + interactively. And if linked with the main program in `main.c' and + the other test files, you can run the already-written tests. */ + +#ifdef DEBUG + +/* We use standard I/O for debugging. */ +# include + +/* It is useful to test things that ``must'' be true when debugging. */ +# include + +static int debug = 0; + +# define DEBUG_STATEMENT(e) e +# define DEBUG_PRINT1(x) if (debug) printf (x) +# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) +# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) +# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ + if (debug) print_partial_compiled_pattern (s, e) +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ + if (debug) print_double_string (w, s1, sz1, s2, sz2) + + +/* Print the fastmap in human-readable form. */ + +void +print_fastmap (fastmap) + char *fastmap; +{ + unsigned was_a_range = 0; + unsigned i = 0; + + while (i < (1 << BYTEWIDTH)) + { + if (fastmap[i++]) + { + was_a_range = 0; + putchar (i - 1); + while (i < (1 << BYTEWIDTH) && fastmap[i]) + { + was_a_range = 1; + i++; + } + if (was_a_range) + { + printf ("-"); + putchar (i - 1); + } + } + } + putchar ('\n'); +} + + +/* Print a compiled pattern string in human-readable form, starting at + the START pointer into it and ending just before the pointer END. */ + +void +print_partial_compiled_pattern (start, end) + unsigned char *start; + unsigned char *end; +{ + int mcnt, mcnt2; + unsigned char *p1; + unsigned char *p = start; + unsigned char *pend = end; + + if (start == NULL) + { + printf ("(null)\n"); + return; + } + + /* Loop over pattern commands. */ + while (p < pend) + { + printf ("%d:\t", p - start); + + switch ((re_opcode_t) *p++) + { + case no_op: + printf ("/no_op"); + break; + + case exactn: + mcnt = *p++; + printf ("/exactn/%d", mcnt); + do + { + putchar ('/'); + putchar (*p++); + } + while (--mcnt); + break; + + case start_memory: + mcnt = *p++; + printf ("/start_memory/%d/%d", mcnt, *p++); + break; + + case stop_memory: + mcnt = *p++; + printf ("/stop_memory/%d/%d", mcnt, *p++); + break; + + case duplicate: + printf ("/duplicate/%d", *p++); + break; + + case anychar: + printf ("/anychar"); + break; + + case charset: + case charset_not: + { + register int c, last = -100; + register int in_range = 0; + + printf ("/charset [%s", + (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); + + assert (p + *p < pend); + + for (c = 0; c < 256; c++) + if (c / 8 < *p + && (p[1 + (c/8)] & (1 << (c % 8)))) + { + /* Are we starting a range? */ + if (last + 1 == c && ! in_range) + { + putchar ('-'); + in_range = 1; + } + /* Have we broken a range? */ + else if (last + 1 != c && in_range) + { + putchar (last); + in_range = 0; + } + + if (! in_range) + putchar (c); + + last = c; + } + + if (in_range) + putchar (last); + + putchar (']'); + + p += 1 + *p; + } + break; + + case begline: + printf ("/begline"); + break; + + case endline: + printf ("/endline"); + break; + + case on_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/on_failure_jump to %d", p + mcnt - start); + break; + + case on_failure_keep_string_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/on_failure_keep_string_jump to %d", p + mcnt - start); + break; + + case dummy_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/dummy_failure_jump to %d", p + mcnt - start); + break; + + case push_dummy_failure: + printf ("/push_dummy_failure"); + break; + + case maybe_pop_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/maybe_pop_jump to %d", p + mcnt - start); + break; + + case pop_failure_jump: + extract_number_and_incr (&mcnt, &p); + printf ("/pop_failure_jump to %d", p + mcnt - start); + break; + + case jump_past_alt: + extract_number_and_incr (&mcnt, &p); + printf ("/jump_past_alt to %d", p + mcnt - start); + break; + + case jump: + extract_number_and_incr (&mcnt, &p); + printf ("/jump to %d", p + mcnt - start); + break; + + case succeed_n: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/succeed_n to %d, %d times", p1 - start, mcnt2); + break; + + case jump_n: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/jump_n to %d, %d times", p1 - start, mcnt2); + break; + + case set_number_at: + extract_number_and_incr (&mcnt, &p); + p1 = p + mcnt; + extract_number_and_incr (&mcnt2, &p); + printf ("/set_number_at location %d to %d", p1 - start, mcnt2); + break; + + case wordbound: + printf ("/wordbound"); + break; + + case notwordbound: + printf ("/notwordbound"); + break; + + case wordbeg: + printf ("/wordbeg"); + break; + + case wordend: + printf ("/wordend"); + +# ifdef emacs + case before_dot: + printf ("/before_dot"); + break; + + case at_dot: + printf ("/at_dot"); + break; + + case after_dot: + printf ("/after_dot"); + break; + + case syntaxspec: + printf ("/syntaxspec"); + mcnt = *p++; + printf ("/%d", mcnt); + break; + + case notsyntaxspec: + printf ("/notsyntaxspec"); + mcnt = *p++; + printf ("/%d", mcnt); + break; +# endif /* emacs */ + + case wordchar: + printf ("/wordchar"); + break; + + case notwordchar: + printf ("/notwordchar"); + break; + + case begbuf: + printf ("/begbuf"); + break; + + case endbuf: + printf ("/endbuf"); + break; + + default: + printf ("?%d", *(p-1)); + } + + putchar ('\n'); + } + + printf ("%d:\tend of pattern.\n", p - start); +} + + +void +print_compiled_pattern (bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *buffer = bufp->buffer; + + print_partial_compiled_pattern (buffer, buffer + bufp->used); + printf ("%ld bytes used/%ld bytes allocated.\n", + bufp->used, bufp->allocated); + + if (bufp->fastmap_accurate && bufp->fastmap) + { + printf ("fastmap: "); + print_fastmap (bufp->fastmap); + } + + printf ("re_nsub: %d\t", bufp->re_nsub); + printf ("regs_alloc: %d\t", bufp->regs_allocated); + printf ("can_be_null: %d\t", bufp->can_be_null); + printf ("newline_anchor: %d\n", bufp->newline_anchor); + printf ("no_sub: %d\t", bufp->no_sub); + printf ("not_bol: %d\t", bufp->not_bol); + printf ("not_eol: %d\t", bufp->not_eol); + printf ("syntax: %lx\n", bufp->syntax); + /* Perhaps we should print the translate table? */ +} + + +void +print_double_string (where, string1, size1, string2, size2) + const char *where; + const char *string1; + const char *string2; + int size1; + int size2; +{ + int this_char; + + if (where == NULL) + printf ("(null)"); + else + { + if (FIRST_STRING_P (where)) + { + for (this_char = where - string1; this_char < size1; this_char++) + putchar (string1[this_char]); + + where = string2; + } + + for (this_char = where - string2; this_char < size2; this_char++) + putchar (string2[this_char]); + } +} + +void +printchar (c) + int c; +{ + putc (c, stderr); +} + +#else /* not DEBUG */ + +# undef assert +# define assert(e) + +# define DEBUG_STATEMENT(e) +# define DEBUG_PRINT1(x) +# define DEBUG_PRINT2(x1, x2) +# define DEBUG_PRINT3(x1, x2, x3) +# define DEBUG_PRINT4(x1, x2, x3, x4) +# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) +# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) + +#endif /* not DEBUG */ + +/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can + also be assigned to arbitrarily: each pattern buffer stores its own + syntax, so it can be changed between regex compilations. */ +/* This has no initializer because initialized variables in Emacs + become read-only after dumping. */ +reg_syntax_t re_syntax_options; + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit mask comprised of the various bits + defined in regex.h. We return the old syntax. */ + +reg_syntax_t +re_set_syntax (syntax) + reg_syntax_t syntax; +{ + reg_syntax_t ret = re_syntax_options; + + re_syntax_options = syntax; +#ifdef DEBUG + if (syntax & RE_DEBUG) + debug = 1; + else if (debug) /* was on but now is not */ + debug = 0; +#endif /* DEBUG */ + return ret; +} +#ifdef _LIBC +weak_alias (__re_set_syntax, re_set_syntax) +#endif + +/* This table gives an error message for each of the error codes listed + in regex.h. Obviously the order here has to be same as there. + POSIX doesn't require that we do anything for REG_NOERROR, + but why not be nice? */ + +static const char *re_error_msgid[] = + { + gettext_noop ("Success"), /* REG_NOERROR */ + gettext_noop ("No match"), /* REG_NOMATCH */ + gettext_noop ("Invalid regular expression"), /* REG_BADPAT */ + gettext_noop ("Invalid collation character"), /* REG_ECOLLATE */ + gettext_noop ("Invalid character class name"), /* REG_ECTYPE */ + gettext_noop ("Trailing backslash"), /* REG_EESCAPE */ + gettext_noop ("Invalid back reference"), /* REG_ESUBREG */ + gettext_noop ("Unmatched [ or [^"), /* REG_EBRACK */ + gettext_noop ("Unmatched ( or \\("), /* REG_EPAREN */ + gettext_noop ("Unmatched \\{"), /* REG_EBRACE */ + gettext_noop ("Invalid content of \\{\\}"), /* REG_BADBR */ + gettext_noop ("Invalid range end"), /* REG_ERANGE */ + gettext_noop ("Memory exhausted"), /* REG_ESPACE */ + gettext_noop ("Invalid preceding regular expression"), /* REG_BADRPT */ + gettext_noop ("Premature end of regular expression"), /* REG_EEND */ + gettext_noop ("Regular expression too big"), /* REG_ESIZE */ + gettext_noop ("Unmatched ) or \\)"), /* REG_ERPAREN */ + }; + +/* Avoiding alloca during matching, to placate r_alloc. */ + +/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the + searching and matching functions should not call alloca. On some + systems, alloca is implemented in terms of malloc, and if we're + using the relocating allocator routines, then malloc could cause a + relocation, which might (if the strings being searched are in the + ralloc heap) shift the data out from underneath the regexp + routines. + + Here's another reason to avoid allocation: Emacs + processes input from X in a signal handler; processing X input may + call malloc; if input arrives while a matching routine is calling + malloc, then we're scrod. But Emacs can't just block input while + calling matching routines; then we don't notice interrupts when + they come in. So, Emacs blocks input around all regexp calls + except the matching calls, which it leaves unprotected, in the + faith that they will not malloc. */ + +/* Normally, this is fine. */ +#define MATCH_MAY_ALLOCATE + +/* When using GNU C, we are not REALLY using the C alloca, no matter + what config.h may say. So don't take precautions for it. */ +#ifdef __GNUC__ +# undef C_ALLOCA +#endif + +/* The match routines may not allocate if (1) they would do it with malloc + and (2) it's not safe for them to use malloc. + Note that if REL_ALLOC is defined, matching would not use malloc for the + failure stack, but we would still use it for the register vectors; + so REL_ALLOC should not affect this. */ +#if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs +# undef MATCH_MAY_ALLOCATE +#endif + + +/* Failure stack declarations and macros; both re_compile_fastmap and + re_match_2 use a failure stack. These have to be macros because of + REGEX_ALLOCATE_STACK. */ + + +/* Number of failure points for which to initially allocate space + when matching. If this number is exceeded, we allocate more + space, so it is not a hard limit. */ +#ifndef INIT_FAILURE_ALLOC +# define INIT_FAILURE_ALLOC 5 +#endif + +/* Roughly the maximum number of failure points on the stack. Would be + exactly that if always used MAX_FAILURE_ITEMS items each time we failed. + This is a variable only so users of regex can assign to it; we never + change it ourselves. */ + +#ifdef INT_IS_16BIT + +# if defined MATCH_MAY_ALLOCATE +/* 4400 was enough to cause a crash on Alpha OSF/1, + whose default stack limit is 2mb. */ +long int re_max_failures = 4000; +# else +long int re_max_failures = 2000; +# endif + +union fail_stack_elt +{ + unsigned char *pointer; + long int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; + +typedef struct +{ + fail_stack_elt_t *stack; + unsigned long int size; + unsigned long int avail; /* Offset of next open position. */ +} fail_stack_type; + +#else /* not INT_IS_16BIT */ + +# if defined MATCH_MAY_ALLOCATE +/* 4400 was enough to cause a crash on Alpha OSF/1, + whose default stack limit is 2mb. */ +int re_max_failures = 20000; +# else +int re_max_failures = 2000; +# endif + +union fail_stack_elt +{ + unsigned char *pointer; + int integer; +}; + +typedef union fail_stack_elt fail_stack_elt_t; + +typedef struct +{ + fail_stack_elt_t *stack; + unsigned size; + unsigned avail; /* Offset of next open position. */ +} fail_stack_type; + +#endif /* INT_IS_16BIT */ + +#define FAIL_STACK_EMPTY() (fail_stack.avail == 0) +#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) +#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) + + +/* Define macros to initialize and free the failure stack. + Do `return -2' if the alloc fails. */ + +#ifdef MATCH_MAY_ALLOCATE +# define INIT_FAIL_STACK() \ + do { \ + fail_stack.stack = (fail_stack_elt_t *) \ + REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ + \ + if (fail_stack.stack == NULL) \ + return -2; \ + \ + fail_stack.size = INIT_FAILURE_ALLOC; \ + fail_stack.avail = 0; \ + } while (0) + +# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) +#else +# define INIT_FAIL_STACK() \ + do { \ + fail_stack.avail = 0; \ + } while (0) + +# define RESET_FAIL_STACK() +#endif + + +/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. + + Return 1 if succeeds, and 0 if either ran out of memory + allocating space for it or it was already too large. + + REGEX_REALLOCATE_STACK requires `destination' be declared. */ + +#define DOUBLE_FAIL_STACK(fail_stack) \ + ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \ + ? 0 \ + : ((fail_stack).stack = (fail_stack_elt_t *) \ + REGEX_REALLOCATE_STACK ((fail_stack).stack, \ + (fail_stack).size * sizeof (fail_stack_elt_t), \ + ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ + \ + (fail_stack).stack == NULL \ + ? 0 \ + : ((fail_stack).size <<= 1, \ + 1))) + + +/* Push pointer POINTER on FAIL_STACK. + Return 1 if was able to do so and 0 if ran out of memory allocating + space to do so. */ +#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ + ((FAIL_STACK_FULL () \ + && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ + ? 0 \ + : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ + 1)) + +/* Push a pointer value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_POINTER(item) \ + fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) + +/* This pushes an integer-valued item onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_INT(item) \ + fail_stack.stack[fail_stack.avail++].integer = (item) + +/* Push a fail_stack_elt_t value onto the failure stack. + Assumes the variable `fail_stack'. Probably should only + be called from within `PUSH_FAILURE_POINT'. */ +#define PUSH_FAILURE_ELT(item) \ + fail_stack.stack[fail_stack.avail++] = (item) + +/* These three POP... operations complement the three PUSH... operations. + All assume that `fail_stack' is nonempty. */ +#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer +#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer +#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] + +/* Used to omit pushing failure point id's when we're not debugging. */ +#ifdef DEBUG +# define DEBUG_PUSH PUSH_FAILURE_INT +# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () +#else +# define DEBUG_PUSH(item) +# define DEBUG_POP(item_addr) +#endif + + +/* Push the information about the state we will need + if we ever fail back to it. + + Requires variables fail_stack, regstart, regend, reg_info, and + num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination' + be declared. + + Does `return FAILURE_CODE' if runs out of memory. */ + +#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ + do { \ + char *destination; \ + /* Must be int, so when we don't save any registers, the arithmetic \ + of 0 + -1 isn't done as unsigned. */ \ + /* Can't be int, since there is not a shred of a guarantee that int \ + is wide enough to hold a value of something to which pointer can \ + be assigned */ \ + active_reg_t this_reg; \ + \ + DEBUG_STATEMENT (failure_id++); \ + DEBUG_STATEMENT (nfailure_points_pushed++); \ + DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ + DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ + DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ + \ + DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \ + DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ + \ + /* Ensure we have enough space allocated for what we will push. */ \ + while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ + { \ + if (!DOUBLE_FAIL_STACK (fail_stack)) \ + return failure_code; \ + \ + DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ + (fail_stack).size); \ + DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ + } \ + \ + /* Push the info, starting with the registers. */ \ + DEBUG_PRINT1 ("\n"); \ + \ + if (1) \ + for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ + this_reg++) \ + { \ + DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \ + DEBUG_STATEMENT (num_regs_pushed++); \ + \ + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ + PUSH_FAILURE_POINTER (regstart[this_reg]); \ + \ + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ + PUSH_FAILURE_POINTER (regend[this_reg]); \ + \ + DEBUG_PRINT2 (" info: %p\n ", \ + reg_info[this_reg].word.pointer); \ + DEBUG_PRINT2 (" match_null=%d", \ + REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ + DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ + DEBUG_PRINT2 (" matched_something=%d", \ + MATCHED_SOMETHING (reg_info[this_reg])); \ + DEBUG_PRINT2 (" ever_matched=%d", \ + EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ + DEBUG_PRINT1 ("\n"); \ + PUSH_FAILURE_ELT (reg_info[this_reg].word); \ + } \ + \ + DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\ + PUSH_FAILURE_INT (lowest_active_reg); \ + \ + DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\ + PUSH_FAILURE_INT (highest_active_reg); \ + \ + DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \ + DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ + PUSH_FAILURE_POINTER (pattern_place); \ + \ + DEBUG_PRINT2 (" Pushing string %p: `", string_place); \ + DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ + size2); \ + DEBUG_PRINT1 ("'\n"); \ + PUSH_FAILURE_POINTER (string_place); \ + \ + DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ + DEBUG_PUSH (failure_id); \ + } while (0) + +/* This is the number of items that are pushed and popped on the stack + for each register. */ +#define NUM_REG_ITEMS 3 + +/* Individual items aside from the registers. */ +#ifdef DEBUG +# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ +#else +# define NUM_NONREG_ITEMS 4 +#endif + +/* We push at most this many items on the stack. */ +/* We used to use (num_regs - 1), which is the number of registers + this regexp will save; but that was changed to 5 + to avoid stack overflow for a regexp with lots of parens. */ +#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS) + +/* We actually push this many items. */ +#define NUM_FAILURE_ITEMS \ + (((0 \ + ? 0 : highest_active_reg - lowest_active_reg + 1) \ + * NUM_REG_ITEMS) \ + + NUM_NONREG_ITEMS) + +/* How many items can still be added to the stack without overflowing it. */ +#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) + + +/* Pops what PUSH_FAIL_STACK pushes. + + We restore into the parameters, all of which should be lvalues: + STR -- the saved data position. + PAT -- the saved pattern position. + LOW_REG, HIGH_REG -- the highest and lowest active registers. + REGSTART, REGEND -- arrays of string positions. + REG_INFO -- array of information about each subexpression. + + Also assumes the variables `fail_stack' and (if debugging), `bufp', + `pend', `string1', `size1', `string2', and `size2'. */ + +#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ +{ \ + DEBUG_STATEMENT (unsigned failure_id;) \ + active_reg_t this_reg; \ + const unsigned char *string_temp; \ + \ + assert (!FAIL_STACK_EMPTY ()); \ + \ + /* Remove failure points and point to how many regs pushed. */ \ + DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ + DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ + DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ + \ + assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ + \ + DEBUG_POP (&failure_id); \ + DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ + \ + /* If the saved string location is NULL, it came from an \ + on_failure_keep_string_jump opcode, and we want to throw away the \ + saved NULL, thus retaining our current position in the string. */ \ + string_temp = POP_FAILURE_POINTER (); \ + if (string_temp != NULL) \ + str = (const char *) string_temp; \ + \ + DEBUG_PRINT2 (" Popping string %p: `", str); \ + DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ + DEBUG_PRINT1 ("'\n"); \ + \ + pat = (unsigned char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \ + DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ + \ + /* Restore register info. */ \ + high_reg = (active_reg_t) POP_FAILURE_INT (); \ + DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \ + \ + low_reg = (active_reg_t) POP_FAILURE_INT (); \ + DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \ + \ + if (1) \ + for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ + { \ + DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \ + \ + reg_info[this_reg].word = POP_FAILURE_ELT (); \ + DEBUG_PRINT2 (" info: %p\n", \ + reg_info[this_reg].word.pointer); \ + \ + regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ + \ + regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \ + DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ + } \ + else \ + { \ + for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ + { \ + reg_info[this_reg].word.integer = 0; \ + regend[this_reg] = 0; \ + regstart[this_reg] = 0; \ + } \ + highest_active_reg = high_reg; \ + } \ + \ + set_regs_matched_done = 0; \ + DEBUG_STATEMENT (nfailure_points_popped++); \ +} /* POP_FAILURE_POINT */ + + + +/* Structure for per-register (a.k.a. per-group) information. + Other register information, such as the + starting and ending positions (which are addresses), and the list of + inner groups (which is a bits list) are maintained in separate + variables. + + We are making a (strictly speaking) nonportable assumption here: that + the compiler will pack our bit fields into something that fits into + the type of `word', i.e., is something that fits into one item on the + failure stack. */ + + +/* Declarations and macros for re_match_2. */ + +typedef union +{ + fail_stack_elt_t word; + struct + { + /* This field is one if this group can match the empty string, + zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ +#define MATCH_NULL_UNSET_VALUE 3 + unsigned match_null_string_p : 2; + unsigned is_active : 1; + unsigned matched_something : 1; + unsigned ever_matched_something : 1; + } bits; +} register_info_type; + +#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) +#define IS_ACTIVE(R) ((R).bits.is_active) +#define MATCHED_SOMETHING(R) ((R).bits.matched_something) +#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) + + +/* Call this when have matched a real character; it sets `matched' flags + for the subexpressions which we are currently inside. Also records + that those subexprs have matched. */ +#define SET_REGS_MATCHED() \ + do \ + { \ + if (!set_regs_matched_done) \ + { \ + active_reg_t r; \ + set_regs_matched_done = 1; \ + for (r = lowest_active_reg; r <= highest_active_reg; r++) \ + { \ + MATCHED_SOMETHING (reg_info[r]) \ + = EVER_MATCHED_SOMETHING (reg_info[r]) \ + = 1; \ + } \ + } \ + } \ + while (0) + +/* Registers are set to a sentinel when they haven't yet matched. */ +static char reg_unset_dummy; +#define REG_UNSET_VALUE (®_unset_dummy) +#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) + +/* Subroutine declarations and macros for regex_compile. */ + +static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size, + reg_syntax_t syntax, + struct re_pattern_buffer *bufp)); +static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg)); +static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg1, int arg2)); +static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg, unsigned char *end)); +static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, + int arg1, int arg2, unsigned char *end)); +static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p, + reg_syntax_t syntax)); +static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend, + reg_syntax_t syntax)); +static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr, + const char *pend, + char *translate, + reg_syntax_t syntax, + unsigned char *b)); + +/* Fetch the next character in the uncompiled pattern---translating it + if necessary. Also cast from a signed character in the constant + string passed to us by the user to an unsigned char that we can use + as an array index (in, e.g., `translate'). */ +#ifndef PATFETCH +# define PATFETCH(c) \ + do {if (p == pend) return REG_EEND; \ + c = (unsigned char) *p++; \ + if (translate) c = (unsigned char) translate[c]; \ + } while (0) +#endif + +/* Fetch the next character in the uncompiled pattern, with no + translation. */ +#define PATFETCH_RAW(c) \ + do {if (p == pend) return REG_EEND; \ + c = (unsigned char) *p++; \ + } while (0) + +/* Go backwards one character in the pattern. */ +#define PATUNFETCH p-- + + +/* If `translate' is non-null, return translate[D], else just D. We + cast the subscript to translate because some data is declared as + `char *', to avoid warnings when a string constant is passed. But + when we use a character as a subscript we must make it unsigned. */ +#ifndef TRANSLATE +# define TRANSLATE(d) \ + (translate ? (char) translate[(unsigned char) (d)] : (d)) +#endif + + +/* Macros for outputting the compiled pattern into `buffer'. */ + +/* If the buffer isn't allocated when it comes in, use this. */ +#define INIT_BUF_SIZE 32 + +/* Make sure we have at least N more bytes of space in buffer. */ +#define GET_BUFFER_SPACE(n) \ + while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \ + EXTEND_BUFFER () + +/* Make sure we have one more byte of buffer space and then add C to it. */ +#define BUF_PUSH(c) \ + do { \ + GET_BUFFER_SPACE (1); \ + *b++ = (unsigned char) (c); \ + } while (0) + + +/* Ensure we have two more bytes of buffer space and then append C1 and C2. */ +#define BUF_PUSH_2(c1, c2) \ + do { \ + GET_BUFFER_SPACE (2); \ + *b++ = (unsigned char) (c1); \ + *b++ = (unsigned char) (c2); \ + } while (0) + + +/* As with BUF_PUSH_2, except for three bytes. */ +#define BUF_PUSH_3(c1, c2, c3) \ + do { \ + GET_BUFFER_SPACE (3); \ + *b++ = (unsigned char) (c1); \ + *b++ = (unsigned char) (c2); \ + *b++ = (unsigned char) (c3); \ + } while (0) + + +/* Store a jump with opcode OP at LOC to location TO. We store a + relative address offset by the three bytes the jump itself occupies. */ +#define STORE_JUMP(op, loc, to) \ + store_op1 (op, loc, (int) ((to) - (loc) - 3)) + +/* Likewise, for a two-argument jump. */ +#define STORE_JUMP2(op, loc, to, arg) \ + store_op2 (op, loc, (int) ((to) - (loc) - 3), arg) + +/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ +#define INSERT_JUMP(op, loc, to) \ + insert_op1 (op, loc, (int) ((to) - (loc) - 3), b) + +/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ +#define INSERT_JUMP2(op, loc, to, arg) \ + insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b) + + +/* This is not an arbitrary limit: the arguments which represent offsets + into the pattern are two bytes long. So if 2^16 bytes turns out to + be too small, many things would have to change. */ +/* Any other compiler which, like MSC, has allocation limit below 2^16 + bytes will have to use approach similar to what was done below for + MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up + reallocating to 0 bytes. Such thing is not going to work too well. + You have been warned!! */ +#if defined _MSC_VER && !defined WIN32 +/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. + The REALLOC define eliminates a flurry of conversion warnings, + but is not required. */ +# define MAX_BUF_SIZE 65500L +# define REALLOC(p,s) realloc ((p), (size_t) (s)) +#else +# define MAX_BUF_SIZE (1L << 16) +# define REALLOC(p,s) realloc ((p), (s)) +#endif + +/* Extend the buffer by twice its current size via realloc and + reset the pointers that pointed into the old block to point to the + correct places in the new one. If extending the buffer results in it + being larger than MAX_BUF_SIZE, then flag memory exhausted. */ +#define EXTEND_BUFFER() \ + do { \ + unsigned char *old_buffer = bufp->buffer; \ + if (bufp->allocated == MAX_BUF_SIZE) \ + return REG_ESIZE; \ + bufp->allocated <<= 1; \ + if (bufp->allocated > MAX_BUF_SIZE) \ + bufp->allocated = MAX_BUF_SIZE; \ + bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\ + if (bufp->buffer == NULL) \ + return REG_ESPACE; \ + /* If the buffer moved, move all the pointers into it. */ \ + if (old_buffer != bufp->buffer) \ + { \ + b = (b - old_buffer) + bufp->buffer; \ + begalt = (begalt - old_buffer) + bufp->buffer; \ + if (fixup_alt_jump) \ + fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ + if (laststart) \ + laststart = (laststart - old_buffer) + bufp->buffer; \ + if (pending_exact) \ + pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ + } \ + } while (0) + + +/* Since we have one byte reserved for the register number argument to + {start,stop}_memory, the maximum number of groups we can report + things about is what fits in that byte. */ +#define MAX_REGNUM 255 + +/* But patterns can have more than `MAX_REGNUM' registers. We just + ignore the excess. */ +typedef unsigned regnum_t; + + +/* Macros for the compile stack. */ + +/* Since offsets can go either forwards or backwards, this type needs to + be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ +/* int may be not enough when sizeof(int) == 2. */ +typedef long pattern_offset_t; + +typedef struct +{ + pattern_offset_t begalt_offset; + pattern_offset_t fixup_alt_jump; + pattern_offset_t inner_group_offset; + pattern_offset_t laststart_offset; + regnum_t regnum; +} compile_stack_elt_t; + + +typedef struct +{ + compile_stack_elt_t *stack; + unsigned size; + unsigned avail; /* Offset of next open position. */ +} compile_stack_type; + + +#define INIT_COMPILE_STACK_SIZE 32 + +#define COMPILE_STACK_EMPTY (compile_stack.avail == 0) +#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) + +/* The next available element. */ +#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) + + +/* Set the bit for character C in a list. */ +#define SET_LIST_BIT(c) \ + (b[((unsigned char) (c)) / BYTEWIDTH] \ + |= 1 << (((unsigned char) c) % BYTEWIDTH)) + + +/* Get the next unsigned number in the uncompiled pattern. */ +#define GET_UNSIGNED_NUMBER(num) \ + { if (p != pend) \ + { \ + PATFETCH (c); \ + while (ISDIGIT (c)) \ + { \ + if (num < 0) \ + num = 0; \ + num = num * 10 + c - '0'; \ + if (p == pend) \ + break; \ + PATFETCH (c); \ + } \ + } \ + } + +#if defined _LIBC || WIDE_CHAR_SUPPORT +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 1. */ +# ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +# else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +# endif + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif +#else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +#endif + +#ifndef MATCH_MAY_ALLOCATE + +/* If we cannot allocate large objects within re_match_2_internal, + we make the fail stack and register vectors global. + The fail stack, we grow to the maximum size when a regexp + is compiled. + The register vectors, we adjust in size each time we + compile a regexp, according to the number of registers it needs. */ + +static fail_stack_type fail_stack; + +/* Size with which the following vectors are currently allocated. + That is so we can make them bigger as needed, + but never make them smaller. */ +static int regs_allocated_size; + +static const char ** regstart, ** regend; +static const char ** old_regstart, ** old_regend; +static const char **best_regstart, **best_regend; +static register_info_type *reg_info; +static const char **reg_dummy; +static register_info_type *reg_info_dummy; + +/* Make the register vectors big enough for NUM_REGS registers, + but don't make them smaller. */ + +static +regex_grow_registers (num_regs) + int num_regs; +{ + if (num_regs > regs_allocated_size) + { + RETALLOC_IF (regstart, num_regs, const char *); + RETALLOC_IF (regend, num_regs, const char *); + RETALLOC_IF (old_regstart, num_regs, const char *); + RETALLOC_IF (old_regend, num_regs, const char *); + RETALLOC_IF (best_regstart, num_regs, const char *); + RETALLOC_IF (best_regend, num_regs, const char *); + RETALLOC_IF (reg_info, num_regs, register_info_type); + RETALLOC_IF (reg_dummy, num_regs, const char *); + RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); + + regs_allocated_size = num_regs; + } +} + +#endif /* not MATCH_MAY_ALLOCATE */ + +static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type + compile_stack, + regnum_t regnum)); + +/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. + Returns one of error codes defined in `regex.h', or zero for success. + + Assumes the `allocated' (and perhaps `buffer') and `translate' + fields are set in BUFP on entry. + + If it succeeds, results are put in BUFP (if it returns an error, the + contents of BUFP are undefined): + `buffer' is the compiled pattern; + `syntax' is set to SYNTAX; + `used' is set to the length of the compiled pattern; + `fastmap_accurate' is zero; + `re_nsub' is the number of subexpressions in PATTERN; + `not_bol' and `not_eol' are zero; + + The `fastmap' and `newline_anchor' fields are neither + examined nor set. */ + +/* Return, freeing storage we allocated. */ +#define FREE_STACK_RETURN(value) \ + return (free (compile_stack.stack), value) + +static reg_errcode_t +regex_compile (pattern, size, syntax, bufp) + const char *pattern; + size_t size; + reg_syntax_t syntax; + struct re_pattern_buffer *bufp; +{ + /* We fetch characters from PATTERN here. Even though PATTERN is + `char *' (i.e., signed), we declare these variables as unsigned, so + they can be reliably used as array indices. */ + register unsigned char c, c1; + + /* A random temporary spot in PATTERN. */ + const char *p1; + + /* Points to the end of the buffer, where we should append. */ + register unsigned char *b; + + /* Keeps track of unclosed groups. */ + compile_stack_type compile_stack; + + /* Points to the current (ending) position in the pattern. */ + const char *p = pattern; + const char *pend = pattern + size; + + /* How to translate the characters in the pattern. */ + RE_TRANSLATE_TYPE translate = bufp->translate; + + /* Address of the count-byte of the most recently inserted `exactn' + command. This makes it possible to tell if a new exact-match + character can be added to that command or if the character requires + a new `exactn' command. */ + unsigned char *pending_exact = 0; + + /* Address of start of the most recently finished expression. + This tells, e.g., postfix * where to find the start of its + operand. Reset at the beginning of groups and alternatives. */ + unsigned char *laststart = 0; + + /* Address of beginning of regexp, or inside of last group. */ + unsigned char *begalt; + + /* Place in the uncompiled pattern (i.e., the {) to + which to go back if the interval is invalid. */ + const char *beg_interval; + + /* Address of the place where a forward jump should go to the end of + the containing expression. Each alternative of an `or' -- except the + last -- ends with a forward jump of this sort. */ + unsigned char *fixup_alt_jump = 0; + + /* Counts open-groups as they are encountered. Remembered for the + matching close-group on the compile stack, so the same register + number is put in the stop_memory as the start_memory. */ + regnum_t regnum = 0; + +#ifdef DEBUG + DEBUG_PRINT1 ("\nCompiling pattern: "); + if (debug) + { + unsigned debug_count; + + for (debug_count = 0; debug_count < size; debug_count++) + putchar (pattern[debug_count]); + putchar ('\n'); + } +#endif /* DEBUG */ + + /* Initialize the compile stack. */ + compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); + if (compile_stack.stack == NULL) + return REG_ESPACE; + + compile_stack.size = INIT_COMPILE_STACK_SIZE; + compile_stack.avail = 0; + + /* Initialize the pattern buffer. */ + bufp->syntax = syntax; + bufp->fastmap_accurate = 0; + bufp->not_bol = bufp->not_eol = 0; + + /* Set `used' to zero, so that if we return an error, the pattern + printer (for debugging) will think there's no pattern. We reset it + at the end. */ + bufp->used = 0; + + /* Always count groups, whether or not bufp->no_sub is set. */ + bufp->re_nsub = 0; + +#if !defined emacs && !defined SYNTAX_TABLE + /* Initialize the syntax table. */ + init_syntax_once (); +#endif + + if (bufp->allocated == 0) + { + if (bufp->buffer) + { /* If zero allocated, but buffer is non-null, try to realloc + enough space. This loses if buffer's address is bogus, but + that is the user's responsibility. */ + RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); + } + else + { /* Caller did not allocate a buffer. Do it for them. */ + bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); + } + if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE); + + bufp->allocated = INIT_BUF_SIZE; + } + + begalt = b = bufp->buffer; + + /* Loop through the uncompiled pattern until we're at the end. */ + while (p != pend) + { + PATFETCH (c); + + switch (c) + { + case '^': + { + if ( /* If at start of pattern, it's an operator. */ + p == pattern + 1 + /* If context independent, it's an operator. */ + || syntax & RE_CONTEXT_INDEP_ANCHORS + /* Otherwise, depends on what's come before. */ + || at_begline_loc_p (pattern, p, syntax)) + BUF_PUSH (begline); + else + goto normal_char; + } + break; + + + case '$': + { + if ( /* If at end of pattern, it's an operator. */ + p == pend + /* If context independent, it's an operator. */ + || syntax & RE_CONTEXT_INDEP_ANCHORS + /* Otherwise, depends on what's next. */ + || at_endline_loc_p (p, pend, syntax)) + BUF_PUSH (endline); + else + goto normal_char; + } + break; + + + case '+': + case '?': + if ((syntax & RE_BK_PLUS_QM) + || (syntax & RE_LIMITED_OPS)) + goto normal_char; + handle_plus: + case '*': + /* If there is no previous pattern... */ + if (!laststart) + { + if (syntax & RE_CONTEXT_INVALID_OPS) + FREE_STACK_RETURN (REG_BADRPT); + else if (!(syntax & RE_CONTEXT_INDEP_OPS)) + goto normal_char; + } + + { + /* Are we optimizing this jump? */ + boolean keep_string_p = false; + + /* 1 means zero (many) matches is allowed. */ + char zero_times_ok = 0, many_times_ok = 0; + + /* If there is a sequence of repetition chars, collapse it + down to just one (the right one). We can't combine + interval operators with these because of, e.g., `a{2}*', + which should only match an even number of `a's. */ + + for (;;) + { + zero_times_ok |= c != '+'; + many_times_ok |= c != '?'; + + if (p == pend) + break; + + PATFETCH (c); + + if (c == '*' + || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) + ; + + else if (syntax & RE_BK_PLUS_QM && c == '\\') + { + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + PATFETCH (c1); + if (!(c1 == '+' || c1 == '?')) + { + PATUNFETCH; + PATUNFETCH; + break; + } + + c = c1; + } + else + { + PATUNFETCH; + break; + } + + /* If we get here, we found another repeat character. */ + } + + /* Star, etc. applied to an empty pattern is equivalent + to an empty pattern. */ + if (!laststart) + break; + + /* Now we know whether or not zero matches is allowed + and also whether or not two or more matches is allowed. */ + if (many_times_ok) + { /* More than one repetition is allowed, so put in at the + end a backward relative jump from `b' to before the next + jump we're going to put in below (which jumps from + laststart to after this jump). + + But if we are at the `*' in the exact sequence `.*\n', + insert an unconditional jump backwards to the ., + instead of the beginning of the loop. This way we only + push a failure point once, instead of every time + through the loop. */ + assert (p - 1 > pattern); + + /* Allocate the space for the jump. */ + GET_BUFFER_SPACE (3); + + /* We know we are not at the first character of the pattern, + because laststart was nonzero. And we've already + incremented `p', by the way, to be the character after + the `*'. Do we have to do something analogous here + for null bytes, because of RE_DOT_NOT_NULL? */ + if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') + && zero_times_ok + && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') + && !(syntax & RE_DOT_NEWLINE)) + { /* We have .*\n. */ + STORE_JUMP (jump, b, laststart); + keep_string_p = true; + } + else + /* Anything else. */ + STORE_JUMP (maybe_pop_jump, b, laststart - 3); + + /* We've added more stuff to the buffer. */ + b += 3; + } + + /* On failure, jump from laststart to b + 3, which will be the + end of the buffer after this jump is inserted. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump + : on_failure_jump, + laststart, b + 3); + pending_exact = 0; + b += 3; + + if (!zero_times_ok) + { + /* At least one repetition is required, so insert a + `dummy_failure_jump' before the initial + `on_failure_jump' instruction of the loop. This + effects a skip over that instruction the first time + we hit that loop. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); + b += 3; + } + } + break; + + + case '.': + laststart = b; + BUF_PUSH (anychar); + break; + + + case '[': + { + boolean had_char_class = false; + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + /* Ensure that we have enough space to push a charset: the + opcode, the length count, and the bitset; 34 bytes in all. */ + GET_BUFFER_SPACE (34); + + laststart = b; + + /* We test `*p == '^' twice, instead of using an if + statement, so we only need one BUF_PUSH. */ + BUF_PUSH (*p == '^' ? charset_not : charset); + if (*p == '^') + p++; + + /* Remember the first position in the bracket expression. */ + p1 = p; + + /* Push the number of bytes in the bitmap. */ + BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); + + /* Clear the whole map. */ + bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); + + /* charset_not matches newline according to a syntax bit. */ + if ((re_opcode_t) b[-2] == charset_not + && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) + SET_LIST_BIT ('\n'); + + /* Read in characters and ranges, setting map bits. */ + for (;;) + { + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + PATFETCH (c); + + /* \ might escape characters inside [...] and [^...]. */ + if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') + { + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + PATFETCH (c1); + SET_LIST_BIT (c1); + continue; + } + + /* Could be the end of the bracket expression. If it's + not (i.e., when the bracket expression is `[]' so + far), the ']' character bit gets set way below. */ + if (c == ']' && p != p1 + 1) + break; + + /* Look ahead to see if it's a range when the last thing + was a character class. */ + if (had_char_class && c == '-' && *p != ']') + FREE_STACK_RETURN (REG_ERANGE); + + /* Look ahead to see if it's a range when the last thing + was a character: if this is a hyphen not at the + beginning or the end of a list, then it's the range + operator. */ + if (c == '-' + && !(p - 2 >= pattern && p[-2] == '[') + && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') + && *p != ']') + { + reg_errcode_t ret + = compile_range (&p, pend, translate, syntax, b); + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); + } + + else if (p[0] == '-' && p[1] != ']') + { /* This handles ranges made up of characters only. */ + reg_errcode_t ret; + + /* Move past the `-'. */ + PATFETCH (c1); + + ret = compile_range (&p, pend, translate, syntax, b); + if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); + } + + /* See if we're at the beginning of a possible character + class. */ + + else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') + { /* Leave room for the null. */ + char str[CHAR_CLASS_MAX_LENGTH + 1]; + + PATFETCH (c); + c1 = 0; + + /* If pattern is `[[:'. */ + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (;;) + { + PATFETCH (c); + if ((c == ':' && *p == ']') || p == pend) + break; + if (c1 < CHAR_CLASS_MAX_LENGTH) + str[c1++] = c; + else + /* This is in any case an invalid class name. */ + str[0] = '\0'; + } + str[c1] = '\0'; + + /* If isn't a word bracketed by `[:' and `:]': + undo the ending character, the letters, and leave + the leading `:' and `[' (but set bits for them). */ + if (c == ':' && *p == ']') + { +#if defined _LIBC || WIDE_CHAR_SUPPORT + boolean is_lower = STREQ (str, "lower"); + boolean is_upper = STREQ (str, "upper"); + wctype_t wt; + int ch; + + wt = IS_CHAR_CLASS (str); + if (wt == 0) + FREE_STACK_RETURN (REG_ECTYPE); + + /* Throw away the ] at the end of the character + class. */ + PATFETCH (c); + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (ch = 0; ch < 1 << BYTEWIDTH; ++ch) + { +# ifdef _LIBC + if (__iswctype (__btowc (ch), wt)) + SET_LIST_BIT (ch); +# else + if (iswctype (btowc (ch), wt)) + SET_LIST_BIT (ch); +# endif + + if (translate && (is_upper || is_lower) + && (ISUPPER (ch) || ISLOWER (ch))) + SET_LIST_BIT (ch); + } + + had_char_class = true; +#else + int ch; + boolean is_alnum = STREQ (str, "alnum"); + boolean is_alpha = STREQ (str, "alpha"); + boolean is_blank = STREQ (str, "blank"); + boolean is_cntrl = STREQ (str, "cntrl"); + boolean is_digit = STREQ (str, "digit"); + boolean is_graph = STREQ (str, "graph"); + boolean is_lower = STREQ (str, "lower"); + boolean is_print = STREQ (str, "print"); + boolean is_punct = STREQ (str, "punct"); + boolean is_space = STREQ (str, "space"); + boolean is_upper = STREQ (str, "upper"); + boolean is_xdigit = STREQ (str, "xdigit"); + + if (!IS_CHAR_CLASS (str)) + FREE_STACK_RETURN (REG_ECTYPE); + + /* Throw away the ] at the end of the character + class. */ + PATFETCH (c); + + if (p == pend) FREE_STACK_RETURN (REG_EBRACK); + + for (ch = 0; ch < 1 << BYTEWIDTH; ch++) + { + /* This was split into 3 if's to + avoid an arbitrary limit in some compiler. */ + if ( (is_alnum && ISALNUM (ch)) + || (is_alpha && ISALPHA (ch)) + || (is_blank && ISBLANK (ch)) + || (is_cntrl && ISCNTRL (ch))) + SET_LIST_BIT (ch); + if ( (is_digit && ISDIGIT (ch)) + || (is_graph && ISGRAPH (ch)) + || (is_lower && ISLOWER (ch)) + || (is_print && ISPRINT (ch))) + SET_LIST_BIT (ch); + if ( (is_punct && ISPUNCT (ch)) + || (is_space && ISSPACE (ch)) + || (is_upper && ISUPPER (ch)) + || (is_xdigit && ISXDIGIT (ch))) + SET_LIST_BIT (ch); + if ( translate && (is_upper || is_lower) + && (ISUPPER (ch) || ISLOWER (ch))) + SET_LIST_BIT (ch); + } + had_char_class = true; +#endif /* libc || wctype.h */ + } + else + { + c1++; + while (c1--) + PATUNFETCH; + SET_LIST_BIT ('['); + SET_LIST_BIT (':'); + had_char_class = false; + } + } + else + { + had_char_class = false; + SET_LIST_BIT (c); + } + } + + /* Discard any (non)matching list bytes that are all 0 at the + end of the map. Decrease the map-length byte too. */ + while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + b += b[-1]; + } + break; + + + case '(': + if (syntax & RE_NO_BK_PARENS) + goto handle_open; + else + goto normal_char; + + + case ')': + if (syntax & RE_NO_BK_PARENS) + goto handle_close; + else + goto normal_char; + + + case '\n': + if (syntax & RE_NEWLINE_ALT) + goto handle_alt; + else + goto normal_char; + + + case '|': + if (syntax & RE_NO_BK_VBAR) + goto handle_alt; + else + goto normal_char; + + + case '{': + if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) + goto handle_interval; + else + goto normal_char; + + + case '\\': + if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); + + /* Do not translate the character after the \, so that we can + distinguish, e.g., \B from \b, even if we normally would + translate, e.g., B to b. */ + PATFETCH_RAW (c); + + switch (c) + { + case '(': + if (syntax & RE_NO_BK_PARENS) + goto normal_backslash; + + handle_open: + bufp->re_nsub++; + regnum++; + + if (COMPILE_STACK_FULL) + { + RETALLOC (compile_stack.stack, compile_stack.size << 1, + compile_stack_elt_t); + if (compile_stack.stack == NULL) return REG_ESPACE; + + compile_stack.size <<= 1; + } + + /* These are the values to restore when we hit end of this + group. They are all relative offsets, so that if the + whole pattern moves because of realloc, they will still + be valid. */ + COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; + COMPILE_STACK_TOP.fixup_alt_jump + = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; + COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; + COMPILE_STACK_TOP.regnum = regnum; + + /* We will eventually replace the 0 with the number of + groups inner to this one. But do not push a + start_memory for groups beyond the last one we can + represent in the compiled pattern. */ + if (regnum <= MAX_REGNUM) + { + COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; + BUF_PUSH_3 (start_memory, regnum, 0); + } + + compile_stack.avail++; + + fixup_alt_jump = 0; + laststart = 0; + begalt = b; + /* If we've reached MAX_REGNUM groups, then this open + won't actually generate any code, so we'll have to + clear pending_exact explicitly. */ + pending_exact = 0; + break; + + + case ')': + if (syntax & RE_NO_BK_PARENS) goto normal_backslash; + + if (COMPILE_STACK_EMPTY) + { + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) + goto normal_backslash; + else + FREE_STACK_RETURN (REG_ERPAREN); + } + + handle_close: + if (fixup_alt_jump) + { /* Push a dummy failure point at the end of the + alternative for a possible future + `pop_failure_jump' to pop. See comments at + `push_dummy_failure' in `re_match_2'. */ + BUF_PUSH (push_dummy_failure); + + /* We allocated space for this jump when we assigned + to `fixup_alt_jump', in the `handle_alt' case below. */ + STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); + } + + /* See similar code for backslashed left paren above. */ + if (COMPILE_STACK_EMPTY) + { + if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) + goto normal_char; + else + FREE_STACK_RETURN (REG_ERPAREN); + } + + /* Since we just checked for an empty stack above, this + ``can't happen''. */ + assert (compile_stack.avail != 0); + { + /* We don't just want to restore into `regnum', because + later groups should continue to be numbered higher, + as in `(ab)c(de)' -- the second group is #2. */ + regnum_t this_group_regnum; + + compile_stack.avail--; + begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; + fixup_alt_jump + = COMPILE_STACK_TOP.fixup_alt_jump + ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 + : 0; + laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; + this_group_regnum = COMPILE_STACK_TOP.regnum; + /* If we've reached MAX_REGNUM groups, then this open + won't actually generate any code, so we'll have to + clear pending_exact explicitly. */ + pending_exact = 0; + + /* We're at the end of the group, so now we know how many + groups were inside this one. */ + if (this_group_regnum <= MAX_REGNUM) + { + unsigned char *inner_group_loc + = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; + + *inner_group_loc = regnum - this_group_regnum; + BUF_PUSH_3 (stop_memory, this_group_regnum, + regnum - this_group_regnum); + } + } + break; + + + case '|': /* `\|'. */ + if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) + goto normal_backslash; + handle_alt: + if (syntax & RE_LIMITED_OPS) + goto normal_char; + + /* Insert before the previous alternative a jump which + jumps to this alternative if the former fails. */ + GET_BUFFER_SPACE (3); + INSERT_JUMP (on_failure_jump, begalt, b + 6); + pending_exact = 0; + b += 3; + + /* The alternative before this one has a jump after it + which gets executed if it gets matched. Adjust that + jump so it will jump to this alternative's analogous + jump (put in below, which in turn will jump to the next + (if any) alternative's such jump, etc.). The last such + jump jumps to the correct final destination. A picture: + _____ _____ + | | | | + | v | v + a | b | c + + If we are at `b', then fixup_alt_jump right now points to a + three-byte space after `a'. We'll put in the jump, set + fixup_alt_jump to right after `b', and leave behind three + bytes which we'll fill in when we get to after `c'. */ + + if (fixup_alt_jump) + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); + + /* Mark and leave space for a jump after this alternative, + to be filled in later either by next alternative or + when know we're at the end of a series of alternatives. */ + fixup_alt_jump = b; + GET_BUFFER_SPACE (3); + b += 3; + + laststart = 0; + begalt = b; + break; + + + case '{': + /* If \{ is a literal. */ + if (!(syntax & RE_INTERVALS) + /* If we're at `\{' and it's not the open-interval + operator. */ + || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) + || (p - 2 == pattern && p == pend)) + goto normal_backslash; + + handle_interval: + { + /* If got here, then the syntax allows intervals. */ + + /* At least (most) this many matches must be made. */ + int lower_bound = -1, upper_bound = -1; + + beg_interval = p - 1; + + if (p == pend) + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_EBRACE); + } + + GET_UNSIGNED_NUMBER (lower_bound); + + if (c == ',') + { + GET_UNSIGNED_NUMBER (upper_bound); + if (upper_bound < 0) upper_bound = RE_DUP_MAX; + } + else + /* Interval such as `{1}' => match exactly once. */ + upper_bound = lower_bound; + + if (lower_bound < 0 || upper_bound > RE_DUP_MAX + || lower_bound > upper_bound) + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_BADBR); + } + + if (!(syntax & RE_NO_BK_BRACES)) + { + if (c != '\\') FREE_STACK_RETURN (REG_EBRACE); + + PATFETCH (c); + } + + if (c != '}') + { + if (syntax & RE_NO_BK_BRACES) + goto unfetch_interval; + else + FREE_STACK_RETURN (REG_BADBR); + } + + /* We just parsed a valid interval. */ + + /* If it's invalid to have no preceding re. */ + if (!laststart) + { + if (syntax & RE_CONTEXT_INVALID_OPS) + FREE_STACK_RETURN (REG_BADRPT); + else if (syntax & RE_CONTEXT_INDEP_OPS) + laststart = b; + else + goto unfetch_interval; + } + + /* If the upper bound is zero, don't want to succeed at + all; jump from `laststart' to `b + 3', which will be + the end of the buffer after we insert the jump. */ + if (upper_bound == 0) + { + GET_BUFFER_SPACE (3); + INSERT_JUMP (jump, laststart, b + 3); + b += 3; + } + + /* Otherwise, we have a nontrivial interval. When + we're all done, the pattern will look like: + set_number_at + set_number_at + succeed_n + + jump_n + (The upper bound and `jump_n' are omitted if + `upper_bound' is 1, though.) */ + else + { /* If the upper bound is > 1, we need to insert + more at the end of the loop. */ + unsigned nbytes = 10 + (upper_bound > 1) * 10; + + GET_BUFFER_SPACE (nbytes); + + /* Initialize lower bound of the `succeed_n', even + though it will be set during matching by its + attendant `set_number_at' (inserted next), + because `re_compile_fastmap' needs to know. + Jump to the `jump_n' we might insert below. */ + INSERT_JUMP2 (succeed_n, laststart, + b + 5 + (upper_bound > 1) * 5, + lower_bound); + b += 5; + + /* Code to initialize the lower bound. Insert + before the `succeed_n'. The `5' is the last two + bytes of this `set_number_at', plus 3 bytes of + the following `succeed_n'. */ + insert_op2 (set_number_at, laststart, 5, lower_bound, b); + b += 5; + + if (upper_bound > 1) + { /* More than one repetition is allowed, so + append a backward jump to the `succeed_n' + that starts this interval. + + When we've reached this during matching, + we'll have matched the interval once, so + jump back only `upper_bound - 1' times. */ + STORE_JUMP2 (jump_n, b, laststart + 5, + upper_bound - 1); + b += 5; + + /* The location we want to set is the second + parameter of the `jump_n'; that is `b-2' as + an absolute address. `laststart' will be + the `set_number_at' we're about to insert; + `laststart+3' the number to set, the source + for the relative address. But we are + inserting into the middle of the pattern -- + so everything is getting moved up by 5. + Conclusion: (b - 2) - (laststart + 3) + 5, + i.e., b - laststart. + + We insert this at the beginning of the loop + so that if we fail during matching, we'll + reinitialize the bounds. */ + insert_op2 (set_number_at, laststart, b - laststart, + upper_bound - 1, b); + b += 5; + } + } + pending_exact = 0; + beg_interval = NULL; + } + break; + + unfetch_interval: + /* If an invalid interval, match the characters as literals. */ + assert (beg_interval); + p = beg_interval; + beg_interval = NULL; + + /* normal_char and normal_backslash need `c'. */ + PATFETCH (c); + + if (!(syntax & RE_NO_BK_BRACES)) + { + if (p > pattern && p[-1] == '\\') + goto normal_backslash; + } + goto normal_char; + +#ifdef emacs + /* There is no way to specify the before_dot and after_dot + operators. rms says this is ok. --karl */ + case '=': + BUF_PUSH (at_dot); + break; + + case 's': + laststart = b; + PATFETCH (c); + BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); + break; + + case 'S': + laststart = b; + PATFETCH (c); + BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); + break; +#endif /* emacs */ + + + case 'w': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + laststart = b; + BUF_PUSH (wordchar); + break; + + + case 'W': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + laststart = b; + BUF_PUSH (notwordchar); + break; + + + case '<': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordbeg); + break; + + case '>': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordend); + break; + + case 'b': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (wordbound); + break; + + case 'B': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (notwordbound); + break; + + case '`': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (begbuf); + break; + + case '\'': + if (syntax & RE_NO_GNU_OPS) + goto normal_char; + BUF_PUSH (endbuf); + break; + + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + if (syntax & RE_NO_BK_REFS) + goto normal_char; + + c1 = c - '0'; + + if (c1 > regnum) + FREE_STACK_RETURN (REG_ESUBREG); + + /* Can't back reference to a subexpression if inside of it. */ + if (group_in_compile_stack (compile_stack, (regnum_t) c1)) + goto normal_char; + + laststart = b; + BUF_PUSH_2 (duplicate, c1); + break; + + + case '+': + case '?': + if (syntax & RE_BK_PLUS_QM) + goto handle_plus; + else + goto normal_backslash; + + default: + normal_backslash: + /* You might think it would be useful for \ to mean + not to translate; but if we don't translate it + it will never match anything. */ + c = TRANSLATE (c); + goto normal_char; + } + break; + + + default: + /* Expects the character in `c'. */ + normal_char: + /* If no exactn currently being built. */ + if (!pending_exact + + /* If last exactn not at current position. */ + || pending_exact + *pending_exact + 1 != b + + /* We have only one byte following the exactn for the count. */ + || *pending_exact == (1 << BYTEWIDTH) - 1 + + /* If followed by a repetition operator. */ + || *p == '*' || *p == '^' + || ((syntax & RE_BK_PLUS_QM) + ? *p == '\\' && (p[1] == '+' || p[1] == '?') + : (*p == '+' || *p == '?')) + || ((syntax & RE_INTERVALS) + && ((syntax & RE_NO_BK_BRACES) + ? *p == '{' + : (p[0] == '\\' && p[1] == '{')))) + { + /* Start building a new exactn. */ + + laststart = b; + + BUF_PUSH_2 (exactn, 0); + pending_exact = b - 1; + } + + BUF_PUSH (c); + (*pending_exact)++; + break; + } /* switch (c) */ + } /* while p != pend */ + + + /* Through the pattern now. */ + + if (fixup_alt_jump) + STORE_JUMP (jump_past_alt, fixup_alt_jump, b); + + if (!COMPILE_STACK_EMPTY) + FREE_STACK_RETURN (REG_EPAREN); + + /* If we don't want backtracking, force success + the first time we reach the end of the compiled pattern. */ + if (syntax & RE_NO_POSIX_BACKTRACKING) + BUF_PUSH (succeed); + + free (compile_stack.stack); + + /* We have succeeded; set the length of the buffer. */ + bufp->used = b - bufp->buffer; + +#ifdef DEBUG + if (debug) + { + DEBUG_PRINT1 ("\nCompiled pattern: \n"); + print_compiled_pattern (bufp); + } +#endif /* DEBUG */ + +#ifndef MATCH_MAY_ALLOCATE + /* Initialize the failure stack to the largest possible stack. This + isn't necessary unless we're trying to avoid calling alloca in + the search and match routines. */ + { + int num_regs = bufp->re_nsub + 1; + + /* Since DOUBLE_FAIL_STACK refuses to double only if the current size + is strictly greater than re_max_failures, the largest possible stack + is 2 * re_max_failures failure points. */ + if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS)) + { + fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS); + +# ifdef emacs + if (! fail_stack.stack) + fail_stack.stack + = (fail_stack_elt_t *) xmalloc (fail_stack.size + * sizeof (fail_stack_elt_t)); + else + fail_stack.stack + = (fail_stack_elt_t *) xrealloc (fail_stack.stack, + (fail_stack.size + * sizeof (fail_stack_elt_t))); +# else /* not emacs */ + if (! fail_stack.stack) + fail_stack.stack + = (fail_stack_elt_t *) malloc (fail_stack.size + * sizeof (fail_stack_elt_t)); + else + fail_stack.stack + = (fail_stack_elt_t *) realloc (fail_stack.stack, + (fail_stack.size + * sizeof (fail_stack_elt_t))); +# endif /* not emacs */ + } + + regex_grow_registers (num_regs); + } +#endif /* not MATCH_MAY_ALLOCATE */ + + return REG_NOERROR; +} /* regex_compile */ + +/* Subroutines for `regex_compile'. */ + +/* Store OP at LOC followed by two-byte integer parameter ARG. */ + +static void +store_op1 (op, loc, arg) + re_opcode_t op; + unsigned char *loc; + int arg; +{ + *loc = (unsigned char) op; + STORE_NUMBER (loc + 1, arg); +} + + +/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ + +static void +store_op2 (op, loc, arg1, arg2) + re_opcode_t op; + unsigned char *loc; + int arg1, arg2; +{ + *loc = (unsigned char) op; + STORE_NUMBER (loc + 1, arg1); + STORE_NUMBER (loc + 3, arg2); +} + + +/* Copy the bytes from LOC to END to open up three bytes of space at LOC + for OP followed by two-byte integer parameter ARG. */ + +static void +insert_op1 (op, loc, arg, end) + re_opcode_t op; + unsigned char *loc; + int arg; + unsigned char *end; +{ + register unsigned char *pfrom = end; + register unsigned char *pto = end + 3; + + while (pfrom != loc) + *--pto = *--pfrom; + + store_op1 (op, loc, arg); +} + + +/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ + +static void +insert_op2 (op, loc, arg1, arg2, end) + re_opcode_t op; + unsigned char *loc; + int arg1, arg2; + unsigned char *end; +{ + register unsigned char *pfrom = end; + register unsigned char *pto = end + 5; + + while (pfrom != loc) + *--pto = *--pfrom; + + store_op2 (op, loc, arg1, arg2); +} + + +/* P points to just after a ^ in PATTERN. Return true if that ^ comes + after an alternative or a begin-subexpression. We assume there is at + least one character before the ^. */ + +static boolean +at_begline_loc_p (pattern, p, syntax) + const char *pattern, *p; + reg_syntax_t syntax; +{ + const char *prev = p - 2; + boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\'; + + return + /* After a subexpression? */ + (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) + /* After an alternative? */ + || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); +} + + +/* The dual of at_begline_loc_p. This one is for $. We assume there is + at least one character after the $, i.e., `P < PEND'. */ + +static boolean +at_endline_loc_p (p, pend, syntax) + const char *p, *pend; + reg_syntax_t syntax; +{ + const char *next = p; + boolean next_backslash = *next == '\\'; + const char *next_next = p + 1 < pend ? p + 1 : 0; + + return + /* Before a subexpression? */ + (syntax & RE_NO_BK_PARENS ? *next == ')' + : next_backslash && next_next && *next_next == ')') + /* Before an alternative? */ + || (syntax & RE_NO_BK_VBAR ? *next == '|' + : next_backslash && next_next && *next_next == '|'); +} + + +/* Returns true if REGNUM is in one of COMPILE_STACK's elements and + false if it's not. */ + +static boolean +group_in_compile_stack (compile_stack, regnum) + compile_stack_type compile_stack; + regnum_t regnum; +{ + int this_element; + + for (this_element = compile_stack.avail - 1; + this_element >= 0; + this_element--) + if (compile_stack.stack[this_element].regnum == regnum) + return true; + + return false; +} + + +/* Read the ending character of a range (in a bracket expression) from the + uncompiled pattern *P_PTR (which ends at PEND). We assume the + starting character is in `P[-2]'. (`P[-1]' is the character `-'.) + Then we set the translation of all bits between the starting and + ending characters (inclusive) in the compiled pattern B. + + Return an error code. + + We use these short variable names so we can use the same macros as + `regex_compile' itself. */ + +static reg_errcode_t +compile_range (p_ptr, pend, translate, syntax, b) + const char **p_ptr, *pend; + RE_TRANSLATE_TYPE translate; + reg_syntax_t syntax; + unsigned char *b; +{ + unsigned this_char; + + const char *p = *p_ptr; + unsigned int range_start, range_end; + + if (p == pend) + return REG_ERANGE; + + /* Even though the pattern is a signed `char *', we need to fetch + with unsigned char *'s; if the high bit of the pattern character + is set, the range endpoints will be negative if we fetch using a + signed char *. + + We also want to fetch the endpoints without translating them; the + appropriate translation is done in the bit-setting loop below. */ + /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */ + range_start = ((const unsigned char *) p)[-2]; + range_end = ((const unsigned char *) p)[0]; + + /* Have to increment the pointer into the pattern string, so the + caller isn't still at the ending character. */ + (*p_ptr)++; + + /* If the start is after the end, the range is empty. */ + if (range_start > range_end) + return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; + + /* Here we see why `this_char' has to be larger than an `unsigned + char' -- the range is inclusive, so if `range_end' == 0xff + (assuming 8-bit characters), we would otherwise go into an infinite + loop, since all characters <= 0xff. */ + for (this_char = range_start; this_char <= range_end; this_char++) + { + SET_LIST_BIT (TRANSLATE (this_char)); + } + + return REG_NOERROR; +} + +/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in + BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible + characters can start a string that matches the pattern. This fastmap + is used by re_search to skip quickly over impossible starting points. + + The caller must supply the address of a (1 << BYTEWIDTH)-byte data + area as BUFP->fastmap. + + We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in + the pattern buffer. + + Returns 0 if we succeed, -2 if an internal error. */ + +int +re_compile_fastmap (bufp) + struct re_pattern_buffer *bufp; +{ + int j, k; +#ifdef MATCH_MAY_ALLOCATE + fail_stack_type fail_stack; +#endif +#ifndef REGEX_MALLOC + char *destination; +#endif + + register char *fastmap = bufp->fastmap; + unsigned char *pattern = bufp->buffer; + unsigned char *p = pattern; + register unsigned char *pend = pattern + bufp->used; + +#ifdef REL_ALLOC + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; +#endif + + /* Assume that each path through the pattern can be null until + proven otherwise. We set this false at the bottom of switch + statement, to which we get only if a particular path doesn't + match the empty string. */ + boolean path_can_be_null = true; + + /* We aren't doing a `succeed_n' to begin with. */ + boolean succeed_n_p = false; + + assert (fastmap != NULL && p != NULL); + + INIT_FAIL_STACK (); + bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ + bufp->fastmap_accurate = 1; /* It will be when we're done. */ + bufp->can_be_null = 0; + + while (1) + { + if (p == pend || *p == succeed) + { + /* We have reached the (effective) end of pattern. */ + if (!FAIL_STACK_EMPTY ()) + { + bufp->can_be_null |= path_can_be_null; + + /* Reset for next path. */ + path_can_be_null = true; + + p = fail_stack.stack[--fail_stack.avail].pointer; + + continue; + } + else + break; + } + + /* We should never be about to go beyond the end of the pattern. */ + assert (p < pend); + + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) + { + + /* I guess the idea here is to simply not bother with a fastmap + if a backreference is used, since it's too hard to figure out + the fastmap for the corresponding group. Setting + `can_be_null' stops `re_search_2' from using the fastmap, so + that is all we do. */ + case duplicate: + bufp->can_be_null = 1; + goto done; + + + /* Following are the cases which match a character. These end + with `break'. */ + + case exactn: + fastmap[p[1]] = 1; + break; + + + case charset: + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) + fastmap[j] = 1; + break; + + + case charset_not: + /* Chars beyond end of map must be allowed. */ + for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) + fastmap[j] = 1; + break; + + + case wordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) == Sword) + fastmap[j] = 1; + break; + + + case notwordchar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) != Sword) + fastmap[j] = 1; + break; + + + case anychar: + { + int fastmap_newline = fastmap['\n']; + + /* `.' matches anything ... */ + for (j = 0; j < (1 << BYTEWIDTH); j++) + fastmap[j] = 1; + + /* ... except perhaps newline. */ + if (!(bufp->syntax & RE_DOT_NEWLINE)) + fastmap['\n'] = fastmap_newline; + + /* Return if we have already set `can_be_null'; if we have, + then the fastmap is irrelevant. Something's wrong here. */ + else if (bufp->can_be_null) + goto done; + + /* Otherwise, have to check alternative paths. */ + break; + } + +#ifdef emacs + case syntaxspec: + k = *p++; + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) == (enum syntaxcode) k) + fastmap[j] = 1; + break; + + + case notsyntaxspec: + k = *p++; + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (SYNTAX (j) != (enum syntaxcode) k) + fastmap[j] = 1; + break; + + + /* All cases after this match the empty string. These end with + `continue'. */ + + + case before_dot: + case at_dot: + case after_dot: + continue; +#endif /* emacs */ + + + case no_op: + case begline: + case endline: + case begbuf: + case endbuf: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case push_dummy_failure: + continue; + + + case jump_n: + case pop_failure_jump: + case maybe_pop_jump: + case jump: + case jump_past_alt: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (j, p); + p += j; + if (j > 0) + continue; + + /* Jump backward implies we just went through the body of a + loop and matched nothing. Opcode jumped to should be + `on_failure_jump' or `succeed_n'. Just treat it like an + ordinary jump. For a * loop, it has pushed its failure + point already; if so, discard that as redundant. */ + if ((re_opcode_t) *p != on_failure_jump + && (re_opcode_t) *p != succeed_n) + continue; + + p++; + EXTRACT_NUMBER_AND_INCR (j, p); + p += j; + + /* If what's on the stack is where we are now, pop it. */ + if (!FAIL_STACK_EMPTY () + && fail_stack.stack[fail_stack.avail - 1].pointer == p) + fail_stack.avail--; + + continue; + + + case on_failure_jump: + case on_failure_keep_string_jump: + handle_on_failure_jump: + EXTRACT_NUMBER_AND_INCR (j, p); + + /* For some patterns, e.g., `(a?)?', `p+j' here points to the + end of the pattern. We don't want to push such a point, + since when we restore it above, entering the switch will + increment `p' past the end of the pattern. We don't need + to push such a point since we obviously won't find any more + fastmap entries beyond `pend'. Such a pattern can match + the null string, though. */ + if (p + j < pend) + { + if (!PUSH_PATTERN_OP (p + j, fail_stack)) + { + RESET_FAIL_STACK (); + return -2; + } + } + else + bufp->can_be_null = 1; + + if (succeed_n_p) + { + EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ + succeed_n_p = false; + } + + continue; + + + case succeed_n: + /* Get to the number of times to succeed. */ + p += 2; + + /* Increment p past the n for when k != 0. */ + EXTRACT_NUMBER_AND_INCR (k, p); + if (k == 0) + { + p -= 4; + succeed_n_p = true; /* Spaghetti code alert. */ + goto handle_on_failure_jump; + } + continue; + + + case set_number_at: + p += 4; + continue; + + + case start_memory: + case stop_memory: + p += 2; + continue; + + + default: + abort (); /* We have listed all the cases. */ + } /* switch *p++ */ + + /* Getting here means we have found the possible starting + characters for one path of the pattern -- and that the empty + string does not match. We need not follow this path further. + Instead, look at the next alternative (remembered on the + stack), or quit if no more. The test at the top of the loop + does these things. */ + path_can_be_null = false; + p = pend; + } /* while p */ + + /* Set `can_be_null' for the last path (also the first path, if the + pattern is empty). */ + bufp->can_be_null |= path_can_be_null; + + done: + RESET_FAIL_STACK (); + return 0; +} /* re_compile_fastmap */ +#ifdef _LIBC +weak_alias (__re_compile_fastmap, re_compile_fastmap) +#endif + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use + this memory for recording register information. STARTS and ENDS + must be allocated using the malloc library routine, and must each + be at least NUM_REGS * sizeof (regoff_t) bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ + +void +re_set_registers (bufp, regs, num_regs, starts, ends) + struct re_pattern_buffer *bufp; + struct re_registers *regs; + unsigned num_regs; + regoff_t *starts, *ends; +{ + if (num_regs) + { + bufp->regs_allocated = REGS_REALLOCATE; + regs->num_regs = num_regs; + regs->start = starts; + regs->end = ends; + } + else + { + bufp->regs_allocated = REGS_UNALLOCATED; + regs->num_regs = 0; + regs->start = regs->end = (regoff_t *) 0; + } +} +#ifdef _LIBC +weak_alias (__re_set_registers, re_set_registers) +#endif + +/* Searching routines. */ + +/* Like re_search_2, below, but only one string is specified, and + doesn't let you say where to stop matching. */ + +int +re_search (bufp, string, size, startpos, range, regs) + struct re_pattern_buffer *bufp; + const char *string; + int size, startpos, range; + struct re_registers *regs; +{ + return re_search_2 (bufp, NULL, 0, string, size, startpos, range, + regs, size); +} +#ifdef _LIBC +weak_alias (__re_search, re_search) +#endif + + +/* Using the compiled pattern in BUFP->buffer, first tries to match the + virtual concatenation of STRING1 and STRING2, starting first at index + STARTPOS, then at STARTPOS + 1, and so on. + + STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. + + RANGE is how far to scan while trying to match. RANGE = 0 means try + only at STARTPOS; in general, the last start tried is STARTPOS + + RANGE. + + In REGS, return the indices of the virtual concatenation of STRING1 + and STRING2 that matched the entire BUFP->buffer and its contained + subexpressions. + + Do not consider matching one past the index STOP in the virtual + concatenation of STRING1 and STRING2. + + We return either the position in the strings at which the match was + found, -1 if no match, or -2 if error (such as failure + stack overflow). */ + +int +re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int startpos; + int range; + struct re_registers *regs; + int stop; +{ + int val; + register char *fastmap = bufp->fastmap; + register RE_TRANSLATE_TYPE translate = bufp->translate; + int total_size = size1 + size2; + int endpos = startpos + range; + + /* Check for out-of-range STARTPOS. */ + if (startpos < 0 || startpos > total_size) + return -1; + + /* Fix up RANGE if it might eventually take us outside + the virtual concatenation of STRING1 and STRING2. + Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ + if (endpos < 0) + range = 0 - startpos; + else if (endpos > total_size) + range = total_size - startpos; + + /* If the search isn't to be a backwards one, don't waste time in a + search for a pattern that must be anchored. */ + if (bufp->used > 0 && range > 0 + && ((re_opcode_t) bufp->buffer[0] == begbuf + /* `begline' is like `begbuf' if it cannot match at newlines. */ + || ((re_opcode_t) bufp->buffer[0] == begline + && !bufp->newline_anchor))) + { + if (startpos > 0) + return -1; + else + range = 1; + } + +#ifdef emacs + /* In a forward search for something that starts with \=. + don't keep searching past point. */ + if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) + { + range = PT - startpos; + if (range <= 0) + return -1; + } +#endif /* emacs */ + + /* Update the fastmap now if not correct already. */ + if (fastmap && !bufp->fastmap_accurate) + if (re_compile_fastmap (bufp) == -2) + return -2; + + /* Loop through the string, looking for a place to start matching. */ + for (;;) + { + /* If a fastmap is supplied, skip quickly over characters that + cannot be the start of a match. If the pattern can match the + null string, however, we don't need to skip characters; we want + the first null string. */ + if (fastmap && startpos < total_size && !bufp->can_be_null) + { + if (range > 0) /* Searching forwards. */ + { + register const char *d; + register int lim = 0; + int irange = range; + + if (startpos < size1 && startpos + range >= size1) + lim = range - (size1 - startpos); + + d = (startpos >= size1 ? string2 - size1 : string1) + startpos; + + /* Written out as an if-else to avoid testing `translate' + inside the loop. */ + if (translate) + while (range > lim + && !fastmap[(unsigned char) + translate[(unsigned char) *d++]]) + range--; + else + while (range > lim && !fastmap[(unsigned char) *d++]) + range--; + + startpos += irange - range; + } + else /* Searching backwards. */ + { + register char c = (size1 == 0 || startpos >= size1 + ? string2[startpos - size1] + : string1[startpos]); + + if (!fastmap[(unsigned char) TRANSLATE (c)]) + goto advance; + } + } + + /* If can't match the null string, and that's all we have left, fail. */ + if (range >= 0 && startpos == total_size && fastmap + && !bufp->can_be_null) + return -1; + + val = re_match_2_internal (bufp, string1, size1, string2, size2, + startpos, regs, stop); +#ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +#endif + + if (val >= 0) + return startpos; + + if (val == -2) + return -2; + + advance: + if (!range) + break; + else if (range > 0) + { + range--; + startpos++; + } + else + { + range++; + startpos--; + } + } + return -1; +} /* re_search_2 */ +#ifdef _LIBC +weak_alias (__re_search_2, re_search_2) +#endif + +/* This converts PTR, a pointer into one of the search strings `string1' + and `string2' into an offset from the beginning of that string. */ +#define POINTER_TO_OFFSET(ptr) \ + (FIRST_STRING_P (ptr) \ + ? ((regoff_t) ((ptr) - string1)) \ + : ((regoff_t) ((ptr) - string2 + size1))) + +/* Macros for dealing with the split strings in re_match_2. */ + +#define MATCHING_IN_FIRST_STRING (dend == end_match_1) + +/* Call before fetching a character with *d. This switches over to + string2 if necessary. */ +#define PREFETCH() \ + while (d == dend) \ + { \ + /* End of string2 => fail. */ \ + if (dend == end_match_2) \ + goto fail; \ + /* End of string1 => advance to string2. */ \ + d = string2; \ + dend = end_match_2; \ + } + + +/* Test if at very beginning or at very end of the virtual concatenation + of `string1' and `string2'. If only one string, it's `string2'. */ +#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) +#define AT_STRINGS_END(d) ((d) == end2) + + +/* Test if D points to a character which is word-constituent. We have + two special cases to check for: if past the end of string1, look at + the first character in string2; and if before the beginning of + string2, look at the last character in string1. */ +#define WORDCHAR_P(d) \ + (SYNTAX ((d) == end1 ? *string2 \ + : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ + == Sword) + +/* Disabled due to a compiler bug -- see comment at case wordbound */ +#if 0 +/* Test if the character before D and the one at D differ with respect + to being word-constituent. */ +#define AT_WORD_BOUNDARY(d) \ + (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ + || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) +#endif + +/* Free everything we malloc. */ +#ifdef MATCH_MAY_ALLOCATE +# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL +# define FREE_VARIABLES() \ + do { \ + REGEX_FREE_STACK (fail_stack.stack); \ + FREE_VAR (regstart); \ + FREE_VAR (regend); \ + FREE_VAR (old_regstart); \ + FREE_VAR (old_regend); \ + FREE_VAR (best_regstart); \ + FREE_VAR (best_regend); \ + FREE_VAR (reg_info); \ + FREE_VAR (reg_dummy); \ + FREE_VAR (reg_info_dummy); \ + } while (0) +#else +# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ +#endif /* not MATCH_MAY_ALLOCATE */ + +/* These values must meet several constraints. They must not be valid + register values; since we have a limit of 255 registers (because + we use only one byte in the pattern for the register number), we can + use numbers larger than 255. They must differ by 1, because of + NUM_FAILURE_ITEMS above. And the value for the lowest register must + be larger than the value for the highest register, so we do not try + to actually save any registers when none are active. */ +#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) +#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) + +/* Matching routines. */ + +#ifndef emacs /* Emacs never uses this. */ +/* re_match is like re_match_2 except it takes only a single string. */ + +int +re_match (bufp, string, size, pos, regs) + struct re_pattern_buffer *bufp; + const char *string; + int size, pos; + struct re_registers *regs; +{ + int result = re_match_2_internal (bufp, NULL, 0, string, size, + pos, regs, size); +# ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +# endif + return result; +} +# ifdef _LIBC +weak_alias (__re_match, re_match) +# endif +#endif /* not emacs */ + +static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p, + unsigned char *end, + register_info_type *reg_info)); +static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p, + unsigned char *end, + register_info_type *reg_info)); +static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p, + unsigned char *end, + register_info_type *reg_info)); +static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2, + int len, char *translate)); + +/* re_match_2 matches the compiled pattern in BUFP against the + the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 + and SIZE2, respectively). We start matching at POS, and stop + matching at STOP. + + If REGS is non-null and the `no_sub' field of BUFP is nonzero, we + store offsets for the substring each group matched in REGS. See the + documentation for exactly how many groups we fill. + + We return -1 if no match, -2 if an internal error (such as the + failure stack overflowing). Otherwise, we return the length of the + matched substring. */ + +int +re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int pos; + struct re_registers *regs; + int stop; +{ + int result = re_match_2_internal (bufp, string1, size1, string2, size2, + pos, regs, stop); +#ifndef REGEX_MALLOC +# ifdef C_ALLOCA + alloca (0); +# endif +#endif + return result; +} +#ifdef _LIBC +weak_alias (__re_match_2, re_match_2) +#endif + +/* This is a separate function so that we can force an alloca cleanup + afterwards. */ +static int +re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) + struct re_pattern_buffer *bufp; + const char *string1, *string2; + int size1, size2; + int pos; + struct re_registers *regs; + int stop; +{ + /* General temporaries. */ + int mcnt; + unsigned char *p1; + + /* Just past the end of the corresponding string. */ + const char *end1, *end2; + + /* Pointers into string1 and string2, just past the last characters in + each to consider matching. */ + const char *end_match_1, *end_match_2; + + /* Where we are in the data, and the end of the current string. */ + const char *d, *dend; + + /* Where we are in the pattern, and the end of the pattern. */ + unsigned char *p = bufp->buffer; + register unsigned char *pend = p + bufp->used; + + /* Mark the opcode just after a start_memory, so we can test for an + empty subpattern when we get to the stop_memory. */ + unsigned char *just_past_start_mem = 0; + + /* We use this to map every character in the string. */ + RE_TRANSLATE_TYPE translate = bufp->translate; + + /* Failure point stack. Each place that can handle a failure further + down the line pushes a failure point on this stack. It consists of + restart, regend, and reg_info for all registers corresponding to + the subexpressions we're currently inside, plus the number of such + registers, and, finally, two char *'s. The first char * is where + to resume scanning the pattern; the second one is where to resume + scanning the strings. If the latter is zero, the failure point is + a ``dummy''; if a failure happens and the failure point is a dummy, + it gets discarded and the next next one is tried. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ + fail_stack_type fail_stack; +#endif +#ifdef DEBUG + static unsigned failure_id = 0; + unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; +#endif + +#ifdef REL_ALLOC + /* This holds the pointer to the failure stack, when + it is allocated relocatably. */ + fail_stack_elt_t *failure_stack_ptr; +#endif + + /* We fill all the registers internally, independent of what we + return, for use in backreferences. The number here includes + an element for register zero. */ + size_t num_regs = bufp->re_nsub + 1; + + /* The currently active registers. */ + active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG; + active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG; + + /* Information on the contents of registers. These are pointers into + the input strings; they record just what was matched (on this + attempt) by a subexpression part of the pattern, that is, the + regnum-th regstart pointer points to where in the pattern we began + matching and the regnum-th regend points to right after where we + stopped matching the regnum-th subexpression. (The zeroth register + keeps track of what the whole pattern matches.) */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **regstart, **regend; +#endif + + /* If a group that's operated upon by a repetition operator fails to + match anything, then the register for its start will need to be + restored because it will have been set to wherever in the string we + are when we last see its open-group operator. Similarly for a + register's end. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **old_regstart, **old_regend; +#endif + + /* The is_active field of reg_info helps us keep track of which (possibly + nested) subexpressions we are currently in. The matched_something + field of reg_info[reg_num] helps us tell whether or not we have + matched any of the pattern so far this time through the reg_num-th + subexpression. These two fields get reset each time through any + loop their register is in. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ + register_info_type *reg_info; +#endif + + /* The following record the register info as found in the above + variables when we find a match better than any we've seen before. + This happens as we backtrack through the failure points, which in + turn happens only if we have not yet matched the entire string. */ + unsigned best_regs_set = false; +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **best_regstart, **best_regend; +#endif + + /* Logically, this is `best_regend[0]'. But we don't want to have to + allocate space for that if we're not allocating space for anything + else (see below). Also, we never need info about register 0 for + any of the other register vectors, and it seems rather a kludge to + treat `best_regend' differently than the rest. So we keep track of + the end of the best match so far in a separate variable. We + initialize this to NULL so that when we backtrack the first time + and need to test it, it's not garbage. */ + const char *match_end = NULL; + + /* This helps SET_REGS_MATCHED avoid doing redundant work. */ + int set_regs_matched_done = 0; + + /* Used when we pop values we don't care about. */ +#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ + const char **reg_dummy; + register_info_type *reg_info_dummy; +#endif + +#ifdef DEBUG + /* Counts the total number of registers pushed. */ + unsigned num_regs_pushed = 0; +#endif + + DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); + + INIT_FAIL_STACK (); + +#ifdef MATCH_MAY_ALLOCATE + /* Do not bother to initialize all the register variables if there are + no groups in the pattern, as it takes a fair amount of time. If + there are groups, we include space for register 0 (the whole + pattern), even though we never use it, since it simplifies the + array indexing. We should fix this. */ + if (bufp->re_nsub) + { + regstart = REGEX_TALLOC (num_regs, const char *); + regend = REGEX_TALLOC (num_regs, const char *); + old_regstart = REGEX_TALLOC (num_regs, const char *); + old_regend = REGEX_TALLOC (num_regs, const char *); + best_regstart = REGEX_TALLOC (num_regs, const char *); + best_regend = REGEX_TALLOC (num_regs, const char *); + reg_info = REGEX_TALLOC (num_regs, register_info_type); + reg_dummy = REGEX_TALLOC (num_regs, const char *); + reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); + + if (!(regstart && regend && old_regstart && old_regend && reg_info + && best_regstart && best_regend && reg_dummy && reg_info_dummy)) + { + FREE_VARIABLES (); + return -2; + } + } + else + { + /* We must initialize all our variables to NULL, so that + `FREE_VARIABLES' doesn't try to free them. */ + regstart = regend = old_regstart = old_regend = best_regstart + = best_regend = reg_dummy = NULL; + reg_info = reg_info_dummy = (register_info_type *) NULL; + } +#endif /* MATCH_MAY_ALLOCATE */ + + /* The starting position is bogus. */ + if (pos < 0 || pos > size1 + size2) + { + FREE_VARIABLES (); + return -1; + } + + /* Initialize subexpression text positions to -1 to mark ones that no + start_memory/stop_memory has been seen for. Also initialize the + register information struct. */ + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + regstart[mcnt] = regend[mcnt] + = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; + + REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; + IS_ACTIVE (reg_info[mcnt]) = 0; + MATCHED_SOMETHING (reg_info[mcnt]) = 0; + EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; + } + + /* We move `string1' into `string2' if the latter's empty -- but not if + `string1' is null. */ + if (size2 == 0 && string1 != NULL) + { + string2 = string1; + size2 = size1; + string1 = 0; + size1 = 0; + } + end1 = string1 + size1; + end2 = string2 + size2; + + /* Compute where to stop matching, within the two strings. */ + if (stop <= size1) + { + end_match_1 = string1 + stop; + end_match_2 = string2; + } + else + { + end_match_1 = end1; + end_match_2 = string2 + stop - size1; + } + + /* `p' scans through the pattern as `d' scans through the data. + `dend' is the end of the input string that `d' points within. `d' + is advanced into the following input string whenever necessary, but + this happens before fetching; therefore, at the beginning of the + loop, `d' can be pointing at the end of a string, but it cannot + equal `string2'. */ + if (size1 > 0 && pos <= size1) + { + d = string1 + pos; + dend = end_match_1; + } + else + { + d = string2 + pos - size1; + dend = end_match_2; + } + + DEBUG_PRINT1 ("The compiled pattern is:\n"); + DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); + DEBUG_PRINT1 ("The string to match is: `"); + DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); + DEBUG_PRINT1 ("'\n"); + + /* This loops over pattern commands. It exits by returning from the + function if the match is complete, or it drops through if the match + fails at this starting point in the input data. */ + for (;;) + { +#ifdef _LIBC + DEBUG_PRINT2 ("\n%p: ", p); +#else + DEBUG_PRINT2 ("\n0x%x: ", p); +#endif + + if (p == pend) + { /* End of pattern means we might have succeeded. */ + DEBUG_PRINT1 ("end of pattern ... "); + + /* If we haven't matched the entire string, and we want the + longest match, try backtracking. */ + if (d != end_match_2) + { + /* 1 if this match ends in the same string (string1 or string2) + as the best previous match. */ + boolean same_str_p = (FIRST_STRING_P (match_end) + == MATCHING_IN_FIRST_STRING); + /* 1 if this match is the best seen so far. */ + boolean best_match_p; + + /* AIX compiler got confused when this was combined + with the previous declaration. */ + if (same_str_p) + best_match_p = d > match_end; + else + best_match_p = !MATCHING_IN_FIRST_STRING; + + DEBUG_PRINT1 ("backtracking.\n"); + + if (!FAIL_STACK_EMPTY ()) + { /* More failure points to try. */ + + /* If exceeds best match so far, save it. */ + if (!best_regs_set || best_match_p) + { + best_regs_set = true; + match_end = d; + + DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); + + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + best_regstart[mcnt] = regstart[mcnt]; + best_regend[mcnt] = regend[mcnt]; + } + } + goto fail; + } + + /* If no failure points, don't restore garbage. And if + last match is real best match, don't restore second + best one. */ + else if (best_regs_set && !best_match_p) + { + restore_best_regs: + /* Restore best match. It may happen that `dend == + end_match_1' while the restored d is in string2. + For example, the pattern `x.*y.*z' against the + strings `x-' and `y-z-', if the two strings are + not consecutive in memory. */ + DEBUG_PRINT1 ("Restoring best registers.\n"); + + d = match_end; + dend = ((d >= string1 && d <= end1) + ? end_match_1 : end_match_2); + + for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) + { + regstart[mcnt] = best_regstart[mcnt]; + regend[mcnt] = best_regend[mcnt]; + } + } + } /* d != end_match_2 */ + + succeed_label: + DEBUG_PRINT1 ("Accepting match.\n"); + + /* If caller wants register contents data back, do it. */ + if (regs && !bufp->no_sub) + { + /* Have the register data arrays been allocated? */ + if (bufp->regs_allocated == REGS_UNALLOCATED) + { /* No. So allocate them with malloc. We need one + extra element beyond `num_regs' for the `-1' marker + GNU code uses. */ + regs->num_regs = MAX (RE_NREGS, num_regs + 1); + regs->start = TALLOC (regs->num_regs, regoff_t); + regs->end = TALLOC (regs->num_regs, regoff_t); + if (regs->start == NULL || regs->end == NULL) + { + FREE_VARIABLES (); + return -2; + } + bufp->regs_allocated = REGS_REALLOCATE; + } + else if (bufp->regs_allocated == REGS_REALLOCATE) + { /* Yes. If we need more elements than were already + allocated, reallocate them. If we need fewer, just + leave it alone. */ + if (regs->num_regs < num_regs + 1) + { + regs->num_regs = num_regs + 1; + RETALLOC (regs->start, regs->num_regs, regoff_t); + RETALLOC (regs->end, regs->num_regs, regoff_t); + if (regs->start == NULL || regs->end == NULL) + { + FREE_VARIABLES (); + return -2; + } + } + } + else + { + /* These braces fend off a "empty body in an else-statement" + warning under GCC when assert expands to nothing. */ + assert (bufp->regs_allocated == REGS_FIXED); + } + + /* Convert the pointer data in `regstart' and `regend' to + indices. Register zero has to be set differently, + since we haven't kept track of any info for it. */ + if (regs->num_regs > 0) + { + regs->start[0] = pos; + regs->end[0] = (MATCHING_IN_FIRST_STRING + ? ((regoff_t) (d - string1)) + : ((regoff_t) (d - string2 + size1))); + } + + /* Go through the first `min (num_regs, regs->num_regs)' + registers, since that is all we initialized. */ + for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); + mcnt++) + { + if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) + regs->start[mcnt] = regs->end[mcnt] = -1; + else + { + regs->start[mcnt] + = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); + regs->end[mcnt] + = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); + } + } + + /* If the regs structure we return has more elements than + were in the pattern, set the extra elements to -1. If + we (re)allocated the registers, this is the case, + because we always allocate enough to have at least one + -1 at the end. */ + for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) + regs->start[mcnt] = regs->end[mcnt] = -1; + } /* regs && !bufp->no_sub */ + + DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", + nfailure_points_pushed, nfailure_points_popped, + nfailure_points_pushed - nfailure_points_popped); + DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); + + mcnt = d - pos - (MATCHING_IN_FIRST_STRING + ? string1 + : string2 - size1); + + DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); + + FREE_VARIABLES (); + return mcnt; + } + + /* Otherwise match next pattern command. */ + switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) + { + /* Ignore these. Used to ignore the n of succeed_n's which + currently have n == 0. */ + case no_op: + DEBUG_PRINT1 ("EXECUTING no_op.\n"); + break; + + case succeed: + DEBUG_PRINT1 ("EXECUTING succeed.\n"); + goto succeed_label; + + /* Match the next n pattern characters exactly. The following + byte in the pattern defines n, and the n bytes after that + are the characters to match. */ + case exactn: + mcnt = *p++; + DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); + + /* This is written out as an if-else so we don't waste time + testing `translate' inside the loop. */ + if (translate) + { + do + { + PREFETCH (); + if ((unsigned char) translate[(unsigned char) *d++] + != (unsigned char) *p++) + goto fail; + } + while (--mcnt); + } + else + { + do + { + PREFETCH (); + if (*d++ != (char) *p++) goto fail; + } + while (--mcnt); + } + SET_REGS_MATCHED (); + break; + + + /* Match any character except possibly a newline or a null. */ + case anychar: + DEBUG_PRINT1 ("EXECUTING anychar.\n"); + + PREFETCH (); + + if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') + || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) + goto fail; + + SET_REGS_MATCHED (); + DEBUG_PRINT2 (" Matched `%d'.\n", *d); + d++; + break; + + + case charset: + case charset_not: + { + register unsigned char c; + boolean not = (re_opcode_t) *(p - 1) == charset_not; + + DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); + + PREFETCH (); + c = TRANSLATE (*d); /* The character to match. */ + + /* Cast to `unsigned' instead of `unsigned char' in case the + bit list is a full 32 bytes long. */ + if (c < (unsigned) (*p * BYTEWIDTH) + && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) + not = !not; + + p += 1 + *p; + + if (!not) goto fail; + + SET_REGS_MATCHED (); + d++; + break; + } + + + /* The beginning of a group is represented by start_memory. + The arguments are the register number in the next byte, and the + number of groups inner to this one in the next. The text + matched within the group is recorded (in the internal + registers data structure) under the register number. */ + case start_memory: + DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); + + /* Find out if this group can match the empty string. */ + p1 = p; /* To send to group_match_null_string_p. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[*p]) + = group_match_null_string_p (&p1, pend, reg_info); + + /* Save the position in the string where we were the last time + we were at this open-group operator in case the group is + operated upon by a repetition operator, e.g., with `(a*)*b' + against `ab'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regstart[*p]) ? d : regstart[*p] + : regstart[*p]; + DEBUG_PRINT2 (" old_regstart: %d\n", + POINTER_TO_OFFSET (old_regstart[*p])); + + regstart[*p] = d; + DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); + + IS_ACTIVE (reg_info[*p]) = 1; + MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Clear this whenever we change the register activity status. */ + set_regs_matched_done = 0; + + /* This is the new highest active register. */ + highest_active_reg = *p; + + /* If nothing was active before, this is the new lowest active + register. */ + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) + lowest_active_reg = *p; + + /* Move past the register number and inner group count. */ + p += 2; + just_past_start_mem = p; + + break; + + + /* The stop_memory opcode represents the end of a group. Its + arguments are the same as start_memory's: the register + number, and the number of inner groups. */ + case stop_memory: + DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); + + /* We need to save the string position the last time we were at + this close-group operator in case the group is operated + upon by a repetition operator, e.g., with `((a*)*(b*)*)*' + against `aba'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regend[*p]) ? d : regend[*p] + : regend[*p]; + DEBUG_PRINT2 (" old_regend: %d\n", + POINTER_TO_OFFSET (old_regend[*p])); + + regend[*p] = d; + DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); + + /* This register isn't active anymore. */ + IS_ACTIVE (reg_info[*p]) = 0; + + /* Clear this whenever we change the register activity status. */ + set_regs_matched_done = 0; + + /* If this was the only register active, nothing is active + anymore. */ + if (lowest_active_reg == highest_active_reg) + { + lowest_active_reg = NO_LOWEST_ACTIVE_REG; + highest_active_reg = NO_HIGHEST_ACTIVE_REG; + } + else + { /* We must scan for the new highest active register, since + it isn't necessarily one less than now: consider + (a(b)c(d(e)f)g). When group 3 ends, after the f), the + new highest active register is 1. */ + unsigned char r = *p - 1; + while (r > 0 && !IS_ACTIVE (reg_info[r])) + r--; + + /* If we end up at register zero, that means that we saved + the registers as the result of an `on_failure_jump', not + a `start_memory', and we jumped to past the innermost + `stop_memory'. For example, in ((.)*) we save + registers 1 and 2 as a result of the *, but when we pop + back to the second ), we are at the stop_memory 1. + Thus, nothing is active. */ + if (r == 0) + { + lowest_active_reg = NO_LOWEST_ACTIVE_REG; + highest_active_reg = NO_HIGHEST_ACTIVE_REG; + } + else + highest_active_reg = r; + } + + /* If just failed to match something this time around with a + group that's operated on by a repetition operator, try to + force exit from the ``loop'', and restore the register + information for this group that we had before trying this + last match. */ + if ((!MATCHED_SOMETHING (reg_info[*p]) + || just_past_start_mem == p - 1) + && (p + 2) < pend) + { + boolean is_a_jump_n = false; + + p1 = p + 2; + mcnt = 0; + switch ((re_opcode_t) *p1++) + { + case jump_n: + is_a_jump_n = true; + case pop_failure_jump: + case maybe_pop_jump: + case jump: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (is_a_jump_n) + p1 += 2; + break; + + default: + /* do nothing */ ; + } + p1 += mcnt; + + /* If the next operation is a jump backwards in the pattern + to an on_failure_jump right before the start_memory + corresponding to this stop_memory, exit from the loop + by forcing a failure after pushing on the stack the + on_failure_jump's jump in the pattern, and d. */ + if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump + && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) + { + /* If this group ever matched anything, then restore + what its registers were before trying this last + failed match, e.g., with `(a*)*b' against `ab' for + regstart[1], and, e.g., with `((a*)*(b*)*)*' + against `aba' for regend[3]. + + Also restore the registers for inner groups for, + e.g., `((a*)(b*))*' against `aba' (register 3 would + otherwise get trashed). */ + + if (EVER_MATCHED_SOMETHING (reg_info[*p])) + { + unsigned r; + + EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Restore this and inner groups' (if any) registers. */ + for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1); + r++) + { + regstart[r] = old_regstart[r]; + + /* xx why this test? */ + if (old_regend[r] >= regstart[r]) + regend[r] = old_regend[r]; + } + } + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + PUSH_FAILURE_POINT (p1 + mcnt, d, -2); + + goto fail; + } + } + + /* Move past the register number and the inner group count. */ + p += 2; + break; + + + /* \ has been turned into a `duplicate' command which is + followed by the numeric value of as the register number. */ + case duplicate: + { + register const char *d2, *dend2; + int regno = *p++; /* Get which register to match against. */ + DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); + + /* Can't back reference a group which we've never matched. */ + if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) + goto fail; + + /* Where in input to try to start matching. */ + d2 = regstart[regno]; + + /* Where to stop matching; if both the place to start and + the place to stop matching are in the same string, then + set to the place to stop, otherwise, for now have to use + the end of the first string. */ + + dend2 = ((FIRST_STRING_P (regstart[regno]) + == FIRST_STRING_P (regend[regno])) + ? regend[regno] : end_match_1); + for (;;) + { + /* If necessary, advance to next segment in register + contents. */ + while (d2 == dend2) + { + if (dend2 == end_match_2) break; + if (dend2 == regend[regno]) break; + + /* End of string1 => advance to string2. */ + d2 = string2; + dend2 = regend[regno]; + } + /* At end of register contents => success */ + if (d2 == dend2) break; + + /* If necessary, advance to next segment in data. */ + PREFETCH (); + + /* How many characters left in this segment to match. */ + mcnt = dend - d; + + /* Want how many consecutive characters we can match in + one shot, so, if necessary, adjust the count. */ + if (mcnt > dend2 - d2) + mcnt = dend2 - d2; + + /* Compare that many; failure if mismatch, else move + past them. */ + if (translate + ? bcmp_translate (d, d2, mcnt, translate) + : memcmp (d, d2, mcnt)) + goto fail; + d += mcnt, d2 += mcnt; + + /* Do this because we've match some characters. */ + SET_REGS_MATCHED (); + } + } + break; + + + /* begline matches the empty string at the beginning of the string + (unless `not_bol' is set in `bufp'), and, if + `newline_anchor' is set, after newlines. */ + case begline: + DEBUG_PRINT1 ("EXECUTING begline.\n"); + + if (AT_STRINGS_BEG (d)) + { + if (!bufp->not_bol) break; + } + else if (d[-1] == '\n' && bufp->newline_anchor) + { + break; + } + /* In all other cases, we fail. */ + goto fail; + + + /* endline is the dual of begline. */ + case endline: + DEBUG_PRINT1 ("EXECUTING endline.\n"); + + if (AT_STRINGS_END (d)) + { + if (!bufp->not_eol) break; + } + + /* We have to ``prefetch'' the next character. */ + else if ((d == end1 ? *string2 : *d) == '\n' + && bufp->newline_anchor) + { + break; + } + goto fail; + + + /* Match at the very beginning of the data. */ + case begbuf: + DEBUG_PRINT1 ("EXECUTING begbuf.\n"); + if (AT_STRINGS_BEG (d)) + break; + goto fail; + + + /* Match at the very end of the data. */ + case endbuf: + DEBUG_PRINT1 ("EXECUTING endbuf.\n"); + if (AT_STRINGS_END (d)) + break; + goto fail; + + + /* on_failure_keep_string_jump is used to optimize `.*\n'. It + pushes NULL as the value for the string on the stack. Then + `pop_failure_point' will keep the current value for the + string, instead of restoring it. To see why, consider + matching `foo\nbar' against `.*\n'. The .* matches the foo; + then the . fails against the \n. But the next thing we want + to do is match the \n against the \n; if we restored the + string value, we would be back at the foo. + + Because this is used only in specific cases, we don't need to + check all the things that `on_failure_jump' does, to make + sure the right things get saved on the stack. Hence we don't + share its code. The only reason to push anything on the + stack at all is that otherwise we would have to change + `anychar's code to do something besides goto fail in this + case; that seems worse than this. */ + case on_failure_keep_string_jump: + DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt); +#else + DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt); +#endif + + PUSH_FAILURE_POINT (p + mcnt, NULL, -2); + break; + + + /* Uses of on_failure_jump: + + Each alternative starts with an on_failure_jump that points + to the beginning of the next alternative. Each alternative + except the last ends with a jump that in effect jumps past + the rest of the alternatives. (They really jump to the + ending jump of the following alternative, because tensioning + these jumps is a hassle.) + + Repeats start with an on_failure_jump that points past both + the repetition text and either the following jump or + pop_failure_jump back to this on_failure_jump. */ + case on_failure_jump: + on_failure: + DEBUG_PRINT1 ("EXECUTING on_failure_jump"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt); +#else + DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt); +#endif + + /* If this on_failure_jump comes right before a group (i.e., + the original * applied to a group), save the information + for that group and all inner ones, so that if we fail back + to this point, the group's information will be correct. + For example, in \(a*\)*\1, we need the preceding group, + and in \(zz\(a*\)b*\)\2, we need the inner group. */ + + /* We can't use `p' to check ahead because we push + a failure point to `p + mcnt' after we do this. */ + p1 = p; + + /* We need to skip no_op's before we look for the + start_memory in case this on_failure_jump is happening as + the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 + against aba. */ + while (p1 < pend && (re_opcode_t) *p1 == no_op) + p1++; + + if (p1 < pend && (re_opcode_t) *p1 == start_memory) + { + /* We have a new highest active register now. This will + get reset at the start_memory we are about to get to, + but we will have saved all the registers relevant to + this repetition op, as described above. */ + highest_active_reg = *(p1 + 1) + *(p1 + 2); + if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) + lowest_active_reg = *(p1 + 1); + } + + DEBUG_PRINT1 (":\n"); + PUSH_FAILURE_POINT (p + mcnt, d, -2); + break; + + + /* A smart repeat ends with `maybe_pop_jump'. + We change it to either `pop_failure_jump' or `jump'. */ + case maybe_pop_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); + { + register unsigned char *p2 = p; + + /* Compare the beginning of the repeat with what in the + pattern follows its end. If we can establish that there + is nothing that they would both match, i.e., that we + would have to backtrack because of (as in, e.g., `a*a') + then we can change to pop_failure_jump, because we'll + never have to backtrack. + + This is not true in the case of alternatives: in + `(a|ab)*' we do need to backtrack to the `ab' alternative + (e.g., if the string was `ab'). But instead of trying to + detect that here, the alternative has put on a dummy + failure point which is what we will end up popping. */ + + /* Skip over open/close-group commands. + If what follows this loop is a ...+ construct, + look at what begins its body, since we will have to + match at least one of that. */ + while (1) + { + if (p2 + 2 < pend + && ((re_opcode_t) *p2 == stop_memory + || (re_opcode_t) *p2 == start_memory)) + p2 += 3; + else if (p2 + 6 < pend + && (re_opcode_t) *p2 == dummy_failure_jump) + p2 += 6; + else + break; + } + + p1 = p + mcnt; + /* p1[0] ... p1[2] are the `on_failure_jump' corresponding + to the `maybe_finalize_jump' of this case. Examine what + follows. */ + + /* If we're at the end of the pattern, we can change. */ + if (p2 == pend) + { + /* Consider what happens when matching ":\(.*\)" + against ":/". I don't really understand this code + yet. */ + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 + (" End of pattern: change to `pop_failure_jump'.\n"); + } + + else if ((re_opcode_t) *p2 == exactn + || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) + { + register unsigned char c + = *p2 == (unsigned char) endline ? '\n' : p2[2]; + + if ((re_opcode_t) p1[3] == exactn && p1[5] != c) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", + c, p1[5]); + } + + else if ((re_opcode_t) p1[3] == charset + || (re_opcode_t) p1[3] == charset_not) + { + int not = (re_opcode_t) p1[3] == charset_not; + + if (c < (unsigned char) (p1[4] * BYTEWIDTH) + && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) + not = !not; + + /* `not' is equal to 1 if c would match, which means + that we can't change to pop_failure_jump. */ + if (!not) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + } + else if ((re_opcode_t) *p2 == charset) + { +#ifdef DEBUG + register unsigned char c + = *p2 == (unsigned char) endline ? '\n' : p2[2]; +#endif + +#if 0 + if ((re_opcode_t) p1[3] == exactn + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5] + && (p2[2 + p1[5] / BYTEWIDTH] + & (1 << (p1[5] % BYTEWIDTH))))) +#else + if ((re_opcode_t) p1[3] == exactn + && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4] + && (p2[2 + p1[4] / BYTEWIDTH] + & (1 << (p1[4] % BYTEWIDTH))))) +#endif + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", + c, p1[5]); + } + + else if ((re_opcode_t) p1[3] == charset_not) + { + int idx; + /* We win if the charset_not inside the loop + lists every character listed in the charset after. */ + for (idx = 0; idx < (int) p2[1]; idx++) + if (! (p2[2 + idx] == 0 + || (idx < (int) p1[4] + && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) + break; + + if (idx == p2[1]) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + else if ((re_opcode_t) p1[3] == charset) + { + int idx; + /* We win if the charset inside the loop + has no overlap with the one after the loop. */ + for (idx = 0; + idx < (int) p2[1] && idx < (int) p1[4]; + idx++) + if ((p2[2 + idx] & p1[5 + idx]) != 0) + break; + + if (idx == p2[1] || idx == p1[4]) + { + p[-3] = (unsigned char) pop_failure_jump; + DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); + } + } + } + } + p -= 2; /* Point at relative address again. */ + if ((re_opcode_t) p[-1] != pop_failure_jump) + { + p[-1] = (unsigned char) jump; + DEBUG_PRINT1 (" Match => jump.\n"); + goto unconditional_jump; + } + /* Note fall through. */ + + + /* The end of a simple repeat has a pop_failure_jump back to + its matching on_failure_jump, where the latter will push a + failure point. The pop_failure_jump takes off failure + points put on by this pop_failure_jump's matching + on_failure_jump; we got through the pattern to here from the + matching on_failure_jump, so didn't fail. */ + case pop_failure_jump: + { + /* We need to pass separate storage for the lowest and + highest registers, even though we don't care about the + actual values. Otherwise, we will restore only one + register from the stack, since lowest will == highest in + `pop_failure_point'. */ + active_reg_t dummy_low_reg, dummy_high_reg; + unsigned char *pdummy; + const char *sdummy; + + DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); + POP_FAILURE_POINT (sdummy, pdummy, + dummy_low_reg, dummy_high_reg, + reg_dummy, reg_dummy, reg_info_dummy); + } + /* Note fall through. */ + + unconditional_jump: +#ifdef _LIBC + DEBUG_PRINT2 ("\n%p: ", p); +#else + DEBUG_PRINT2 ("\n0x%x: ", p); +#endif + /* Note fall through. */ + + /* Unconditionally jump (without popping any failure points). */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ + DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); + p += mcnt; /* Do the jump. */ +#ifdef _LIBC + DEBUG_PRINT2 ("(to %p).\n", p); +#else + DEBUG_PRINT2 ("(to 0x%x).\n", p); +#endif + break; + + + /* We need this opcode so we can detect where alternatives end + in `group_match_null_string_p' et al. */ + case jump_past_alt: + DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); + goto unconditional_jump; + + + /* Normally, the on_failure_jump pushes a failure point, which + then gets popped at pop_failure_jump. We will end up at + pop_failure_jump, also, and with a pattern of, say, `a+', we + are skipping over the on_failure_jump, so we have to push + something meaningless for pop_failure_jump to pop. */ + case dummy_failure_jump: + DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); + /* It doesn't matter what we push for the string here. What + the code at `fail' tests is the value for the pattern. */ + PUSH_FAILURE_POINT (NULL, NULL, -2); + goto unconditional_jump; + + + /* At the end of an alternative, we need to push a dummy failure + point in case we are followed by a `pop_failure_jump', because + we don't want the failure point for the alternative to be + popped. For example, matching `(a|ab)*' against `aab' + requires that we match the `ab' alternative. */ + case push_dummy_failure: + DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); + /* See comments just above at `dummy_failure_jump' about the + two zeroes. */ + PUSH_FAILURE_POINT (NULL, NULL, -2); + break; + + /* Have to succeed matching what follows at least n times. + After that, handle like `on_failure_jump'. */ + case succeed_n: + EXTRACT_NUMBER (mcnt, p + 2); + DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); + + assert (mcnt >= 0); + /* Originally, this is how many times we HAVE to succeed. */ + if (mcnt > 0) + { + mcnt--; + p += 2; + STORE_NUMBER_AND_INCR (p, mcnt); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt); +#endif + } + else if (mcnt == 0) + { +#ifdef _LIBC + DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2); +#else + DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2); +#endif + p[2] = (unsigned char) no_op; + p[3] = (unsigned char) no_op; + goto on_failure; + } + break; + + case jump_n: + EXTRACT_NUMBER (mcnt, p + 2); + DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); + + /* Originally, this is how many times we CAN jump. */ + if (mcnt) + { + mcnt--; + STORE_NUMBER (p + 2, mcnt); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt); +#endif + goto unconditional_jump; + } + /* If don't have to jump any more, skip over the rest of command. */ + else + p += 4; + break; + + case set_number_at: + { + DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); + + EXTRACT_NUMBER_AND_INCR (mcnt, p); + p1 = p + mcnt; + EXTRACT_NUMBER_AND_INCR (mcnt, p); +#ifdef _LIBC + DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); +#else + DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt); +#endif + STORE_NUMBER (p1, mcnt); + break; + } + +#if 0 + /* The DEC Alpha C compiler 3.x generates incorrect code for the + test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of + AT_WORD_BOUNDARY, so this code is disabled. Expanding the + macro and introducing temporary variables works around the bug. */ + + case wordbound: + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); + if (AT_WORD_BOUNDARY (d)) + break; + goto fail; + + case notwordbound: + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); + if (AT_WORD_BOUNDARY (d)) + goto fail; + break; +#else + case wordbound: + { + boolean prevchar, thischar; + + DEBUG_PRINT1 ("EXECUTING wordbound.\n"); + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) + break; + + prevchar = WORDCHAR_P (d - 1); + thischar = WORDCHAR_P (d); + if (prevchar != thischar) + break; + goto fail; + } + + case notwordbound: + { + boolean prevchar, thischar; + + DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); + if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) + goto fail; + + prevchar = WORDCHAR_P (d - 1); + thischar = WORDCHAR_P (d); + if (prevchar != thischar) + goto fail; + break; + } +#endif + + case wordbeg: + DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); + if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) + break; + goto fail; + + case wordend: + DEBUG_PRINT1 ("EXECUTING wordend.\n"); + if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) + && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) + break; + goto fail; + +#ifdef emacs + case before_dot: + DEBUG_PRINT1 ("EXECUTING before_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) >= point) + goto fail; + break; + + case at_dot: + DEBUG_PRINT1 ("EXECUTING at_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) != point) + goto fail; + break; + + case after_dot: + DEBUG_PRINT1 ("EXECUTING after_dot.\n"); + if (PTR_CHAR_POS ((unsigned char *) d) <= point) + goto fail; + break; + + case syntaxspec: + DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); + mcnt = *p++; + goto matchsyntax; + + case wordchar: + DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); + mcnt = (int) Sword; + matchsyntax: + PREFETCH (); + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ + d++; + if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt) + goto fail; + SET_REGS_MATCHED (); + break; + + case notsyntaxspec: + DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); + mcnt = *p++; + goto matchnotsyntax; + + case notwordchar: + DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); + mcnt = (int) Sword; + matchnotsyntax: + PREFETCH (); + /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ + d++; + if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt) + goto fail; + SET_REGS_MATCHED (); + break; + +#else /* not emacs */ + case wordchar: + DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); + PREFETCH (); + if (!WORDCHAR_P (d)) + goto fail; + SET_REGS_MATCHED (); + d++; + break; + + case notwordchar: + DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); + PREFETCH (); + if (WORDCHAR_P (d)) + goto fail; + SET_REGS_MATCHED (); + d++; + break; +#endif /* not emacs */ + + default: + abort (); + } + continue; /* Successfully executed one pattern command; keep going. */ + + + /* We goto here if a matching operation fails. */ + fail: + if (!FAIL_STACK_EMPTY ()) + { /* A restart point is known. Restore to that state. */ + DEBUG_PRINT1 ("\nFAIL:\n"); + POP_FAILURE_POINT (d, p, + lowest_active_reg, highest_active_reg, + regstart, regend, reg_info); + + /* If this failure point is a dummy, try the next one. */ + if (!p) + goto fail; + + /* If we failed to the end of the pattern, don't examine *p. */ + assert (p <= pend); + if (p < pend) + { + boolean is_a_jump_n = false; + + /* If failed to a backwards jump that's part of a repetition + loop, need to pop this failure point and use the next one. */ + switch ((re_opcode_t) *p) + { + case jump_n: + is_a_jump_n = true; + case maybe_pop_jump: + case pop_failure_jump: + case jump: + p1 = p + 1; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + + if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) + || (!is_a_jump_n + && (re_opcode_t) *p1 == on_failure_jump)) + goto fail; + break; + default: + /* do nothing */ ; + } + } + + if (d >= string1 && d <= end1) + dend = end_match_1; + } + else + break; /* Matching at this starting point really fails. */ + } /* for (;;) */ + + if (best_regs_set) + goto restore_best_regs; + + FREE_VARIABLES (); + + return -1; /* Failure to match. */ +} /* re_match_2 */ + +/* Subroutine definitions for re_match_2. */ + + +/* We are passed P pointing to a register number after a start_memory. + + Return true if the pattern up to the corresponding stop_memory can + match the empty string, and false otherwise. + + If we find the matching stop_memory, sets P to point to one past its number. + Otherwise, sets P to an undefined byte less than or equal to END. + + We don't handle duplicates properly (yet). */ + +static boolean +group_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + /* Point to after the args to the start_memory. */ + unsigned char *p1 = *p + 2; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and return true or + false, as appropriate, when we get to one that can't, or to the + matching stop_memory. */ + + switch ((re_opcode_t) *p1) + { + /* Could be either a loop or a series of alternatives. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + /* If the next operation is not a jump backwards in the + pattern. */ + + if (mcnt >= 0) + { + /* Go through the on_failure_jumps of the alternatives, + seeing if any of the alternatives cannot match nothing. + The last alternative starts with only a jump, + whereas the rest start with on_failure_jump and end + with a jump, e.g., here is the pattern for `a|b|c': + + /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 + /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 + /exactn/1/c + + So, we have to first go through the first (n-1) + alternatives and then deal with the last one separately. */ + + + /* Deal with the first (n-1) alternatives, which start + with an on_failure_jump (see above) that jumps to right + past a jump_past_alt. */ + + while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) + { + /* `mcnt' holds how many bytes long the alternative + is, including the ending `jump_past_alt' and + its number. */ + + if (!alt_match_null_string_p (p1, p1 + mcnt - 3, + reg_info)) + return false; + + /* Move to right after this alternative, including the + jump_past_alt. */ + p1 += mcnt; + + /* Break if it's the beginning of an n-th alternative + that doesn't begin with an on_failure_jump. */ + if ((re_opcode_t) *p1 != on_failure_jump) + break; + + /* Still have to check that it's not an n-th + alternative that starts with an on_failure_jump. */ + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) + { + /* Get to the beginning of the n-th alternative. */ + p1 -= 3; + break; + } + } + + /* Deal with the last alternative: go back and get number + of the `jump_past_alt' just before it. `mcnt' contains + the length of the alternative. */ + EXTRACT_NUMBER (mcnt, p1 - 2); + + if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) + return false; + + p1 += mcnt; /* Get past the n-th alternative. */ + } /* if mcnt > 0 */ + break; + + + case stop_memory: + assert (p1[1] == **p); + *p = p1 + 2; + return true; + + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return false; + } + } /* while p1 < end */ + + return false; +} /* group_match_null_string_p */ + + +/* Similar to group_match_null_string_p, but doesn't deal with alternatives: + It expects P to be the first byte of a single alternative and END one + byte past the last. The alternative can contain groups. */ + +static boolean +alt_match_null_string_p (p, end, reg_info) + unsigned char *p, *end; + register_info_type *reg_info; +{ + int mcnt; + unsigned char *p1 = p; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and break when we get + to one that can't. */ + + switch ((re_opcode_t) *p1) + { + /* It's a loop. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + break; + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return false; + } + } /* while p1 < end */ + + return true; +} /* alt_match_null_string_p */ + + +/* Deals with the ops common to group_match_null_string_p and + alt_match_null_string_p. + + Sets P to one after the op and its arguments, if any. */ + +static boolean +common_op_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + boolean ret; + int reg_no; + unsigned char *p1 = *p; + + switch ((re_opcode_t) *p1++) + { + case no_op: + case begline: + case endline: + case begbuf: + case endbuf: + case wordbeg: + case wordend: + case wordbound: + case notwordbound: +#ifdef emacs + case before_dot: + case at_dot: + case after_dot: +#endif + break; + + case start_memory: + reg_no = *p1; + assert (reg_no > 0 && reg_no <= MAX_REGNUM); + ret = group_match_null_string_p (&p1, end, reg_info); + + /* Have to set this here in case we're checking a group which + contains a group and a back reference to it. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; + + if (!ret) + return false; + break; + + /* If this is an optimized succeed_n for zero times, make the jump. */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (mcnt >= 0) + p1 += mcnt; + else + return false; + break; + + case succeed_n: + /* Get to the number of times to succeed. */ + p1 += 2; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + if (mcnt == 0) + { + p1 -= 4; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + } + else + return false; + break; + + case duplicate: + if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) + return false; + break; + + case set_number_at: + p1 += 4; + + default: + /* All other opcodes mean we cannot match the empty string. */ + return false; + } + + *p = p1; + return true; +} /* common_op_match_null_string_p */ + + +/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN + bytes; nonzero otherwise. */ + +static int +bcmp_translate (s1, s2, len, translate) + const char *s1, *s2; + register int len; + RE_TRANSLATE_TYPE translate; +{ + register const unsigned char *p1 = (const unsigned char *) s1; + register const unsigned char *p2 = (const unsigned char *) s2; + while (len) + { + if (translate[*p1++] != translate[*p2++]) return 1; + len--; + } + return 0; +} + +/* Entry points for GNU code. */ + +/* re_compile_pattern is the GNU regular expression compiler: it + compiles PATTERN (of length SIZE) and puts the result in BUFP. + Returns 0 if the pattern was valid, otherwise an error string. + + Assumes the `allocated' (and perhaps `buffer') and `translate' fields + are set in BUFP on entry. + + We call regex_compile to do the actual compilation. */ + +const char * +re_compile_pattern (pattern, length, bufp) + const char *pattern; + size_t length; + struct re_pattern_buffer *bufp; +{ + reg_errcode_t ret; + + /* GNU code is written to assume at least RE_NREGS registers will be set + (and at least one extra will be -1). */ + bufp->regs_allocated = REGS_UNALLOCATED; + + /* And GNU code determines whether or not to get register information + by passing null for the REGS argument to re_match, etc., not by + setting no_sub. */ + bufp->no_sub = 0; + + /* Match anchors at newline. */ + bufp->newline_anchor = 1; + + ret = regex_compile (pattern, length, re_syntax_options, bufp); + + if (!ret) + return NULL; + return gettext (re_error_msgid[(int) ret]); +} +#ifdef _LIBC +weak_alias (__re_compile_pattern, re_compile_pattern) +#endif + +/* Entry points compatible with 4.2 BSD regex library. We don't define + them unless specifically requested. */ + +#if defined _REGEX_RE_COMP || defined _LIBC + +/* BSD has one and only one pattern buffer. */ +static struct re_pattern_buffer re_comp_buf; + +char * +#ifdef _LIBC +/* Make these definitions weak in libc, so POSIX programs can redefine + these names if they don't use our functions, and still use + regcomp/regexec below without link errors. */ +weak_function +#endif +re_comp (s) + const char *s; +{ + reg_errcode_t ret; + + if (!s) + { + if (!re_comp_buf.buffer) + return gettext ("No previous regular expression"); + return 0; + } + + if (!re_comp_buf.buffer) + { + re_comp_buf.buffer = (unsigned char *) malloc (200); + if (re_comp_buf.buffer == NULL) + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); + re_comp_buf.allocated = 200; + + re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); + if (re_comp_buf.fastmap == NULL) + return (char *) gettext (re_error_msgid[(int) REG_ESPACE]); + } + + /* Since `re_exec' always passes NULL for the `regs' argument, we + don't need to initialize the pattern buffer fields which affect it. */ + + /* Match anchors at newlines. */ + re_comp_buf.newline_anchor = 1; + + ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); + + if (!ret) + return NULL; + + /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ + return (char *) gettext (re_error_msgid[(int) ret]); +} + + +int +#ifdef _LIBC +weak_function +#endif +re_exec (s) + const char *s; +{ + const int len = strlen (s); + return + 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); +} + +#endif /* _REGEX_RE_COMP */ + +/* POSIX.2 functions. Don't define these for Emacs. */ + +#ifndef emacs + +/* regcomp takes a regular expression as a string and compiles it. + + PREG is a regex_t *. We do not expect any fields to be initialized, + since POSIX says we shouldn't. Thus, we set + + `buffer' to the compiled pattern; + `used' to the length of the compiled pattern; + `syntax' to RE_SYNTAX_POSIX_EXTENDED if the + REG_EXTENDED bit in CFLAGS is set; otherwise, to + RE_SYNTAX_POSIX_BASIC; + `newline_anchor' to REG_NEWLINE being set in CFLAGS; + `fastmap' to an allocated space for the fastmap; + `fastmap_accurate' to zero; + `re_nsub' to the number of subexpressions in PATTERN. + + PATTERN is the address of the pattern string. + + CFLAGS is a series of bits which affect compilation. + + If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we + use POSIX basic syntax. + + If REG_NEWLINE is set, then . and [^...] don't match newline. + Also, regexec will try a match beginning after every newline. + + If REG_ICASE is set, then we considers upper- and lowercase + versions of letters to be equivalent when matching. + + If REG_NOSUB is set, then when PREG is passed to regexec, that + routine will report only success or failure, and nothing about the + registers. + + It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for + the return codes and their meanings.) */ + +int +regcomp (preg, pattern, cflags) + regex_t *preg; + const char *pattern; + int cflags; +{ + reg_errcode_t ret; + reg_syntax_t syntax + = (cflags & REG_EXTENDED) ? + RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; + + /* regex_compile will allocate the space for the compiled pattern. */ + preg->buffer = 0; + preg->allocated = 0; + preg->used = 0; + + /* Try to allocate space for the fastmap. */ + preg->fastmap = (char *) malloc (1 << BYTEWIDTH); + + if (cflags & REG_ICASE) + { + unsigned i; + + preg->translate + = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE + * sizeof (*(RE_TRANSLATE_TYPE)0)); + if (preg->translate == NULL) + return (int) REG_ESPACE; + + /* Map uppercase characters to corresponding lowercase ones. */ + for (i = 0; i < CHAR_SET_SIZE; i++) + preg->translate[i] = ISUPPER (i) ? tolower (i) : i; + } + else + preg->translate = NULL; + + /* If REG_NEWLINE is set, newlines are treated differently. */ + if (cflags & REG_NEWLINE) + { /* REG_NEWLINE implies neither . nor [^...] match newline. */ + syntax &= ~RE_DOT_NEWLINE; + syntax |= RE_HAT_LISTS_NOT_NEWLINE; + /* It also changes the matching behavior. */ + preg->newline_anchor = 1; + } + else + preg->newline_anchor = 0; + + preg->no_sub = !!(cflags & REG_NOSUB); + + /* POSIX says a null character in the pattern terminates it, so we + can use strlen here in compiling the pattern. */ + ret = regex_compile (pattern, strlen (pattern), syntax, preg); + + /* POSIX doesn't distinguish between an unmatched open-group and an + unmatched close-group: both are REG_EPAREN. */ + if (ret == REG_ERPAREN) ret = REG_EPAREN; + + if (ret == REG_NOERROR && preg->fastmap) + { + /* Compute the fastmap now, since regexec cannot modify the pattern + buffer. */ + if (re_compile_fastmap (preg) == -2) + { + /* Some error occured while computing the fastmap, just forget + about it. */ + free (preg->fastmap); + preg->fastmap = NULL; + } + } + + return (int) ret; +} +#ifdef _LIBC +weak_alias (__regcomp, regcomp) +#endif + + +/* regexec searches for a given pattern, specified by PREG, in the + string STRING. + + If NMATCH is zero or REG_NOSUB was set in the cflags argument to + `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at + least NMATCH elements, and we set them to the offsets of the + corresponding matched substrings. + + EFLAGS specifies `execution flags' which affect matching: if + REG_NOTBOL is set, then ^ does not match at the beginning of the + string; if REG_NOTEOL is set, then $ does not match at the end. + + We return 0 if we find a match and REG_NOMATCH if not. */ + +int +regexec (preg, string, nmatch, pmatch, eflags) + const regex_t *preg; + const char *string; + size_t nmatch; + regmatch_t pmatch[]; + int eflags; +{ + int ret; + struct re_registers regs; + regex_t private_preg; + int len = strlen (string); + boolean want_reg_info = !preg->no_sub && nmatch > 0; + + private_preg = *preg; + + private_preg.not_bol = !!(eflags & REG_NOTBOL); + private_preg.not_eol = !!(eflags & REG_NOTEOL); + + /* The user has told us exactly how many registers to return + information about, via `nmatch'. We have to pass that on to the + matching routines. */ + private_preg.regs_allocated = REGS_FIXED; + + if (want_reg_info) + { + regs.num_regs = nmatch; + regs.start = TALLOC (nmatch * 2, regoff_t); + if (regs.start == NULL) + return (int) REG_NOMATCH; + regs.end = regs.start + nmatch; + } + + /* Perform the searching operation. */ + ret = re_search (&private_preg, string, len, + /* start: */ 0, /* range: */ len, + want_reg_info ? ®s : (struct re_registers *) 0); + + /* Copy the register information to the POSIX structure. */ + if (want_reg_info) + { + if (ret >= 0) + { + unsigned r; + + for (r = 0; r < nmatch; r++) + { + pmatch[r].rm_so = regs.start[r]; + pmatch[r].rm_eo = regs.end[r]; + } + } + + /* If we needed the temporary register info, free the space now. */ + free (regs.start); + } + + /* We want zero return to mean success, unlike `re_search'. */ + return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; +} +#ifdef _LIBC +weak_alias (__regexec, regexec) +#endif + + +/* Returns a message corresponding to an error code, ERRCODE, returned + from either regcomp or regexec. We don't use PREG here. */ + +size_t +regerror (errcode, preg, errbuf, errbuf_size) + int errcode; + const regex_t *preg; + char *errbuf; + size_t errbuf_size; +{ + const char *msg; + size_t msg_size; + + if (errcode < 0 + || errcode >= (int) (sizeof (re_error_msgid) + / sizeof (re_error_msgid[0]))) + /* Only error codes returned by the rest of the code should be passed + to this routine. If we are given anything else, or if other regex + code generates an invalid error code, then the program has a bug. + Dump core so we can fix it. */ + abort (); + + msg = gettext (re_error_msgid[errcode]); + + msg_size = strlen (msg) + 1; /* Includes the null. */ + + if (errbuf_size != 0) + { + if (msg_size > errbuf_size) + { +#if defined HAVE_MEMPCPY || defined _LIBC + *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; +#else + memcpy (errbuf, msg, errbuf_size - 1); + errbuf[errbuf_size - 1] = 0; +#endif + } + else + memcpy (errbuf, msg, msg_size); + } + + return msg_size; +} +#ifdef _LIBC +weak_alias (__regerror, regerror) +#endif + + +/* Free dynamically allocated space used by PREG. */ + +void +regfree (preg) + regex_t *preg; +{ + if (preg->buffer != NULL) + free (preg->buffer); + preg->buffer = NULL; + + preg->allocated = 0; + preg->used = 0; + + if (preg->fastmap != NULL) + free (preg->fastmap); + preg->fastmap = NULL; + preg->fastmap_accurate = 0; + + if (preg->translate != NULL) + free (preg->translate); + preg->translate = NULL; +} +#ifdef _LIBC +weak_alias (__regfree, regfree) +#endif + +#endif /* not emacs */ diff --git a/goldlib/glibc/regex.h b/goldlib/glibc/regex.h new file mode 100644 index 0000000..2bca537 --- /dev/null +++ b/goldlib/glibc/regex.h @@ -0,0 +1,572 @@ +/* Definitions for data structures and routines for the regular + expression library, version 0.12. + Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc. + + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in /gd/gnu/lib. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _REGEX_H +#define _REGEX_H 1 + +/* Allow the use in C++ code. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* POSIX says that must be included (by the caller) before + . */ + +#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS +/* VMS doesn't have `size_t' in , even though POSIX says it + should be there. */ +# include +#endif + +/* The following two types have to be signed and unsigned integer type + wide enough to hold a value of a pointer. For most ANSI compilers + ptrdiff_t and size_t should be likely OK. Still size of these two + types is 2 for Microsoft C. Ugh... */ +typedef long int s_reg_t; +typedef unsigned long int active_reg_t; + +/* The following bits are used to determine the regexp syntax we + recognize. The set/not-set meanings are chosen so that Emacs syntax + remains the value 0. The bits are given in alphabetical order, and + the definitions shifted by one from the previous bit; thus, when we + add or remove a bit, only one other definition need change. */ +typedef unsigned long int reg_syntax_t; + +/* If this bit is not set, then \ inside a bracket expression is literal. + If set, then such a \ quotes the following character. */ +#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) + +/* If this bit is not set, then + and ? are operators, and \+ and \? are + literals. + If set, then \+ and \? are operators and + and ? are literals. */ +#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) + +/* If this bit is set, then character classes are supported. They are: + [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], + [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. + If not set, then character classes are not supported. */ +#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) + +/* If this bit is set, then ^ and $ are always anchors (outside bracket + expressions, of course). + If this bit is not set, then it depends: + ^ is an anchor if it is at the beginning of a regular + expression or after an open-group or an alternation operator; + $ is an anchor if it is at the end of a regular expression, or + before a close-group or an alternation operator. + + This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because + POSIX draft 11.2 says that * etc. in leading positions is undefined. + We already implemented a previous draft which made those constructs + invalid, though, so we haven't changed the code back. */ +#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) + +/* If this bit is set, then special characters are always special + regardless of where they are in the pattern. + If this bit is not set, then special characters are special only in + some contexts; otherwise they are ordinary. Specifically, + * + ? and intervals are only special when not after the beginning, + open-group, or alternation operator. */ +#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) + +/* If this bit is set, then *, +, ?, and { cannot be first in an re or + immediately after an alternation or begin-group operator. */ +#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) + +/* If this bit is set, then . matches newline. + If not set, then it doesn't. */ +#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) + +/* If this bit is set, then . doesn't match NUL. + If not set, then it does. */ +#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) + +/* If this bit is set, nonmatching lists [^...] do not match newline. + If not set, they do. */ +#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) + +/* If this bit is set, either \{...\} or {...} defines an + interval, depending on RE_NO_BK_BRACES. + If not set, \{, \}, {, and } are literals. */ +#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) + +/* If this bit is set, +, ? and | aren't recognized as operators. + If not set, they are. */ +#define RE_LIMITED_OPS (RE_INTERVALS << 1) + +/* If this bit is set, newline is an alternation operator. + If not set, newline is literal. */ +#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) + +/* If this bit is set, then `{...}' defines an interval, and \{ and \} + are literals. + If not set, then `\{...\}' defines an interval. */ +#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) + +/* If this bit is set, (...) defines a group, and \( and \) are literals. + If not set, \(...\) defines a group, and ( and ) are literals. */ +#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) + +/* If this bit is set, then \ matches . + If not set, then \ is a back-reference. */ +#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) + +/* If this bit is set, then | is an alternation operator, and \| is literal. + If not set, then \| is an alternation operator, and | is literal. */ +#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) + +/* If this bit is set, then an ending range point collating higher + than the starting range point, as in [z-a], is invalid. + If not set, then when ending range point collates higher than the + starting range point, the range is ignored. */ +#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) + +/* If this bit is set, then an unmatched ) is ordinary. + If not set, then an unmatched ) is invalid. */ +#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) + +/* If this bit is set, succeed as soon as we match the whole pattern, + without further backtracking. */ +#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) + +/* If this bit is set, do not process the GNU regex operators. + If not set, then the GNU regex operators are recognized. */ +#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) + +/* If this bit is set, turn on internal regex debugging. + If not set, and debugging was on, turn it off. + This only works if regex.c is compiled -DDEBUG. + We define this bit always, so that all that's needed to turn on + debugging is to recompile regex.c; the calling code can always have + this bit set, and it won't affect anything in the normal case. */ +#define RE_DEBUG (RE_NO_GNU_OPS << 1) + +/* This global variable defines the particular regexp syntax to use (for + some interfaces). When a regexp is compiled, the syntax used is + stored in the pattern buffer, so changing this does not affect + already-compiled regexps. */ +extern reg_syntax_t re_syntax_options; + +/* Define combinations of the above bits for the standard possibilities. + (The [[[ comments delimit what gets put into the Texinfo file, so + don't delete them!) */ +/* [[[begin syntaxes]]] */ +#define RE_SYNTAX_EMACS 0 + +#define RE_SYNTAX_AWK \ + (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ + | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ + | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) + +#define RE_SYNTAX_GNU_AWK \ + ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ + & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS)) + +#define RE_SYNTAX_POSIX_AWK \ + (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ + | RE_INTERVALS | RE_NO_GNU_OPS) + +#define RE_SYNTAX_GREP \ + (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ + | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ + | RE_NEWLINE_ALT) + +#define RE_SYNTAX_EGREP \ + (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ + | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ + | RE_NO_BK_VBAR) + +#define RE_SYNTAX_POSIX_EGREP \ + (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) + +/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ +#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC + +#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC + +/* Syntax bits common to both basic and extended POSIX regex syntax. */ +#define _RE_SYNTAX_POSIX_COMMON \ + (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ + | RE_INTERVALS | RE_NO_EMPTY_RANGES) + +#define RE_SYNTAX_POSIX_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) + +/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes + RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this + isn't minimal, since other operators, such as \`, aren't disabled. */ +#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) + +#define RE_SYNTAX_POSIX_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ + | RE_UNMATCHED_RIGHT_PAREN_ORD) + +/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS + replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ +#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ + (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ + | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ + | RE_NO_BK_PARENS | RE_NO_BK_REFS \ + | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) +/* [[[end syntaxes]]] */ + +/* Maximum number of duplicates an interval can allow. Some systems + (erroneously) define this in other header files, but we want our + value, so remove any previous define. */ +#ifdef RE_DUP_MAX +# undef RE_DUP_MAX +#endif +/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ +#define RE_DUP_MAX (0x7fff) + + +/* POSIX `cflags' bits (i.e., information for `regcomp'). */ + +/* If this bit is set, then use extended regular expression syntax. + If not set, then use basic regular expression syntax. */ +#define REG_EXTENDED 1 + +/* If this bit is set, then ignore case when matching. + If not set, then case is significant. */ +#define REG_ICASE (REG_EXTENDED << 1) + +/* If this bit is set, then anchors do not match at newline + characters in the string. + If not set, then anchors do match at newlines. */ +#define REG_NEWLINE (REG_ICASE << 1) + +/* If this bit is set, then report only success or fail in regexec. + If not set, then returns differ between not matching and errors. */ +#define REG_NOSUB (REG_NEWLINE << 1) + + +/* POSIX `eflags' bits (i.e., information for regexec). */ + +/* If this bit is set, then the beginning-of-line operator doesn't match + the beginning of the string (presumably because it's not the + beginning of a line). + If not set, then the beginning-of-line operator does match the + beginning of the string. */ +#define REG_NOTBOL 1 + +/* Like REG_NOTBOL, except for the end-of-line. */ +#define REG_NOTEOL (1 << 1) + + +/* If any error codes are removed, changed, or added, update the + `re_error_msg' table in regex.c. */ +typedef enum +{ +#ifdef _XOPEN_SOURCE + REG_ENOSYS = -1, /* This will never happen for this implementation. */ +#endif + + REG_NOERROR = 0, /* Success. */ + REG_NOMATCH, /* Didn't find a match (for regexec). */ + + /* POSIX regcomp return error codes. (In the order listed in the + standard.) */ + REG_BADPAT, /* Invalid pattern. */ + REG_ECOLLATE, /* Not implemented. */ + REG_ECTYPE, /* Invalid character class name. */ + REG_EESCAPE, /* Trailing backslash. */ + REG_ESUBREG, /* Invalid back reference. */ + REG_EBRACK, /* Unmatched left bracket. */ + REG_EPAREN, /* Parenthesis imbalance. */ + REG_EBRACE, /* Unmatched \{. */ + REG_BADBR, /* Invalid contents of \{\}. */ + REG_ERANGE, /* Invalid range end. */ + REG_ESPACE, /* Ran out of memory. */ + REG_BADRPT, /* No preceding re for repetition op. */ + + /* Error codes we've added. */ + REG_EEND, /* Premature end. */ + REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ + REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ +} reg_errcode_t; + +/* This data structure represents a compiled pattern. Before calling + the pattern compiler, the fields `buffer', `allocated', `fastmap', + `translate', and `no_sub' can be set. After the pattern has been + compiled, the `re_nsub' field is available. All other fields are + private to the regex routines. */ + +#ifndef RE_TRANSLATE_TYPE +# define RE_TRANSLATE_TYPE char * +#endif + +struct re_pattern_buffer +{ +/* [[[begin pattern_buffer]]] */ + /* Space that holds the compiled pattern. It is declared as + `unsigned char *' because its elements are + sometimes used as array indexes. */ + unsigned char *buffer; + + /* Number of bytes to which `buffer' points. */ + unsigned long int allocated; + + /* Number of bytes actually used in `buffer'. */ + unsigned long int used; + + /* Syntax setting with which the pattern was compiled. */ + reg_syntax_t syntax; + + /* Pointer to a fastmap, if any, otherwise zero. re_search uses + the fastmap, if there is one, to skip over impossible + starting points for matches. */ + char *fastmap; + + /* Either a translate table to apply to all characters before + comparing them, or zero for no translation. The translation + is applied to a pattern when it is compiled and to a string + when it is matched. */ + RE_TRANSLATE_TYPE translate; + + /* Number of subexpressions found by the compiler. */ + size_t re_nsub; + + /* Zero if this pattern cannot match the empty string, one else. + Well, in truth it's used only in `re_search_2', to see + whether or not we should use the fastmap, so we don't set + this absolutely perfectly; see `re_compile_fastmap' (the + `duplicate' case). */ + unsigned can_be_null : 1; + + /* If REGS_UNALLOCATED, allocate space in the `regs' structure + for `max (RE_NREGS, re_nsub + 1)' groups. + If REGS_REALLOCATE, reallocate space if necessary. + If REGS_FIXED, use what's there. */ +#define REGS_UNALLOCATED 0 +#define REGS_REALLOCATE 1 +#define REGS_FIXED 2 + unsigned regs_allocated : 2; + + /* Set to zero when `regex_compile' compiles a pattern; set to one + by `re_compile_fastmap' if it updates the fastmap. */ + unsigned fastmap_accurate : 1; + + /* If set, `re_match_2' does not return information about + subexpressions. */ + unsigned no_sub : 1; + + /* If set, a beginning-of-line anchor doesn't match at the + beginning of the string. */ + unsigned not_bol : 1; + + /* Similarly for an end-of-line anchor. */ + unsigned not_eol : 1; + + /* If true, an anchor at a newline matches. */ + unsigned newline_anchor : 1; + +/* [[[end pattern_buffer]]] */ +}; + +typedef struct re_pattern_buffer regex_t; + +/* Type for byte offsets within the string. POSIX mandates this. */ +typedef int regoff_t; + + +/* This is the structure we store register match data in. See + regex.texinfo for a full description of what registers match. */ +struct re_registers +{ + unsigned num_regs; + regoff_t *start; + regoff_t *end; +}; + + +/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, + `re_match_2' returns information about at least this many registers + the first time a `regs' structure is passed. */ +#ifndef RE_NREGS +# define RE_NREGS 30 +#endif + + +/* POSIX specification for registers. Aside from the different names than + `re_registers', POSIX uses an array of structures, instead of a + structure of arrays. */ +typedef struct +{ + regoff_t rm_so; /* Byte offset from string's start to substring's start. */ + regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ +} regmatch_t; + +/* Declarations for routines. */ + +/* To avoid duplicating every routine declaration -- once with a + prototype (if we are ANSI), and once without (if we aren't) -- we + use the following macro to declare argument types. This + unfortunately clutters up the declarations a bit, but I think it's + worth it. */ + +#if __STDC__ + +# define _RE_ARGS(args) args + +#else /* not __STDC__ */ + +# define _RE_ARGS(args) () + +#endif /* not __STDC__ */ + +/* Sets the current default syntax to SYNTAX, and return the old syntax. + You can also simply assign to the `re_syntax_options' variable. */ +extern reg_syntax_t __re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); +extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); + +/* Compile the regular expression PATTERN, with length LENGTH + and syntax given by the global `re_syntax_options', into the buffer + BUFFER. Return NULL if successful, and an error string if not. */ +extern const char *__re_compile_pattern + _RE_ARGS ((const char *pattern, size_t length, + struct re_pattern_buffer *buffer)); +extern const char *re_compile_pattern + _RE_ARGS ((const char *pattern, size_t length, + struct re_pattern_buffer *buffer)); + + +/* Compile a fastmap for the compiled pattern in BUFFER; used to + accelerate searches. Return 0 if successful and -2 if was an + internal error. */ +extern int __re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); +extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); + + +/* Search in the string STRING (with length LENGTH) for the pattern + compiled into BUFFER. Start searching at position START, for RANGE + characters. Return the starting position of the match, -1 for no + match, or -2 for an internal error. Also return register + information in REGS (if REGS and BUFFER->no_sub are nonzero). */ +extern int __re_search + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, int range, struct re_registers *regs)); +extern int re_search + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, int range, struct re_registers *regs)); + + +/* Like `re_search', but search in the concatenation of STRING1 and + STRING2. Also, stop searching at index START + STOP. */ +extern int __re_search_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, int range, struct re_registers *regs, int stop)); +extern int re_search_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, int range, struct re_registers *regs, int stop)); + + +/* Like `re_search', but return how many characters in STRING the regexp + in BUFFER matched, starting at position START. */ +extern int __re_match + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, struct re_registers *regs)); +extern int re_match + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, + int length, int start, struct re_registers *regs)); + + +/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ +extern int __re_match_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, struct re_registers *regs, int stop)); +extern int re_match_2 + _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, + int length1, const char *string2, int length2, + int start, struct re_registers *regs, int stop)); + + +/* Set REGS to hold NUM_REGS registers, storing them in STARTS and + ENDS. Subsequent matches using BUFFER and REGS will use this memory + for recording register information. STARTS and ENDS must be + allocated with malloc, and must each be at least `NUM_REGS * sizeof + (regoff_t)' bytes long. + + If NUM_REGS == 0, then subsequent matches should allocate their own + register data. + + Unless this function is called, the first search or match using + PATTERN_BUFFER will allocate its own register data, without + freeing the old data. */ +extern void __re_set_registers + _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, + unsigned num_regs, regoff_t *starts, regoff_t *ends)); +extern void re_set_registers + _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, + unsigned num_regs, regoff_t *starts, regoff_t *ends)); + +#ifdef _REGEX_RE_COMP +# ifndef _CRAY +/* 4.2 bsd compatibility. */ +extern char *re_comp _RE_ARGS ((const char *)); +extern int re_exec _RE_ARGS ((const char *)); +# endif +#endif + +/* POSIX compatibility. */ +extern int __regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, + int __cflags)); +extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, + int __cflags)); + +extern int __regexec _RE_ARGS ((const regex_t *__preg, + const char *__string, size_t __nmatch, + regmatch_t __pmatch[], int __eflags)); +extern int regexec _RE_ARGS ((const regex_t *__preg, + const char *__string, size_t __nmatch, + regmatch_t __pmatch[], int __eflags)); + +extern size_t __regerror _RE_ARGS ((int __errcode, const regex_t *__preg, + char *__errbuf, size_t __errbuf_size)); +extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, + char *__errbuf, size_t __errbuf_size)); + +extern void __regfree _RE_ARGS ((regex_t *__preg)); +extern void regfree _RE_ARGS ((regex_t *__preg)); + + +#ifdef __cplusplus +} +#endif /* C++ */ + +#endif /* regex.h */ + +/* +Local variables: +make-backup-files: t +version-control: t +trim-versions-without-asking: nil +End: +*/ diff --git a/goldlib/gmb3/Makefile b/goldlib/gmb3/Makefile new file mode 100644 index 0000000..4e243e4 --- /dev/null +++ b/goldlib/gmb3/Makefile @@ -0,0 +1,13 @@ +# -*- makefile -*- + +TOP=../.. +TARGET=gmb3 +INCS=-I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg -I$(TOP)/goldlib/gmb3 + +include $(TOP)/GNUmakef.inc +ifeq ($(PLATFORM),emx) +ifeq ($(AR),emxomfar) +AR += -p32 +endif +endif +include $(TOP)/GNUmakef.lib diff --git a/goldlib/gmb3/gmb3.all b/goldlib/gmb3/gmb3.all new file mode 100644 index 0000000..9809883 --- /dev/null +++ b/goldlib/gmb3/gmb3.all @@ -0,0 +1,67 @@ + +## ------------------------------------------------------------------ +## The Goldware Library. Copyright (C) Odinn Sorensen. +## ------------------------------------------------------------------ +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## ------------------------------------------------------------------ +## $Id$ +## ------------------------------------------------------------------ +## Master build file. +## ------------------------------------------------------------------ + +## Msgbase source for GoldED 3.xx +gmoarea cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmohuds cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmoezyc1 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmoezyc2 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmoezyc3 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmoezyc4 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmoezyc5 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmofido1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmofido2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmofido3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmofido4 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmofido5 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmojamm1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmojamm2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmojamm3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmojamm4 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmojamm5 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmopcbd1 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmopcbd2 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmopcbd3 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmopcbd4 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmopcbd5 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosmb1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosmb2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosmb3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosqsh1 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosqsh2 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosqsh3 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosqsh4 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmosqsh5 cpp all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +gmowcat1 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmowcat2 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmowcat3 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmowcat4 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmowcat5 cpp all nov bco bcx wcn wco wcx lnx emx djg rsx cyg +gmoxbbs1 cpp all nov bco wco emx +gmoxbbs2 cpp all nov bco wco emx +gmoxbbs3 cpp all nov bco wco emx +gmoxbbs4 cpp all nov bco wco emx +gmoxbbs5 cpp all nov bco wco emx + +## ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmo_msg.h b/goldlib/gmb3/gmo_msg.h new file mode 100644 index 0000000..22e5716 --- /dev/null +++ b/goldlib/gmb3/gmo_msg.h @@ -0,0 +1,321 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Message structures and classes. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#ifndef __GMB_MSG_H +#define __GMB_MSG_H + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// Internet name typedefs + +typedef char INam[128]; + + +// ------------------------------------------------------------------ +// Internet subject typedefs + +typedef char ISub[1301]; + + +// ------------------------------------------------------------------ +// Message modes + +const uint GMSG_HDR = 0x0001; +const uint GMSG_TXT = 0x0002; +const uint GMSG_HDRTXT = 0x0003; // GMSG_HDR|GMSG_TXT +const uint GMSG_NEW = 0x0010; +const uint GMSG_UPDATE = 0x0020; +const uint GMSG_DELETE = 0x0040; +const uint GMSG_COPY = 0x0080; +const uint GMSG_MOVE = 0x0100; +const uint GMSG_UNS_NOT_RCV = 0x0200; +const uint GMSG_NOLSTUPD = 0x8000; + + +// ------------------------------------------------------------------ +// Line attributes + +const uint GLINE_TEAR = 0x0001; +const uint GLINE_ORIG = 0x0002; +const uint GLINE_HIDD = 0x0004; +const uint GLINE_KLUD = 0x0008; +const uint GLINE_QUOT = 0x0010; +const uint GLINE_HARD = 0x0020; +const uint GLINE_WRAP = 0x0040; +const uint GLINE_BLOK = 0x0080; +const uint GLINE_POSI = 0x0100; +const uint GLINE_HIGH = 0x0200; +const uint GLINE_TAGL = 0x0400; +const uint GLINE_SIGN = 0x0800; +const uint GLINE_NOAL = 0x1000; // text is not allocated + +const uint GLINE_KLUDGE = GLINE_HIDD | GLINE_KLUD; +const uint GLINE_ALL = GLINE_HIDD | GLINE_KLUD | GLINE_QUOT; + + +// ------------------------------------------------------------------ +// Kludge types + +const uint GKLUD_INTL = 0x0001; +const uint GKLUD_FMPT = 0x0002; +const uint GKLUD_TOPT = 0x0004; +const uint GKLUD_FLAGS = 0x0008; +const uint GKLUD_AREA = 0x0010; +const uint GKLUD_MSGID = 0x0020; +const uint GKLUD_REPLY = 0x0040; +const uint GKLUD_PID = 0x0080; +const uint GKLUD_FWD = 0x0100; +const uint GKLUD_PATH = 0x0200; +const uint GKLUD_SEENBY = 0x0400; +const uint GKLUD_CHARSET = 0x0800; +const uint GKLUD_REPLYTO = 0x1000; +const uint GKLUD_REPLYADDR = 0x2000; +const uint GKLUD_KNOWN = 0x4000; +const uint GKLUD_RFC = 0x8000; + + +// ------------------------------------------------------------------ +// Search locations + +const uint GFIND_FROM = 0x0001; +const uint GFIND_TO = 0x0002; +const uint GFIND_SUBJECT = 0x0004; +const uint GFIND_BODY = 0x0008; +const uint GFIND_TAGLINE = 0x0010; +const uint GFIND_TEARLINE = 0x0020; +const uint GFIND_ORIGIN = 0x0040; +const uint GFIND_KLUDGES = 0x0080; +const uint GFIND_SIGNATURE = 0x0100; +const uint GFIND_HDR = GFIND_FROM | GFIND_TO | GFIND_SUBJECT; +const uint GFIND_HDRTXT = GFIND_HDR | GFIND_BODY; + + +// ------------------------------------------------------------------ +// Charset encoding formats + +const int GCHENC_CMP = 0x0001; // Composed characters +const int GCHENC_I51 = 0x0002; // FSC-51 +const int GCHENC_MNE = 0x0004; // K.Simonsen Mnemonic +const int GCHENC_QP = 0x0008; // Quoted-Printable + + +// ------------------------------------------------------------------ +// Line record + +class Line { + +public: + + int color; // Line color + uint type; // GLINE_* + uint kludge; // GKLUD_* + char* text; // Pointer to the line text + Line* prev; // Pointer to previous line + Line* next; // Pointer to next line + + int istearline() { return !!(type & GLINE_TEAR); } + int isorigin() { return !!(type & GLINE_ORIG); } + int ishidden() { return !!(type & GLINE_HIDD); } + int iskludge() { return !!(type & GLINE_KLUD); } + int isquote() { return !!(type & GLINE_QUOT); } + int ishard() { return !!(type & GLINE_HARD); } + int iswrapped() { return !!(type & GLINE_WRAP); } + int isblock() { return !!(type & GLINE_BLOK); } + int isposition() { return !!(type & GLINE_POSI); } + int ishighlighted() { return !!(type & GLINE_HIGH); } + int istagline() { return !!(type & GLINE_TAGL); } + int isheader() { return !!kludge; } + + int isallocated() { return !(type & GLINE_NOAL); } +}; + + +// ------------------------------------------------------------------ + +Line* AddLineF(Line*& line, const char* format, ...) __attribute__ ((format (printf, 2, 3))); +Line* AddLine(Line* line, char* buf); +Line* AddHexdump(Line*& line, void* data, size_t datalen); + + +// ------------------------------------------------------------------ + +class gmsg_links { + +private: + + enum { list_limit = 29 }; + + ulong reply_to; + ulong reply_first; + ulong reply_list[list_limit]; + ulong reply_next; + +public: + + void reset() { + reply_to = reply_first = reply_next = 0; + for(int n=0; n + + +// ------------------------------------------------------------------ + +glog* WideLog = NULL; +int WideDebug = false; +int WideCanLock = true; +const char** WideUsername = NULL; +int WideUsernames = 0; +uint WideSharemode = SH_DENYNO; +int WideDispsoftcr = false; +int WidePersonalmail = 0; + +#if defined(GOLD_16BIT) +long WideMsgSize = 64000L; +#else +long WideMsgSize = 512000L; +#endif + + +// ------------------------------------------------------------------ + +gmo_area::gmo_area() : cfg(), cfg2() { + + Msgn = NULL; + PMrk = NULL; + lastread = 0; + lastreadentry = 0; + isopen = false; +} + + +// ------------------------------------------------------------------ + +gmo_area::~gmo_area() { + +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoarea.h b/goldlib/gmb3/gmoarea.h new file mode 100644 index 0000000..c3748e6 --- /dev/null +++ b/goldlib/gmb3/gmoarea.h @@ -0,0 +1,290 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Area structures and classes. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#ifndef __GMBAREA_H +#define __GMBAREA_H + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ +// Area base class + +class gmo_area { + +public: + + // ---------------------------------------------------------------- + // Config data + + AreaCfgBase cfg; + GStrSet3 cfg2; + + + // ---------------------------------------------------------------- + // Constructor and destructor + + gmo_area(); + virtual ~gmo_area(); + + + // ---------------------------------------------------------------- + // Data members + + GTag* Msgn; // Message numbers + GTag* PMrk; // Personal mail marks + + uint lastread; // Number of last message read + ulong lastreadentry; // Lastread message number at entry to area + + int isopen; // NONZERO if open + + + // ---------------------------------------------------------------- + // Access config data + + int areaid() const { return cfg.areaid; } + int groupid() const { return cfg.groupid; } + uint type() const { return cfg.type; } + uint msgbase() const { return cfg.msgbase; } + uint board() const { return cfg.board; } + const ftn_addr& aka() const { return cfg.aka; } + int originno() const { return cfg.originno; } + Attr& attr() { return cfg.attr; } + + bool ascan() { return (bool)cfg.scan; } + bool ascanexcl() { return (bool)cfg.scanexcl; } + bool ascanincl() { return (bool)cfg.scanincl; } + bool pmscan() { return (bool)cfg.pmscan; } + bool pmscanexcl() { return (bool)cfg.pmscanexcl; } + bool pmscanincl() { return (bool)cfg.pmscanincl; } + + const char* echoid() const { return cfg2.Get1(); } + const char* desc() const { return cfg2.Get2(); } + const char* path() const { return cfg2.Get3(); } + + void set_areaid(int a) { cfg.areaid = a; } + void set_groupid(int g) { cfg.groupid = g; } + void set_type(uint t) { cfg.type = t; } + void set_msgbase(uint m) { cfg.msgbase = m; } + void set_board(uint b) { cfg.board = b; } + void set_aka(ftn_addr& a) { cfg.aka = a; } + void set_originno(int o) { cfg.originno = o; } + void set_attr(Attr& a) { cfg.attr = a; } + void set_origin(char* o) { string tmp = o; cfg.setorigin(tmp); } + + void set_scan(bool s) { cfg.scan = (byte)s; } + void set_scanexcl(bool s) { cfg.scanexcl = (byte)s; } + void set_scanincl(bool s) { cfg.scanincl = (byte)s; } + void set_pmscan(bool s) { cfg.pmscan = (byte)s; } + void set_pmscanexcl(bool s) { cfg.pmscanexcl = (byte)s; } + void set_pmscanincl(bool s) { cfg.pmscanincl = (byte)s; } + + void set_echoid(const char* s) { cfg2.Change1(s); } + void set_desc(const char* s) { cfg2.Change2(s); } + void set_path(const char* s) { cfg2.Change3(s); } + + + // ---------------------------------------------------------------- + // Determine msgbase format + + int isfts1() const; + int isopus() const; + int isezycom() const; + int isfido() const; + int isgoldbase() const; + int ishudson() const; + int isjam() const; + int ispcboard() const; + int issquish() const; + int iswildcat() const; + int isadeptxbbs() const; + int isseparator() const; + + + // ---------------------------------------------------------------- + // Determine area type + + int isnet() const; + int isecho() const; + int islocal() const; + int isemail() const; + int isnewsgroup() const; + int isinternet() const; + int isqwk() const; + int issoup() const; + + + // ---------------------------------------------------------------- + // Low-level messagebase member functions + + virtual void open() = 0; + virtual void close() = 0; + + virtual void suspend() = 0; + virtual void resume() = 0; + + virtual void lock() = 0; + virtual void unlock() = 0; + + virtual void scan() = 0; + virtual void scan_area() = 0; + virtual void scan_area_pm() = 0; + + virtual int load_hdr(gmsg* msg) = 0; + virtual int load_msg(gmsg* msg) = 0; + + virtual void save_hdr(int mode, gmsg* msg) = 0; + virtual void save_msg(int mode, gmsg* msg) = 0; + + virtual void del_msg(gmsg* msg) = 0; + + virtual void new_msgno(gmsg* msg) = 0; + virtual char* user_lookup(char* lookfor) = 0; + virtual int renumber() = 0; + + virtual void update_timesread(gmsg* msg) = 0; + + virtual Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) = 0; + + virtual void set_highwater_mark() { } + virtual void reset_highwater_mark() { } +}; + + +// ------------------------------------------------------------------ +// Inline implementations + +inline int gmo_area::isfts1() const { return cfg.isfts1(); } +inline int gmo_area::isopus() const { return cfg.isopus(); } +inline int gmo_area::isezycom() const { return cfg.isezycom(); } +inline int gmo_area::isfido() const { return cfg.isfido(); } +inline int gmo_area::isgoldbase() const { return cfg.isgoldbase(); } +inline int gmo_area::ishudson() const { return cfg.ishudson(); } +inline int gmo_area::isjam() const { return cfg.isjam(); } +inline int gmo_area::ispcboard() const { return cfg.ispcboard(); } +inline int gmo_area::issquish() const { return cfg.issquish(); } +inline int gmo_area::iswildcat() const { return cfg.iswildcat(); } +inline int gmo_area::isadeptxbbs() const { return cfg.isadeptxbbs(); } +inline int gmo_area::isseparator() const { return cfg.isseparator(); } + +inline int gmo_area::isnet() const { return cfg.isnet(); } +inline int gmo_area::isecho() const { return cfg.isecho(); } +inline int gmo_area::islocal() const { return cfg.islocal(); } +inline int gmo_area::isemail() const { return cfg.isemail(); } +inline int gmo_area::isnewsgroup() const { return cfg.isnewsgroup(); } +inline int gmo_area::isinternet() const { return cfg.isinternet(); } +inline int gmo_area::isqwk() const { return cfg.isqwk(); } +inline int gmo_area::issoup() const { return cfg.issoup(); } + + +// ------------------------------------------------------------------ + +class SepArea : public gmo_area { + +public: + + SepArea() { } + virtual ~SepArea() { } + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open() { } + void close() { } + + void suspend() { } + void resume() { } + + void lock() { } + void unlock() { } + + void scan() { } + void scan_area() { } + void scan_area_pm() { } + + int load_hdr(gmsg*) { return 0; } + int load_msg(gmsg*) { return 0; } + + void save_hdr(int, gmsg*) { } + void save_msg(int, gmsg*) { } + + void del_msg(gmsg*) { } + + void new_msgno(gmsg*) { } + char* user_lookup(char*) { return NULL; } + int renumber() { return false; } + + void update_timesread(gmsg*) { } + + Line* make_dump_msg(Line*&, gmsg*, char*) { return NULL; } +}; + + +// ------------------------------------------------------------------ +// Personal mail + +const int PM_STARTUP = 0x0001; +const int PM_ALLNAMES = 0x0002; +const int PM_LISTONLY = 0x0004; + + +// ------------------------------------------------------------------ + +extern glog* WideLog; +extern int WideDebug; +extern int WideCanLock; +extern long WideMsgSize; +extern const char** WideUsername; +extern int WideUsernames; +extern uint WideSharemode; +extern int WideDispsoftcr; +extern int WidePersonalmail; + + +// ------------------------------------------------------------------ + +int PopupLocked(long __tries, int __isopen, const char* __file); + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoezyc.h b/goldlib/gmb3/gmoezyc.h new file mode 100644 index 0000000..191b263 --- /dev/null +++ b/goldlib/gmb3/gmoezyc.h @@ -0,0 +1,258 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom msgbase. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GMEZYC_H +#define __GMEZYC_H + + +// ------------------------------------------------------------------ + +#include +#include + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Ezycom constants + +#define EZYC_MAXNAME 36 +#define EZYC_MAXSUBJ 73 +#define EZYC_MAXMESS102 1024 +#define EZYC_MAXMESS110 1536 +#define EZYC_USERSBUF 100 + +#define EZYC_USERDELETED 0x0001 + + +// ------------------------------------------------------------------ + +const byte EZYC_MSGATTR_DELETED = 0x01; +const byte EZYC_MSGATTR_NETPEND = 0x02; +const byte EZYC_MSGATTR_RESERVED = 0x04; +const byte EZYC_MSGATTR_PRIVATE = 0x08; +const byte EZYC_MSGATTR_RECEIVED = 0x10; +const byte EZYC_MSGATTR_ECHOPEND = 0x20; +const byte EZYC_MSGATTR_LOCAL = 0x40; +const byte EZYC_MSGATTR_NOKILL = 0x80; + +const byte EZYC_NETATTR_KILLSENT = 0x01; +const byte EZYC_NETATTR_SENT = 0x02; +const byte EZYC_NETATTR_ATTACH = 0x04; +const byte EZYC_NETATTR_CRASH = 0x08; +const byte EZYC_NETATTR_FREQ = 0x10; +const byte EZYC_NETATTR_RREQ = 0x20; +const byte EZYC_NETATTR_AREQ = 0x40; +const byte EZYC_NETATTR_RREC = 0x80; + +const byte EZYC_EXTATTR_RSVD1 = 0x01; +const byte EZYC_EXTATTR_RSVD2 = 0x02; +const byte EZYC_EXTATTR_RSVD3 = 0x04; +const byte EZYC_EXTATTR_RSVD4 = 0x08; +const byte EZYC_EXTATTR_RSVD5 = 0x10; +const byte EZYC_EXTATTR_RSVD6 = 0x20; +const byte EZYC_EXTATTR_RSVD7 = 0x40; +const byte EZYC_EXTATTR_SEEN = 0x80; + + +// ------------------------------------------------------------------ +// Ezycom message header + +struct EzycHdr { + + word replyto; + word reply1st; + + ulong startposition; + ulong messagelength; + + Addr destnet; + Addr orignet; + + word cost; // redefine to replynext? + + byte msgattr; + byte netattr; + byte extattr; + + FTime posttimedate; + FTime recvtimedate; + + char whoto[EZYC_MAXNAME]; + char whofrom[EZYC_MAXNAME]; + char subject[EZYC_MAXSUBJ]; +}; + + +// ------------------------------------------------------------------ +// Ezycom LASTCOMB.BBS record structure + +struct EzycLast { + word combinedinfo; + word lastreadinfo[16]; +}; + + +// ------------------------------------------------------------------ +// Ezycom MSGFAST.BBS record structure + +struct EzycFast { + dword whoto; // 32 bit CRC on WhoTo in MSGHxxx.BBS + word msgboard; + word msgnumber; +}; + + +// ------------------------------------------------------------------ +// Ezycom MSGDLTD.BBS record + +struct EzycDeleted { + word msgboard; + word msgnumber; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct EzycData { + int fhhdr; + int fhtxt; + int fhnow; + int omode; + int smode; + int timesposted; + int islocked; + Path ezyfile; +}; + + +// ------------------------------------------------------------------ + +struct EzycWide { + int ver; + EzycomUser* user; + int userno; + int maxmess; + const char* msgbasepath; + const char* userbasepath; +}; + + +// ------------------------------------------------------------------ + +class EzycomArea : public gmo_area { + +protected: + + EzycWide* wide; + EzycData* data; + + void data_open(); + void data_close(); + + char* ret_mess_xxx(char* __path, byte __type); + char* ret_mess_area(char* __path); + + int raw_open(); + + void test_raw_open(int __fileline); + void raw_close(); + int test_open(const char* __file, int __mode, int __share); + + void save_lastread(); + + void raw_scan(int __keep_index); + + int load_message(int __mode, gmsg* __msg, EzycHdr& __hdr); + void save_message(int __mode, gmsg* __msg, EzycHdr& __hdr); + + +public: + + EzycomArea() { wide = NULL; data = NULL; } + virtual ~EzycomArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern EzycWide* ezycomwide; +extern EzycData* ezycomdata; +extern int ezycomdatano; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoezyc1.cpp b/goldlib/gmb3/gmoezyc1.cpp new file mode 100644 index 0000000..0c85b19 --- /dev/null +++ b/goldlib/gmb3/gmoezyc1.cpp @@ -0,0 +1,440 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom msgbase handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +EzycWide* ezycomwide = NULL; +EzycData* ezycomdata = NULL; +int ezycomdatano = 0; + + +// ------------------------------------------------------------------ + +void EzycomArea::data_open() { + + wide = ezycomwide; + data = ezycomdata + (ezycomdatano++); + data->fhhdr = data->fhtxt = data->fhnow = -1; + data->omode = O_RDONLY; + data->smode = SH_DENYNO; + data->timesposted = 0; +} + + +// ------------------------------------------------------------------ + +void EzycomArea::data_close() { + + ezycomdatano--; +} + + +// ------------------------------------------------------------------ + +char* EzycomArea::ret_mess_xxx(char* __path, byte __type) { + + if(wide->ver >= 110) { + sprintf(__path, "%sAREA%u\\M%c%05u.BBS", + wide->msgbasepath, + ((board()-1) / 100) + 1, + (__type == 1) ? 'H' : 'T', + board() + ); + } + else { + sprintf(__path, "%sAREA%u\\MSG%c%03u.BBS", + wide->msgbasepath, + ((board()-1) / 100) + 1, + (__type == 1) ? 'H' : 'T', + (board() > 999) ? board()/10 : board() + ); + } + return __path; +} + + +// ------------------------------------------------------------------ + +char* EzycomArea::ret_mess_area(char* __path) { + + sprintf(__path, "%sAREA%u", + wide->msgbasepath, + ((board()-1) / 100) + 1 + ); + return __path; +} + + +// ------------------------------------------------------------------ + +void EzycomArea::raw_close() { + + GFTRK("EzycomRawClose"); + + if(data->fhhdr != -1) ::close(data->fhhdr); data->fhhdr = -1; + if(data->fhtxt != -1) ::close(data->fhtxt); data->fhtxt = -1; + if(data->fhnow != -1) ::close(data->fhnow); data->fhnow = -1; + if(data->omode == O_WRONLY) + remove(AddPath(wide->msgbasepath, "EZYMSG.NOW")); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +int EzycomArea::test_open(const char* __file, int __mode, int __share) { + + GFTRK("EzycomTestOpen"); + + int _fh; + long _tries = 0; + Path _path; + strcpy(_path, __file); + + do { + + _fh = ::sopen(_path, __mode, __share, S_STDRW); + if(_fh == -1) { + + // Tell the world + if(PopupLocked(++_tries, false, _path) == false) { + WideLog->ErrOpen(); + raw_close(); + WideLog->printf("! A Ezycom msgbase file could not be opened."); + WideLog->printf(": %s.", _path); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +int EzycomArea::raw_open() { + + GFTRK("EzycomRawOpen"); + + int _tryagain = 0; + + do { + + int _sopen_access = data->omode | O_BINARY; + int _sopen_permit = 0; + + if(NOT fexist(ret_mess_xxx(data->ezyfile,1))) { + _sopen_access |= O_CREAT; + _sopen_permit = S_STDRW; + } + + ret_mess_xxx(data->ezyfile, 1); + data->fhhdr = ::sopen(data->ezyfile, _sopen_access, data->smode, _sopen_permit); + if(data->fhhdr != -1) { + ret_mess_xxx(data->ezyfile, 2); + data->fhtxt = ::sopen(data->ezyfile, _sopen_access, data->smode, _sopen_permit); + if(data->fhtxt != -1) { + if(data->omode == O_WRONLY) { + + // Create semaphore file + byte _sema = 0; + data->fhnow = ::sopen(AddPath(wide->msgbasepath, "EZYMSG.NOW"), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, WideSharemode, S_STDRW); + write(data->fhnow, &_sema, 1); // Write some dummy data + } + + GFTRK(NULL); + return true; + } + } + raw_close(); + if(fexist(AddPath(wide->msgbasepath, "EZYMSG.NOW"))) { + errno = EACCES; + break; + } + Path _path; + if(NOT is_dir(ret_mess_area(_path))) { + mkdir(ret_mess_area(_path), S_IWUSR); + _tryagain++; + } + } while(_tryagain == 1); + + GFTRK(NULL); + + return false; +} + + +// ------------------------------------------------------------------ + +void EzycomArea::test_raw_open(int __fileline) { + + GFTRK("EzycomTestRawOpen"); + + int _isopen; + long _tries = 0; + + do { + + _isopen = raw_open(); + + if(NOT _isopen) { + + // Tell the world + if((errno != EACCES) OR PopupLocked(++_tries, false, data->ezyfile) == false) { + + // User requested to exit + WideLog->erropen(__FILE__, __fileline); + WideLog->printf("! A Ezycom msgbase file could not be opened."); + WideLog->printf(": %s.", data->ezyfile); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(NOT _isopen); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomExit() { + + if(ezycomwide) + delete ezycomwide->user; + throw_xrelease(ezycomwide); + throw_xrelease(ezycomdata); +} + + +// ------------------------------------------------------------------ + +void EzycomInit(const char* msgbasepath, const char* userbasepath, int userno) { + + ezycomdata = (EzycData*)throw_calloc(2, sizeof(EzycData)); + ezycomwide = (EzycWide*)throw_calloc(1, sizeof(EzycWide)); + + ezycomwide->msgbasepath = msgbasepath; + ezycomwide->userbasepath = userbasepath; + ezycomwide->userno = userno; + + Path _path; + *_path = NUL; + char* _ptr = getenv("EZY"); + if(_ptr AND *_ptr) { + _ptr = strcpy(_path, _ptr); + char* _ptr2 = strchr(_ptr, ' '); + if(_ptr2) + *_ptr2 = NUL; + AddBackslash(_path); + } + const char* _file = ""; + _ptr = getenv("TASK"); + if(_ptr AND *_ptr) { + char _tmp[20]; + sprintf(_tmp, "CONFIG.%u", atoi(_ptr)); + _file = AddPath(_path, _tmp); + } + if(NOT fexist(_file)) + _file = AddPath(_path, "CONFIG.EZY"); + + ezycomwide->ver = 102; + ezycomwide->maxmess = EZYC_MAXMESS102; + int _fh = ::sopen(_file, O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(_fh != -1) { + char _verstr[9]; + read(_fh, _verstr, 9); + close(_fh); + strp2c(_verstr); + if(strnicmp(_verstr, "1.10", 4) >= 0) { + ezycomwide->ver = 110; + ezycomwide->maxmess = EZYC_MAXMESS110; + } + } + + ezycomwide->user = new EzycomUser; + throw_new(ezycomwide->user); + + const char* _username = WideUsername[0]; + ezycomwide->user->ver = ezycomwide->ver; + if(ezycomwide->userno == -1) { + ezycomwide->user->fh = ::sopen(AddPath(ezycomwide->userbasepath, "USERS.BBS"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(ezycomwide->user->fh != -1) { + ezycomwide->user->extfh = ::sopen(AddPath(ezycomwide->userbasepath, "USERSEXT.BBS"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(ezycomwide->user->extfh != -1) { + ezycomwide->user->find(_username); + if(NOT ezycomwide->user->found) { + WideLog->printf("* User \"%s\" not found in %sUSERS.BBS.", _username, ezycomwide->userbasepath); + ezycomwide->user->add(_username); + WideLog->printf("* Now added with user number %u.", ezycomwide->user->index); + } + close(ezycomwide->user->extfh); + } + close(ezycomwide->user->fh); + } + ezycomwide->userno = ezycomwide->user->index; + } +} + + +// ------------------------------------------------------------------ + +void EzycomArea::open() { + + GFTRK("EzycomOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a Ezycom msgbase more than twice."); + WideLog->printf(": %s, board %u.", echoid(), board()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + test_raw_open(__LINE__); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::save_lastread() { + + GFTRK("EzycomSaveLastread"); + + int _fh = test_open(AddPath(wide->userbasepath, "LASTCOMB.BBS"), O_RDWR|O_CREAT|O_BINARY, SH_DENYNO); + if(_fh != -1) { + word _lastread = (word)(Msgn->CvtReln(lastread)+1); + lseekset(_fh, (long)wide->userno * ((long)wide->maxmess / 16) * (long)sizeof(EzycLast) + + (((board() - 1) / 16) * sizeof(EzycLast) + sizeof(word)) + + (board()-1) % 16 * sizeof(word) + ); + write(_fh, &_lastread, sizeof(word)); + ::close(_fh); + } + + if(data->timesposted) { + wide->user->extfh = ::sopen(AddPath(wide->userbasepath, "USERSEXT.BBS"), O_RDWR|O_BINARY, SH_DENYNO, S_STDRW); + if(wide->user->extfh != -1) { + wide->user->moveto(wide->userno); + wide->user->inctimesposted(data->timesposted); + data->timesposted = 0; + ::close(wide->user->extfh); + } + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::close() { + + GFTRK("EzycomClose"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + raw_close(); + Msgn->Reset(); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed Ezycom msgbase."); + WideLog->printf(": %s, board %u.", echoid(), board()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::suspend() { + + GFTRK("EzycomSuspend"); + + save_lastread(); + raw_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::resume() { + + GFTRK("EzycomResume"); + if(NOT raw_open()) { + Path _path; + WideLog->ErrOpen(); + WideLog->printf("! A Ezycom msgbase file could not be opened."); + WideLog->printf(": %s.", ret_mess_xxx(_path, 1)); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmoezyc2.cpp b/goldlib/gmb3/gmoezyc2.cpp new file mode 100644 index 0000000..154eda5 --- /dev/null +++ b/goldlib/gmb3/gmoezyc2.cpp @@ -0,0 +1,153 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom msgbase handling +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +void EzycomArea::raw_scan(int __keep_index) { + + GFTRK("EzycomRawScan"); + + int _wasopen = isopen; + if(NOT _wasopen) { + isopen++; + data_open(); + test_raw_open(__LINE__); + } + + Msgn->Resize((uint)(filelength(data->fhhdr) / sizeof(EzycHdr))); + + for(uint _count=0; _countCount(); _count++) + Msgn->at(_count) = _count + 1; + + int _fh = ::sopen(AddPath(wide->userbasepath, "LASTCOMB.BBS"), O_RDONLY|O_BINARY, SH_DENYNO, S_STDRD); + if(_fh != -1) { + word _lastread; + lseekset(_fh, (long)wide->userno * ((long)wide->maxmess / 16) * (long)sizeof(EzycLast) + + (((board() - 1) / 16) * sizeof(EzycLast) + sizeof(word)) + + (board()-1) % 16 * sizeof(word) + ); + read(_fh, &_lastread, sizeof(word)); + if(_lastread) + _lastread--; + + register uint _active = Msgn->Count(); + register uint _count = 1; + register ulong* _msgnoptr = Msgn->tag; + register uint _lastread_reln = 0; + register ulong _firstmsgno = 0; + register ulong _lastmsgno = 0; + register ulong _lastreadfound = 0; + + if(_active) { + + _firstmsgno = Msgn->at(0); + _lastmsgno = Msgn->at(_active-1); + + while(1) { + + // Set lastread pointer + if((*_msgnoptr >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = *_msgnoptr; + _lastread_reln = _count - (*_msgnoptr != _lastread ? 1 : 0); + break; + } + if((++_count) > _active) + break; + _msgnoptr++; + } + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + + // Update area data + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + ::close(_fh); + } + + if(NOT __keep_index) + Msgn->Reset(); + + if(NOT _wasopen) { + raw_close(); + data_close(); + isopen--; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::scan() { + + GFTRK("EzycomScan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::scan_area() { + + GFTRK("EzycomScanArea"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::scan_area_pm() { + + GFTRK("EzycomScanArea*M"); + + scan_area(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmoezyc3.cpp b/goldlib/gmb3/gmoezyc3.cpp new file mode 100644 index 0000000..93217b0 --- /dev/null +++ b/goldlib/gmb3/gmoezyc3.cpp @@ -0,0 +1,132 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom msgbase handling +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +int EzycomArea::load_message(int __mode, gmsg* __msg, EzycHdr& __hdr) { + + // Load the header + memset(&__hdr, 0, sizeof(EzycHdr)); + lseekset(data->fhhdr, __msg->msgno-1, sizeof(EzycHdr)); + read(data->fhhdr, &__hdr, sizeof(EzycHdr)); + + // Convert header data + + __msg->link.to_set(__hdr.replyto); + __msg->link.first_set(__hdr.reply1st); + + __msg->cost = __hdr.cost; + + __msg->txtstart = __hdr.startposition; + __msg->txtlength = __hdr.messagelength; + + strnp2cc(__msg->by, __hdr.whofrom, EZYC_MAXNAME-1); + strnp2cc(__msg->to, __hdr.whoto, EZYC_MAXNAME-1); + strnp2cc(__msg->re, __hdr.subject, EZYC_MAXSUBJ-1); + + __msg->orig.zone = __msg->oorig.zone = __hdr.orignet.zone; + __msg->orig.net = __msg->oorig.net = __hdr.orignet.net; + __msg->orig.node = __msg->oorig.node = __hdr.orignet.node; + __msg->orig.point = __msg->oorig.point = __hdr.orignet.point; + + __msg->dest.zone = __msg->odest.zone = __hdr.destnet.zone; + __msg->dest.net = __msg->odest.net = __hdr.destnet.net; + __msg->dest.node = __msg->odest.node = __hdr.destnet.node; + __msg->dest.point = __msg->odest.point = __hdr.destnet.point; + + // Convert date and time + SwapWord32((long*)&__hdr.posttimedate); + SwapWord32((long*)&__hdr.recvtimedate); + __msg->written = FTimeToTime(&__hdr.posttimedate); + __msg->arrived = FTimeToTime(&__hdr.recvtimedate); + + // Convert attributes + __msg->attr.del(__hdr.msgattr & EZYC_MSGATTR_DELETED); + __msg->attr.pvt(__hdr.msgattr & EZYC_MSGATTR_PRIVATE); + __msg->attr.rcv(__hdr.msgattr & EZYC_MSGATTR_RECEIVED); + __msg->attr.loc(__hdr.msgattr & EZYC_MSGATTR_LOCAL); + __msg->attr.lok(__hdr.msgattr & EZYC_MSGATTR_NOKILL); + __msg->attr.k_s(__hdr.netattr & EZYC_NETATTR_KILLSENT); + __msg->attr.snt(__hdr.netattr & EZYC_NETATTR_SENT); + __msg->attr.att(__hdr.netattr & EZYC_NETATTR_ATTACH); + __msg->attr.cra(__hdr.netattr & EZYC_NETATTR_CRASH); + __msg->attr.frq(__hdr.netattr & EZYC_NETATTR_FREQ); + __msg->attr.rrq(__hdr.netattr & EZYC_NETATTR_RREQ); + __msg->attr.arq(__hdr.netattr & EZYC_NETATTR_AREQ); + __msg->attr.rrc(__hdr.netattr & EZYC_NETATTR_RREC); + __msg->attr.uns(((__hdr.msgattr & EZYC_MSGATTR_NETPEND) OR (__hdr.msgattr & EZYC_MSGATTR_ECHOPEND)) ? 1 : 0); + + __msg->ezycom.extattr = __hdr.extattr; + __msg->timesread = (__hdr.extattr & EZYC_EXTATTR_SEEN) ? 1 : 0; + + if(__mode & GMSG_TXT) { + + __msg->txt = (char*)throw_calloc(1, (uint)(__hdr.messagelength+256)); + lseekset(data->fhtxt, __hdr.startposition); + read(data->fhtxt, __msg->txt, (uint)__hdr.messagelength); + } + + GFTRK(NULL); + + return true; +} + + +// ------------------------------------------------------------------ + +int EzycomArea::load_hdr(gmsg* __msg) { + + GFTRK("EzycomLoadHdr"); + + EzycHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int EzycomArea::load_msg(gmsg* __msg) { + + GFTRK("EzycomLoadMsg"); + + EzycHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoezyc4.cpp b/goldlib/gmb3/gmoezyc4.cpp new file mode 100644 index 0000000..3c8c0f4 --- /dev/null +++ b/goldlib/gmb3/gmoezyc4.cpp @@ -0,0 +1,316 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom msgbase handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void EzycomArea::lock() { + + GFTRK("EzycomLock"); + + raw_close(); + data->omode = O_RDWR; + data->smode = SH_DENYWR; + test_raw_open(__LINE__); + data->islocked = true; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::unlock() { + + GFTRK("EzycomUnlock"); + + raw_close(); + data->omode = O_RDONLY; + data->smode = SH_DENYNO; + test_raw_open(__LINE__); + data->islocked = false; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::save_message(int __mode, gmsg* __msg, EzycHdr& __hdr) { + + int _was_locked = data->islocked; + if(NOT _was_locked) + lock(); + + if(__mode & GMSG_NEW) + __msg->msgno = (filelength(data->fhhdr) / sizeof(EzycHdr)) + 1; + + // Reset header + memset(&__hdr, 0, sizeof(EzycHdr)); + + // Convert attributes + __hdr.msgattr |= (byte)(__msg->attr.del() ? EZYC_MSGATTR_DELETED : 0); + __hdr.msgattr |= (byte)(__msg->attr.pvt() ? EZYC_MSGATTR_PRIVATE : 0); + __hdr.msgattr |= (byte)(__msg->attr.rcv() ? EZYC_MSGATTR_RECEIVED : 0); + __hdr.msgattr |= (byte)(__msg->attr.loc() ? EZYC_MSGATTR_LOCAL : 0); + __hdr.msgattr |= (byte)(__msg->attr.lok() ? EZYC_MSGATTR_NOKILL : 0); + __hdr.netattr |= (byte)(__msg->attr.k_s() ? EZYC_NETATTR_KILLSENT : 0); + __hdr.netattr |= (byte)(__msg->attr.snt() ? EZYC_NETATTR_SENT : 0); + __hdr.netattr |= (byte)(__msg->attr.att() ? EZYC_NETATTR_ATTACH : 0); + __hdr.netattr |= (byte)(__msg->attr.cra() ? EZYC_NETATTR_CRASH : 0); + __hdr.netattr |= (byte)(__msg->attr.frq() ? EZYC_NETATTR_FREQ : 0); + __hdr.netattr |= (byte)(__msg->attr.rrq() ? EZYC_NETATTR_RREQ : 0); + __hdr.netattr |= (byte)(__msg->attr.arq() ? EZYC_NETATTR_AREQ : 0); + __hdr.netattr |= (byte)(__msg->attr.rrc() ? EZYC_NETATTR_RREC : 0); + __hdr.extattr = __msg->ezycom.extattr; + __hdr.extattr |= (byte)(__msg->timesread ? EZYC_EXTATTR_SEEN : 0); + + if(__msg->attr.uns()) { + if(isnet()) + __hdr.msgattr |= EZYC_MSGATTR_NETPEND; + else if(isecho()) + __hdr.msgattr |= EZYC_MSGATTR_ECHOPEND; + } + + // Delete if requested + if(__mode & GMSG_DELETE) + __hdr.msgattr |= EZYC_MSGATTR_DELETED; + + // Convert header data + + __hdr.posttimedate = TimeToFTime(__msg->written); + __hdr.recvtimedate = TimeToFTime(__msg->arrived); + + SwapWord32((long*)&__hdr.posttimedate); + SwapWord32((long*)&__hdr.recvtimedate); + + strc2p(strxcpy(__hdr.whoto, __msg->to, sizeof(__hdr.whoto))); + strc2p(strxcpy(__hdr.whofrom, __msg->by, sizeof(__hdr.whofrom))); + strc2p(strxcpy(__hdr.subject, __msg->re, sizeof(__hdr.subject))); + + __hdr.orignet.zone = __msg->oorig.zone; + __hdr.orignet.net = __msg->oorig.net; + __hdr.orignet.node = __msg->oorig.node; + __hdr.orignet.point = __msg->oorig.point; + + __hdr.destnet.zone = __msg->odest.zone; + __hdr.destnet.net = __msg->odest.net; + __hdr.destnet.node = __msg->odest.node; + __hdr.destnet.point = __msg->odest.point; + + __hdr.replyto = (word)__msg->link.to(); + __hdr.reply1st = (word)__msg->link.first(); + + __hdr.cost = (word)__msg->cost; + + __hdr.startposition = __msg->txtstart; + __hdr.messagelength = __msg->txtlength; + + if(__mode & GMSG_TXT) { + + // Write the message text + uint _size = strlen(__msg->txt) + 1; + if((__mode & GMSG_NEW) OR (_size > __hdr.messagelength)) + __hdr.startposition = filelength(data->fhtxt); + lseekset(data->fhtxt, __hdr.startposition); + write(data->fhtxt, __msg->txt, _size); + __hdr.messagelength = _size; + } + + // Write header record + lseekset(data->fhhdr, __msg->msgno-1, sizeof(EzycHdr)); + write(data->fhhdr, &__hdr, sizeof(EzycHdr)); + + int _fh; + + // Update MSGEXPRT.BBS, which tells ezymail/ezynet which areas to scan for mail + _fh = test_open(AddPath(wide->msgbasepath, "MSGEXPRT.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYNO); + if(_fh == -1) { + WideLog->ErrOpen(); + WideLog->printf("! A Ezycom msgbase file could not be opened."); + WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGEXPRT.BBS")); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + byte _tmp = true; + lseekset(_fh, board()-1); + write(_fh, &_tmp, sizeof(byte)); + ::close(_fh); + + // Update MSGFAST.BBS + EzycFast _msgfast; + _msgfast.msgboard = (word)board(); + _msgfast.msgnumber = (word)__msg->msgno; + _msgfast.whoto = CRC32_MASK_CCITT; + char* _ptr = __msg->to; + while(*_ptr) { + _msgfast.whoto = updCrc32((char)toupper(*_ptr), _msgfast.whoto); + _ptr++; + } + _fh = test_open(AddPath(wide->msgbasepath, "MSGFAST.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYWR); + if(_fh == -1) { + WideLog->ErrOpen(); + WideLog->printf("! A Ezycom msgbase file could not be opened."); + WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGFAST.BBS")); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + lseek(_fh, 0, SEEK_END); + write(_fh, &_msgfast, sizeof(EzycFast)); + ::close(_fh); + + // Update MSGCOUNT.BBS + _fh = test_open(AddPath(wide->msgbasepath, "MSGCOUNT.BBS"), O_WRONLY|O_CREAT|O_BINARY, SH_DENYNO); + if(_fh == -1) { + WideLog->ErrOpen(); + WideLog->printf("! A Ezycom msgbase file could not be opened."); + WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGCOUNT.BBS")); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + + if(WideCanLock) { + + // Try to get the lock + long _tries = 0; + while(::lock(_fh, (board()-1)*2, 2) == -1) { + + // Tell the world + if(PopupLocked(++_tries, true, AddPath(wide->msgbasepath, "MSGCOUNT.BBS")) == false) { + + // User requested to exit + WideLog->ErrLock(); + WideLog->printf("! A Ezycom msgbase file could not be locked."); + WideLog->printf(": %s.", AddPath(wide->msgbasepath, "MSGCOUNT.BBS")); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + } + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + } + + word _tmpword = (word)(filelength(data->fhhdr) / sizeof(EzycHdr)); + lseekset(_fh, (board()-1)*2); + write(_fh, &_tmpword, sizeof(word)); + ::unlock(_fh, (board()-1)*2, 2); + ::close(_fh); + + // Update internals if new + if(__mode & GMSG_NEW) { + + // Count our msgs + data->timesposted++; + + // Update internal array + Msgn->Append(__msg->msgno); + } + + if(NOT _was_locked) + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("EzycomSaveHdr"); + + EzycHdr _hdr; + save_message(__mode|GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("EzycomSaveMsg"); + + EzycHdr _hdr; + save_message(__mode|GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::del_msg(gmsg* __msg) { + + GFTRK("EzycomDelMsg"); + + EzycHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::new_msgno(gmsg* __msg) { + + GFTRK("EzycomNewMsgno"); + + __msg->msgno = (filelength(data->fhhdr) / sizeof(EzycHdr)) + 1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void EzycomArea::update_timesread(gmsg* msg) { + + GFTRK("EzycomArea::update_timesread"); + + lock(); + + EzycHdr hdr; + ::lseekset(data->fhhdr, msg->msgno-1, sizeof(EzycHdr)); + ::read(data->fhhdr, &hdr, sizeof(EzycHdr)); + + hdr.extattr |= (byte)(msg->timesread ? EZYC_EXTATTR_SEEN : 0); + + ::lseekset(data->fhhdr, msg->msgno-1, sizeof(EzycHdr)); + ::write(data->fhhdr, &hdr, sizeof(EzycHdr)); + + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmoezyc5.cpp b/goldlib/gmb3/gmoezyc5.cpp new file mode 100644 index 0000000..815c1cf --- /dev/null +++ b/goldlib/gmb3/gmoezyc5.cpp @@ -0,0 +1,112 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Ezycom msgbase handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +char* EzycomArea::user_lookup(char* __lookfor) { + + wide->user->fh = ::sopen(AddPath(wide->userbasepath, "USERS.BBS"), O_RDWR|O_BINARY, WideSharemode, S_STDRW); + if(wide->user->fh) { + wide->user->findwild(__lookfor, __lookfor); + ::close(wide->user->fh); + } + + if(wide->user->found) + return __lookfor; + else + return NULL; +} + + +// ------------------------------------------------------------------ + +int EzycomArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ + +Line* EzycomArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) { + + GFTRK("EzycomMakeDump"); + + EzycHdr _hdr; + load_message(GMSG_HDRTXT, msg, _hdr); + + char buf[100]; + Line* line = lin = + AddLine (NULL, "Hexdump of Ezycom-style message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Msgbase : %s", wide->msgbasepath); + AddLineF(line, "BoardNo : %u", board()); + AddLineF(line, "From : %-35.35s", msg->by); + AddLineF(line, "To : %-35.35s", msg->to); + AddLineF(line, "Subject : %-72.72s", msg->re); + AddLineF(line, "Orig : %u:%u/%u.%u", _hdr.orignet.zone, _hdr.orignet.net, _hdr.orignet.node, _hdr.orignet.point); + AddLineF(line, "Dest : %u:%u/%u.%u", _hdr.destnet.zone, _hdr.destnet.net, _hdr.destnet.node, _hdr.destnet.point); + AddLineF(line, "Reply : %u See : %u", _hdr.replyto, _hdr.reply1st); + AddLineF(line, "Cost : %u", _hdr.cost); + AddLineF(line, "MsgAttr : %02Xh (%sb)", _hdr.msgattr, ltob(buf, _hdr.msgattr, 8)); + AddLineF(line, "NetAttr : %02Xh (%sb)", _hdr.netattr, ltob(buf, _hdr.netattr, 8)); + AddLineF(line, "ExtAttr : %02Xh (%sb)", _hdr.extattr, ltob(buf, _hdr.extattr, 8)); + AddLineF(line, "PostDate : %s (%08lXh)", FTimeToStr(buf, _hdr.posttimedate), *(dword*)&_hdr.posttimedate); + AddLineF(line, "RecvDate : %s (%08lXh)", FTimeToStr(buf, _hdr.recvtimedate), *(dword*)&_hdr.recvtimedate); + AddLineF(line, "StartPos : %lu", _hdr.startposition); + AddLineF(line, "MsgLength: %lu", _hdr.messagelength); + AddLineF(line, "UserRecno: %u (%s)", wide->userno, WideUsername[0]); + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + uint _count = 0; + char* _ptr = (char*)&_hdr; + while(_count < sizeof(EzycHdr)) { + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, 16, HEX_DUMP2); + line = AddLine(line, buf); + _count += 16; + _ptr += 16; + } + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, sizeof(EzycHdr)%16, HEX_DUMP2); + line = AddLine(line, buf); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmofido.h b/goldlib/gmb3/gmofido.h new file mode 100644 index 0000000..eb79518 --- /dev/null +++ b/goldlib/gmb3/gmofido.h @@ -0,0 +1,206 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fido/Opus *.MSG +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GMFIDO_H +#define __GMFIDO_H + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +const uint FIDO_SCANBUFSIZE = 100; + + +// ------------------------------------------------------------------ +// Fido message attributes + +#define FIDO_PVT 0x0001 +#define FIDO_CRASH 0x0002 +#define FIDO_RECEIVED 0x0004 +#define FIDO_SENT 0x0008 +#define FIDO_ATTACH 0x0010 +#define FIDO_TRANSIT 0x0020 +#define FIDO_ORPHAN 0x0040 +#define FIDO_KILLSENT 0x0080 +#define FIDO_LOCAL 0x0100 +#define FIDO_HOLD 0x0200 +#define FIDO_RESERVED 0x0400 +#define FIDO_FREQ 0x0800 +#define FIDO_RETRECREQ 0x1000 +#define FIDO_RETREC 0x2000 +#define FIDO_AUDITREQ 0x4000 +#define FIDO_UPDREQ 0x8000 + + +// ------------------------------------------------------------------ +// Fido style message header (FTS-0001.015 compatible) + +struct FidoHdr { + char by[36]; + char to[36]; + char re[72]; + char datetime[20]; + word timesread; + word destnode; + word orignode; + word cost; + word orignet; + word destnet; + union { + struct { + word destzone; + word origzone; + word destpoint; + word origpoint; + } ftsc; + struct { + FTime written; + FTime arrived; + } opus; + }; + word replyto; + word attr; + word reply1st; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct FidoData { + ulong highwatermark; +}; + + +// ------------------------------------------------------------------ + +struct FidoWide { + MaximusUser* user; + int userno; + int fidohwmarks; + int fidonullfix; + const char* fidolastread; + const char* squishuserpath; +}; + + +// ------------------------------------------------------------------ + +class FidoArea : public gmo_area { + +protected: + + FidoWide* wide; + FidoData* data; + + void data_open(); + void data_close(); + + char* build_msgname(char* __buf, ulong __msgno); + int test_open(const char* __file, int __openmode, int __sharemode, int __fail=NO); + void raw_scan(bool __scanpm); + int load_message(int __mode, gmsg* __msg, FidoHdr& __hdr); + void save_lastread(); + void save_message(int __mode, gmsg* __msg, FidoHdr& __hdr); + +public: + + FidoArea() { wide = NULL; data = NULL; } + virtual ~FidoArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); + + void set_highwater_mark(); + void reset_highwater_mark(); +}; + + +// ------------------------------------------------------------------ + +extern FidoWide* fidowide; +extern FidoData* fidodata; +extern int fidodatano; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmofido1.cpp b/goldlib/gmb3/gmofido1.cpp new file mode 100644 index 0000000..32a3c2c --- /dev/null +++ b/goldlib/gmb3/gmofido1.cpp @@ -0,0 +1,249 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fido/Opus/FTSC (*.MSG) type handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +FidoWide* fidowide = NULL; +FidoData* fidodata = NULL; +int fidodatano = 0; + + +// ------------------------------------------------------------------ + +void FidoArea::data_open() { + + wide = fidowide; + data = fidodata + (fidodatano++); +} + + +// ------------------------------------------------------------------ + +void FidoArea::data_close() { + + fidodatano--; +} + + +// ------------------------------------------------------------------ + +char* FidoArea::build_msgname(char* __buf, ulong __msgno) { + + sprintf(__buf, "%s%lu.msg", path(), __msgno); + return __buf; +} + + +// ------------------------------------------------------------------ + +int FidoArea::test_open(const char* __file, int __openmode, int __sharemode, int __fail) { + + GFTRK("FidoTestOpen"); + + int _fh; + long _tries = 0; + + do { + + _fh = ::sopen(__file, __openmode, __sharemode, S_STDRW); + if(_fh == -1) { + + if((errno != EACCES) OR (PopupLocked(++_tries, false, __file) == false)) { + + // Return instead of halting if requested + if(errno != EACCES AND NOT __fail) { + GFTRK(NULL); + return _fh; + } + + // User requested to exit + WideLog->ErrOpen(); + WideLog->printf("! A Fido message file could not be opened."); + WideLog->printf(": %s", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void FidoExit() { + + if(fidowide) + delete fidowide->user; + throw_release(fidowide); + throw_release(fidodata); +} + + +// ------------------------------------------------------------------ + +void FidoInit(const char* fidolastread, int fidohwmarks, int fidonullfix, int fidouserno, const char* squishuserpath) { + + fidodata = (FidoData*)throw_calloc(2, sizeof(FidoData)); + fidowide = (FidoWide*)throw_calloc(1, sizeof(FidoWide)); + + fidowide->fidolastread = fidolastread; + fidowide->fidohwmarks = fidohwmarks; + fidowide->fidonullfix = fidonullfix; + fidowide->userno = fidouserno; + fidowide->squishuserpath = squishuserpath; + + fidowide->user = new MaximusUser; + throw_new(fidowide->user); + + const char* _username = WideUsername[0]; + if(fidowide->userno == -1) { + Path userfile; + strxcpy(userfile, fidowide->squishuserpath, sizeof(Path)); + AddPath(userfile, "USER.BBS"); + fidowide->user->fh = ::sopen(userfile, O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(fidowide->user->fh != -1) { + fidowide->user->find(_username); + if(NOT fidowide->user->found) { + WideLog->printf("* User \"%s\" not found in %s.", _username, userfile); + fidowide->user->add(_username); + WideLog->printf("* Now added with user number %u.", fidowide->user->index); + } + ::close(fidowide->user->fh); + } + fidowide->userno = fidowide->user->index; + } +} + + +// ------------------------------------------------------------------ + +void FidoArea::open() { + + GFTRK("FidoOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a *.MSG msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::save_lastread() { + + GFTRK("FidoSaveLastread"); + + int _fh = ::sopen(AddPath(path(), wide->fidolastread), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(_fh != -1) { + word _lastread = (word)Msgn->CvtReln(lastread); + lseekset(_fh, wide->userno, sizeof(word)); + write(_fh, &_lastread, sizeof(word)); + ::close(_fh); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::close() { + + GFTRK("FidoClose"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + Msgn->Reset(); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed *.MSG msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::suspend() { + + GFTRK("FidoSuspend"); + + save_lastread(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::resume() { + + GFTRK("FidoResume"); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmofido2.cpp b/goldlib/gmb3/gmofido2.cpp new file mode 100644 index 0000000..5c1ea20 --- /dev/null +++ b/goldlib/gmb3/gmofido2.cpp @@ -0,0 +1,262 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fido/Opus/FTSC (*.MSG) type handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void FidoArea::raw_scan(bool __scanpm) { + + GFTRK("FidoArea::raw_scan"); + + register uint _active = 0; + register ulong* _msgnoptr = NULL; + register ulong* _msgndx = Msgn->tag; + + gposixdir d(path()); + if(WideDebug) + WideLog->printf("- %s/*.msg", d.fullpath()); + const gdirentry *de; + while((de = d.nextentry("*.msg", true)) != NULL) { + if(WideDebug) + WideLog->printf("- %s", de->name.c_str()); + register ulong _msgno = (ulong)atol(de->name.c_str()); + if(_msgno) { + if((_active % FIDO_SCANBUFSIZE) == 0) { + _msgndx = Msgn->Resize(_active+FIDO_SCANBUFSIZE); + _msgnoptr = _msgndx + _active; + } + *_msgnoptr++ = _msgno; + _active++; + } + } + + // Sort the index + Msgn->SetCount(_active); + Msgn->Sort(); + + // Get the lastread msgno + word _lastread = 0; + int _fh = ::sopen(AddPath(path(), wide->fidolastread), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(_fh != -1) { + lseekset(_fh, wide->userno, sizeof(word)); + read(_fh, &_lastread, sizeof(word)); + ::close(_fh); + } + + _msgnoptr = _msgndx; + + register uint _count = 1; + register uint _lastread_reln = 0; + register ulong _firstmsgno = 0; + register ulong _lastmsgno = 0; + register ulong _lastreadfound = 0; + FidoHdr _hdr; + + if(_active) { + + _firstmsgno = Msgn->at(0); + _lastmsgno = Msgn->at(_active-1); + + while(1) { + + // Set lastread pointer + if((*_msgnoptr >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = *_msgnoptr; + _lastread_reln = _count - (*_msgnoptr != _lastread ? 1 : 0); + break; + } + if((++_count) > _active) + break; + _msgnoptr++; + } + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + + // Read highwater mark + data->highwatermark = 0; + if(isecho() AND wide->fidohwmarks) { + _fh = test_open(AddPath(path(), "1.msg"), O_RDONLY|O_BINARY, WideSharemode); + if(_fh != -1) { + read(_fh, &_hdr, sizeof(FidoHdr)); + data->highwatermark = _hdr.replyto; + ::close(_fh); + } + } + + // Update area data + Msgn->SetCount(_active); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + if(__scanpm) { + char hdr_by[37]; + int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; + bool gotpm = false; + + PMrk->ResetAll(); + + for(uint i = lastread+1; i<=Msgn->Count(); i++) { + // Build message filename + Path _msgfile; + ulong msgno = Msgn->CvtReln(i); + build_msgname(_msgfile, msgno); + + // Open the message file + int _fh = test_open(_msgfile, O_RDONLY|O_BINARY, WideSharemode); + if(_fh >= 0) { + read(_fh, &_hdr, sizeof(FidoHdr)); + strxcpy(hdr_by, _hdr.to, 36); + + for(int u=0; uAppend(msgno); + + gotpm = false; + } + ::close(_fh); + } + } + } + + if(WideDebug) { + WideLog->printf("- %s: t:%u, l:%u, fm:%lu, hm:%lu, lr:%u, u:%u, pm: %i", + echoid(), + Msgn->Count(), + lastread, + _firstmsgno, + _lastmsgno, + _lastread, + fidowide->userno, + __scanpm ? (int)PMrk->Count() : -1 + ); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::scan() { + + GFTRK("FidoArea::scan"); + + scan_area(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::scan_area() { + + GFTRK("FidoArea::scan_area"); + + bool was_open = data ? true : false; + if(not was_open) + data_open(); + raw_scan(false); + if(not was_open) + data_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::scan_area_pm() { + + GFTRK("FidoArea::scan_area_pm"); + + bool was_open = data ? true : false; + if(not was_open) + data_open(); + raw_scan(true); + if(not was_open) + data_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::set_highwater_mark() { + + if(isecho()) { + open(); + gmsg hmsg; + hmsg.msgno = 1; + if(load_hdr(&hmsg)) { + hmsg.link.to_set(Msgn->CvtReln(Msgn->Count())); + save_hdr(GMSG_UPDATE, &hmsg); + } + close(); + } +} + + +// ------------------------------------------------------------------ + +void FidoArea::reset_highwater_mark() { + + if(isecho()) { + open(); + gmsg hmsg; + hmsg.msgno = 1; + if(load_hdr(&hmsg)) { + hmsg.link.to_set(Msgn->CvtReln(1)); + save_hdr(GMSG_UPDATE, &hmsg); + } + close(); + } +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmofido3.cpp b/goldlib/gmb3/gmofido3.cpp new file mode 100644 index 0000000..e35f117 --- /dev/null +++ b/goldlib/gmb3/gmofido3.cpp @@ -0,0 +1,189 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fido/Opus/FTSC (*.MSG) type handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +int FidoArea::load_message(int __mode, gmsg* __msg, FidoHdr& __hdr) { + + // Build message filename + Path _msgfile; + build_msgname(_msgfile, __msg->msgno); + + // Open the message file + int _fh = test_open(_msgfile, O_RDONLY|O_BINARY, WideSharemode); + if(_fh == -1) { + GFTRK(NULL); + return false; + } + + // Get file info + struct stat st; + stat(_msgfile, &st); + + // Read header + memset(&__hdr, 0, sizeof(FidoHdr)); + read(_fh, &__hdr, sizeof(FidoHdr)); + + __msg->link.to_set(__hdr.replyto); + __msg->link.first_set(__hdr.reply1st); + + __msg->cost = __hdr.cost; + __msg->timesread = __hdr.timesread; + + strxcpy(__msg->by, __hdr.by, 36); + strxcpy(__msg->to, __hdr.to, 36); + strxcpy(__msg->re, __hdr.re, 72); + + __msg->orig.zone = __msg->oorig.zone = __hdr.ftsc.origzone; + __msg->orig.net = __msg->oorig.net = __hdr.orignet; + __msg->orig.node = __msg->oorig.node = __hdr.orignode; + __msg->orig.point = __msg->oorig.point = __hdr.ftsc.origpoint; + + __msg->dest.zone = __msg->odest.zone = __hdr.ftsc.destzone; + __msg->dest.net = __msg->odest.net = __hdr.destnet; + __msg->dest.node = __msg->odest.node = __hdr.destnode; + __msg->dest.point = __msg->odest.point = __hdr.ftsc.destpoint; + + if(isopus()) { + __msg->orig.zone = __msg->oorig.zone = + __msg->dest.zone = __msg->odest.zone = + __msg->orig.point = __msg->oorig.point = + __msg->dest.point = __msg->odest.point = 0; + } + + // Convert datetime + if(isopus()) { + __msg->written = FTimeToTime(&__hdr.opus.written); + __msg->arrived = FTimeToTime(&__hdr.opus.arrived); + } + else { + __msg->written = __msg->arrived = 0; + } + __msg->written = __msg->written ? __msg->written : FidoTimeToUnix(__hdr.datetime); + time_t a = time(NULL); + time_t b = mktime(gmtime(&a)); + __msg->arrived = __msg->arrived ? __msg->arrived : a + a - b; + + // Transfer attributes + __msg->attr.pvt(__hdr.attr & FIDO_PVT); + __msg->attr.cra(__hdr.attr & FIDO_CRASH); + __msg->attr.rcv(__hdr.attr & FIDO_RECEIVED); + __msg->attr.snt(__hdr.attr & FIDO_SENT); + __msg->attr.att(__hdr.attr & FIDO_ATTACH); + __msg->attr.trs(__hdr.attr & FIDO_TRANSIT); + __msg->attr.orp(__hdr.attr & FIDO_ORPHAN); + __msg->attr.k_s(__hdr.attr & FIDO_KILLSENT); + __msg->attr.loc(__hdr.attr & FIDO_LOCAL); + __msg->attr.hld(__hdr.attr & FIDO_HOLD); + __msg->attr.rsv(__hdr.attr & FIDO_RESERVED); + __msg->attr.frq(__hdr.attr & FIDO_FREQ); + __msg->attr.rrq(__hdr.attr & FIDO_RETRECREQ); + __msg->attr.rrc(__hdr.attr & FIDO_RETREC); + __msg->attr.arq(__hdr.attr & FIDO_AUDITREQ); + __msg->attr.urq(__hdr.attr & FIDO_UPDREQ); + __msg->attr.lok(not (st.st_mode & S_IWUSR)); + + // Set the unsent attribute + if(isnet() OR (isecho() AND NOT wide->fidohwmarks)) + __msg->attr.uns((__hdr.attr & FIDO_LOCAL) AND NOT (__hdr.attr & FIDO_SENT)); + else if(isecho() AND wide->fidohwmarks) { + __msg->attr.uns(data->highwatermark < __msg->msgno); + __msg->attr.snt(data->highwatermark >= __msg->msgno); + } + else + __msg->attr.uns0(); + + // If message text is used + if(__mode & GMSG_TXT) { + + // Get length of message text and adjust if necessary + long _fillen = filelength(_fh); + long _txtlen = _fillen >= sizeof(FidoHdr) ? _fillen - sizeof(FidoHdr) : 0; + if((_txtlen+256) > WideMsgSize) + _txtlen = WideMsgSize; + uint _alloclen = (uint)(_txtlen+256); + + // Allocate space for the message text + __msg->txt = (char*)throw_calloc(1, _alloclen); + + // Read the message text + read(_fh, __msg->txt, (uint)_txtlen); + + // Fix msgs handled by brain-dead programs + register char* _ptr = __msg->txt; + if(!*_ptr) + if(_txtlen) + *_ptr = LF; // Quick fix + + // Fix complete msg + if(wide->fidonullfix) { + for(uint _count=0; _count<_txtlen; _count++,_ptr++) + if(!*_ptr) + *_ptr = LF; + } + } + + // Close the message file + ::close(_fh); + + GFTRK(NULL); + + // Success + return true; +} + + +// ------------------------------------------------------------------ + +int FidoArea::load_hdr(gmsg* __msg) { + + GFTRK("FidoLoadHdr"); + + FidoHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int FidoArea::load_msg(gmsg* __msg) { + + GFTRK("FidoLoadMsg"); + + FidoHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmofido4.cpp b/goldlib/gmb3/gmofido4.cpp new file mode 100644 index 0000000..b1aafaa --- /dev/null +++ b/goldlib/gmb3/gmofido4.cpp @@ -0,0 +1,304 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fido/Opus/FTSC (*.MSG) type handling +// ------------------------------------------------------------------ + +#include +#include +#if defined(__WATCOMC__) || defined(__MINGW32__) || defined(_MSC_VER) +#include +#else +#include +#endif +#include +#include +#include + + +// ------------------------------------------------------------------ + +void FidoArea::lock() { + + GFTRK("FidoLock"); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::unlock() { + + GFTRK("FidoUnlock"); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::save_message(int __mode, gmsg* __msg, FidoHdr& __hdr) { + + // Build message filename + Path _msgfile; + if(__mode & GMSG_NEW) { + + // Get a new message number + uint _cnt = 0; + do { + __msg->msgno = Msgn->CvtReln(Msgn->Count()) + (++_cnt); + } while(fexist(build_msgname(_msgfile, __msg->msgno))); + + // Never create a new 1.MSG in echo or local areas. + if(__msg->msgno == 1) { + if(NOT isnet()) { + __msg->msgno = 2; + build_msgname(_msgfile, __msg->msgno); + } + } + + // Avoid collision with an existing msg + while(fexist(_msgfile)) { + build_msgname(_msgfile, ++__msg->msgno); + // here we should signal that a rescan is needed + } + } + else { + build_msgname(_msgfile, __msg->msgno); + } + + // Delete message, if so ordered + if(__mode & GMSG_DELETE) { + if(remove(_msgfile)) { + chmod(_msgfile, S_STDRW); + remove(_msgfile); + } + GFTRK(NULL); + return; + } + + // Get message file attributes + struct stat st; + if(stat(_msgfile, &st) == 0) { + bool readonly = not (st.st_mode & S_IWUSR); + + // If the file is read-only, make it read-write-able + if(readonly) + chmod(_msgfile, S_STDRW); + } + + // Determine file open mode + int _omode = O_RDWR|O_CREAT|O_BINARY; + if(__mode & GMSG_TXT) { + + // Add truncate, in case a changed msg is shorter + _omode |= O_TRUNC; + } + + // Open the message file + int _fh = test_open(_msgfile, _omode, WideSharemode, YES); + + // Get date/time of message file + if(NOT(__mode & GMSG_NEW)) { + if(NOT __msg->attr.upd()) + fstat(_fh, &st); + } + + memset(&__hdr, 0, sizeof(FidoHdr)); + + // Transfer attributes + __hdr.attr |= (word)(__msg->attr.pvt() ? FIDO_PVT : 0); + __hdr.attr |= (word)(__msg->attr.cra() ? FIDO_CRASH : 0); + __hdr.attr |= (word)(__msg->attr.rcv() ? FIDO_RECEIVED : 0); + __hdr.attr |= (word)(__msg->attr.snt() ? FIDO_SENT : 0); + __hdr.attr |= (word)(__msg->attr.att() ? FIDO_ATTACH : 0); + __hdr.attr |= (word)(__msg->attr.trs() ? FIDO_TRANSIT : 0); + __hdr.attr |= (word)(__msg->attr.orp() ? FIDO_ORPHAN : 0); + __hdr.attr |= (word)(__msg->attr.k_s() ? FIDO_KILLSENT : 0); + __hdr.attr |= (word)(__msg->attr.loc() ? FIDO_LOCAL : 0); + __hdr.attr |= (word)(__msg->attr.hld() ? FIDO_HOLD : 0); + __hdr.attr |= (word)(__msg->attr.rsv() ? FIDO_RESERVED : 0); + __hdr.attr |= (word)(__msg->attr.frq() ? FIDO_FREQ : 0); + __hdr.attr |= (word)(__msg->attr.rrq() ? FIDO_RETRECREQ : 0); + __hdr.attr |= (word)(__msg->attr.rrc() ? FIDO_RETREC : 0); + __hdr.attr |= (word)(__msg->attr.arq() ? FIDO_AUDITREQ : 0); + __hdr.attr |= (word)(__msg->attr.urq() ? FIDO_UPDREQ : 0); + + strxcpy(__hdr.to, __msg->to, 36); + strxcpy(__hdr.by, __msg->by, 36); + strxcpy(__hdr.re, __msg->re, 72); + + __hdr.ftsc.origzone = __msg->oorig.zone; + __hdr.orignet = __msg->oorig.net; + __hdr.orignode = __msg->oorig.node; + __hdr.ftsc.origpoint = __msg->oorig.point; + + __hdr.ftsc.destzone = __msg->odest.zone; + __hdr.destnet = __msg->odest.net; + __hdr.destnode = __msg->odest.node; + __hdr.ftsc.destpoint = __msg->odest.point; + + __hdr.replyto = (word)__msg->link.to(); + __hdr.reply1st = (word)__msg->link.first(); + + __hdr.cost = (word)__msg->cost; + __hdr.timesread = (word)__msg->timesread; + + if(isopus()) { + __hdr.opus.written = TimeToFTime(__msg->written); + __hdr.opus.arrived = TimeToFTime(__msg->arrived); + } + struct tm* _tm = gmtime(&__msg->written); + sprintf(__hdr.datetime, "%02d %3s %02d %02d:%02d:%02d", + _tm->tm_mday, gmonths[_tm->tm_mon+1], _tm->tm_year % 100, + _tm->tm_hour, _tm->tm_min, _tm->tm_sec + ); + + // Write message header + write(_fh, &__hdr, sizeof(FidoHdr)); + + // If message text is used + if(__mode & GMSG_TXT) { + + // Write the message text + write(_fh, __msg->txt, strlen(__msg->txt)+1); + } + + // Close the message file + ::close(_fh); + + // Reset date/time of message file + if(NOT(__mode & GMSG_NEW)) { + if(NOT __msg->attr.upd()) { + struct utimbuf t; + t.actime = st.st_atime; + t.modtime = st.st_mtime; + utime(_msgfile, &t); + } + } + + // If the message has locked status, make it read-only + if(__msg->attr.lok()) + chmod(_msgfile, S_STDRD); + + // Update internal array if the msg is new + if(__mode & GMSG_NEW) { + + // Add the msgno to the index + Msgn->Append(__msg->msgno); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("FidoSaveHdr"); + + FidoHdr _hdr; + save_message(__mode|GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void FidoArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("FidoSaveMsg"); + + FidoHdr _hdr; + save_message(__mode|GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void FidoArea::del_msg(gmsg* __msg) { + + GFTRK("FidoDelMsg"); + + FidoHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void FidoArea::new_msgno(gmsg* __msg) { + + GFTRK("FidoNewMsgno"); + + uint n = 0; + Path _buf; + do { + __msg->msgno = Msgn->CvtReln(Msgn->Count()) + (++n); + } while(fexist(build_msgname(_buf, __msg->msgno))); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void FidoArea::update_timesread(gmsg* msg) { + + GFTRK("FidoArea::update_timesread"); + + Path filename; + build_msgname(filename, msg->msgno); + + // If it has Lok attribute set, remove READ_ONLY attribute + // and later add it again + struct stat st; + bool readonly = false; + + if(stat(filename, &st) == 0) { + readonly = not (st.st_mode & S_IWUSR); + + if(readonly) + chmod(filename, S_STDRW); + } + + int fh = test_open(filename, O_RDWR|O_BINARY, WideSharemode); + if(fh != -1) { + FidoHdr hdr; + ::read(fh, &hdr, sizeof(FidoHdr)); + hdr.timesread = (word)msg->timesread; + ::lseekset(fh, 0); + ::write(fh, &hdr, sizeof(FidoHdr)); + ::close(fh); + } + + // If file was read_only before, make it again read_only + if(readonly) + chmod(filename,S_STDRD); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmofido5.cpp b/goldlib/gmb3/gmofido5.cpp new file mode 100644 index 0000000..6eecdba --- /dev/null +++ b/goldlib/gmb3/gmofido5.cpp @@ -0,0 +1,199 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Fido/Opus/FTSC (*.MSG) type handling +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +char* FidoArea::user_lookup(char* __lookfor) { + + Path userfile; + strxcpy(userfile, fidowide->squishuserpath, sizeof(Path)); + AddPath(userfile, "USER.BBS"); + wide->user->fh = ::sopen(userfile, O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + wide->user->findwild(__lookfor, __lookfor); + ::close(wide->user->fh); + + if(wide->user->found) + return __lookfor; + else + return NULL; +} + + +// ------------------------------------------------------------------ + +int FidoArea::renumber() { + + GFTRK("FidoRenumber"); + + // Save the current lastread + save_lastread(); + + // Rescan the area + scan(); + + // In echo or local, start with 2.MSG so we don't conflict + // with highwater marks, unless there is already a 1.MSG + ulong _msgno1st = 1; + if((NOT isnet()) AND (Msgn->at(0) != 1)) + _msgno1st++; + + // Renumber *.MSG files + register uint _count = 0; + register ulong _msgno = _msgno1st; + while(_count < Msgn->Count()) { + + // Only renumber a msg if different + if(_msgno != Msgn->at(_count)) { + + Path _oldname, _newname; + sprintf(_oldname, "%s%lu.msg", path(), Msgn->at(_count)); + sprintf(_newname, "%s%lu.msg", path(), _msgno); + + // Get the file attribute of the message + struct stat st; + stat(_oldname, &st); + bool readonly = not (st.st_mode & S_IWUSR); + if(readonly) + chmod(_oldname, S_STDRW); + + // Show progress + char buf[100]; + sprintf(buf, + "%s: %lu.msg -> %lu.msg%s", + "Renumbering", + Msgn->at(_count), + _msgno, + readonly ? " (locked)" : "" + ); + FidoRenumberProgress(buf); + + // Update the msg + int _fh = test_open(_oldname, O_RDWR|O_BINARY, SH_DENYWR); + if(_fh != -1) { + + // Read the header + FidoHdr _hdr; + read(_fh, &_hdr, sizeof(FidoHdr)); + + // Update the replylinks + if(_hdr.replyto OR _hdr.reply1st) { + _hdr.replyto = (word)Msgn->ToReln(_hdr.replyto); + _hdr.reply1st = (word)Msgn->ToReln(_hdr.reply1st); + lseekset(_fh, 0); + write(_fh, &_hdr, sizeof(FidoHdr)); + } + ::close(_fh); + + // Rename the message file + rename(_oldname, _newname); + if(readonly) + chmod(_oldname, S_STDRD); + } + } + _msgno++; + _count++; + } + + // Renumber the personal mail marks + for(_count=0; _countTags(); _count++) + PMrk->at(_count) = Msgn->ToReln(PMrk->at(_count)) + _msgno1st - 1; + + // Renumber the index + for(_count=0; _countCount(); _count++) + Msgn->at(_count) = _count + _msgno1st; + + GFTRK(NULL); + + return true; +} + + +// ------------------------------------------------------------------ +// Hexdump the current message header + +Line* FidoArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) { + + GFTRK("FidoMakeDump"); + + FidoHdr _hdr; + load_message(GMSG_HDRTXT, msg, _hdr); + + char buf[100]; + Line* line = lin = + AddLine (NULL, "Hexdump of Fido/Opus-style message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "File : %s%lu.msg", path(), msg->msgno); + AddLineF(line, "From : %-35.35s", _hdr.by); + AddLineF(line, "To : %-35.35s", _hdr.to); + AddLineF(line, "Subject : %-72.72s", _hdr.re); + AddLineF(line, "DateTime : %-20.20s", _hdr.datetime); + if(isopus()) + AddLineF(line, "OrigAddr : %u/%u", _hdr.orignet, _hdr.orignode); + else + AddLineF(line, "OrigAddr : %u:%u/%u.%u", _hdr.ftsc.origzone, _hdr.orignet, _hdr.orignode, _hdr.ftsc.origpoint); + if(isopus()) + AddLineF(line, "DestAddr : %u/%u", _hdr.destnet, _hdr.destnode); + else + AddLineF(line, "DestAddr : %u:%u/%u.%u", _hdr.ftsc.destzone, _hdr.destnet, _hdr.destnode, _hdr.ftsc.destpoint); + AddLineF(line, "Reply : %u See : %u", _hdr.replyto, _hdr.reply1st); + AddLineF(line, "TimesRead: %u Cost: %u", _hdr.timesread, _hdr.cost); + AddLineF(line, "Attr : %u (%04X)", *(word*)&_hdr.attr, *(word*)&_hdr.attr); + if(isopus()) { + AddLineF(line, "Written : %s (%08lXh)", FTimeToStr(buf, _hdr.opus.written), *(dword*)&_hdr.opus.written); + AddLineF(line, "Arrived : %s (%08lXh)", FTimeToStr(buf, _hdr.opus.arrived), *(dword*)&_hdr.opus.arrived); + } + AddLineF(line, "UserRecno: %u (%s)", wide->userno, WideUsername[0]); + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + int _count; + char* _ptr = (char*)&_hdr; + for(_count=0; _count<190; _ptr+=16,_count+=16) { + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, 16, HEX_DUMP2); + line = AddLine(line, buf); + } + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, 14, HEX_DUMP2); + line = AddLine(line, buf); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmohuds.cpp b/goldlib/gmb3/gmohuds.cpp new file mode 100644 index 0000000..8ca7145 --- /dev/null +++ b/goldlib/gmb3/gmohuds.cpp @@ -0,0 +1,121 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson/GoldBase messagebase engine. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +HudsWide* hudsonwide = NULL; +GoldWide* goldbasewide = NULL; + + +// ------------------------------------------------------------------ + +void HudsWideOpen() { + + hudsonwide->open(); +} + + +// ------------------------------------------------------------------ + +void GoldWideOpen() { + + goldbasewide->open(); +} + + +// ------------------------------------------------------------------ + +void HudsWideClose() { + + hudsonwide->close(); +} + + +// ------------------------------------------------------------------ + +void GoldWideClose() { + + goldbasewide->close(); +} + + +// ------------------------------------------------------------------ + +void HudsExit() { + + if(hudsonwide) + hudsonwide->exit(); + throw_xrelease(hudsonwide); +} + + +// ------------------------------------------------------------------ + +void GoldExit() { + + if(goldbasewide) + goldbasewide->exit(); + throw_xrelease(goldbasewide); +} + + +// ------------------------------------------------------------------ + +void HudsInit(const char* path, const char* syspath, int userno, long sizewarn, int ra2usersbbs) { + + // Initialize msgbase-wide data + hudsonwide = (HudsWide*)throw_calloc(1, sizeof(HudsWide)); + hudsonwide->path = path; + hudsonwide->syspath = syspath; + hudsonwide->userno = userno; + hudsonwide->sizewarn = sizewarn; + hudsonwide->ra2usersbbs = ra2usersbbs; + hudsonwide->init(); +} + + +// ------------------------------------------------------------------ + +void GoldInit(const char* path, const char* syspath, int userno, long sizewarn, int ra2usersbbs) { + + // Initialize msgbase-wide data + goldbasewide = (GoldWide*)throw_calloc(1, sizeof(GoldWide)); + goldbasewide->path = path; + goldbasewide->syspath = syspath; + goldbasewide->userno = userno; + NW(sizewarn); + NW(ra2usersbbs); + goldbasewide->init(); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmohuds.h b/goldlib/gmb3/gmohuds.h new file mode 100644 index 0000000..d99e612 --- /dev/null +++ b/goldlib/gmb3/gmohuds.h @@ -0,0 +1,358 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GMHUDS_H +#define __GMHUDS_H + + +// ------------------------------------------------------------------ +// Required + +#include +#include +#include +#include + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +#define HUDS_DELETEDMSGNO 0xFFFFu +#define HUDS_MAXBOARD 200 +#define HUDS_EXT ".bbs" +#define HUDS_NAME "Hudson" + +#define GOLD_DELETEDMSGNO 0xFFFFFFFFL +#define GOLD_MAXBOARD 500 +#define GOLD_EXT ".dat" +#define GOLD_NAME "Goldbase" + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Hudson Message Attributes + +#define HUDS_DELETED 0x01 +#define HUDS_NETTRANS 0x02 +#define HUDS_NETMSG 0x04 +#define HUDS_PVT 0x08 +#define HUDS_RECEIVED 0x10 +#define HUDS_ECHOTRANS 0x20 +#define HUDS_LOCAL 0x40 +#define HUDS_GROUPMSG 0x80 + +#define HUDS_KILLSENT 0x01 +#define HUDS_SENT 0x02 +#define HUDS_ATTACH 0x04 +#define HUDS_CRASH 0x08 +#define HUDS_RETRECREQ 0x10 +#define HUDS_AUDITREQ 0x20 +#define HUDS_RETREC 0x40 +#define HUDS_FREQ 0x80 + + +// ------------------------------------------------------------------ +// Hudson Message Header (MSGHDR.BBS) + +template +struct _HudsHdr { + msgn_t msgno; + msgn_t replyto; + msgn_t reply1st; + word timesread; + rec_t startrec; + word numrecs; + word destnet; + word destnode; + word orignet; + word orignode; + byte destzone; + byte origzone; + word cost; + attr_t msgattr; + attr_t netattr; + board_t board; + char time[6]; + char date[9]; + char to[36]; + char by[36]; + char re[73]; +} __attribute__ ((packed)); + + +// ------------------------------------------------------------------ +// Hudson Messagebase Information (MSGINFO.BBS) + +template +struct _HudsInfo { + msgn_t low; + msgn_t high; + msgn_t total; + last_t active; +} __attribute__ ((packed)); + + +// ------------------------------------------------------------------ +// Hudson Message Header Index (MSGIDX.BBS) + +template +struct _HudsIdx { + msgn_t msgno; + board_t board; +} __attribute__((packed)); + + +// ------------------------------------------------------------------ +// Hudson Message Name Index (MSGTOIDX.BBS) + +struct HudsToIdx { + char name[36]; +} __attribute__((packed)); + + +// ------------------------------------------------------------------ + +typedef word HudsLast[HUDS_MAXBOARD] __attribute__((packed)); +typedef word GoldLast[GOLD_MAXBOARD] __attribute__((packed)); + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct HudsScan { + uint count; + uint active; + ulong lastread; + uint lastreadreln; + ulong lastreadfound; + ulong firstmsgno; + ulong lastmsgno; + uint pmcount; +}; + + +// ------------------------------------------------------------------ + + +template +struct _HudsWide { + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + // + typedef _HudsHdr HudsHdr; + typedef _HudsInfo HudsInfo; + typedef _HudsIdx HudsIdx; +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + int fhtxt; + int fhhdr; + int fhidx; + int fhinf; + int fhlrd; + int fhtoi; + int fhusr; + int fhuix; + int fhuxi; + int isopen; + int islocked; + int timesposted; + long msgidxsize; + HudsIdx* msgidxptr; + HudsInfo msginfo; + last_t lastrec; + GUser* user; + int userno; + HudsScan* scn; + HudsIdx* pmscan; + uint pmscantotal; + int iswideopen; + int ispmscanned; + int iswidescanned; + const char* path; + const char* syspath; + long sizewarn; + int ra2usersbbs; + + void init(); + void exit(); + + void open(); + void close(); + + void lock(); + void unlock(); + + void scan(); + + void raw_open_scan(); + void scan_pm(); + + void realloc_pm_scan(); + + void update_netecho(char* __name, msgn_t __hdridx, int __delete); + + int test_open(char* __file, int __oaccess); + void raw_open(int __oaccess=0, int __all=true); + void raw_close(); + void refresh(); + void save_lastread(board_t board, msgn_t msgno); +}; + + +// ------------------------------------------------------------------ + +template +class _HudsArea : public gmo_area { + + // + typedef _HudsWide HudsWide; + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + // + typedef _HudsHdr HudsHdr; + typedef _HudsInfo HudsInfo; + typedef _HudsIdx HudsIdx; +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + +protected: + + HudsWide* wide; + + void data_open(); + void data_close(); + + void raw_scan(int __keep_index); + + msgn_t get_hdr_idx(gmsg* __msg, char* __file__, int __line__); + + int load_message(int __mode, gmsg* __msg, HudsHdr& __hdr); + void save_message(int __mode, gmsg* __msg, HudsHdr& __hdr); + +public: + + _HudsArea() { wide = NULL; } + virtual ~_HudsArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +// +typedef _HudsWide HudsWide; +typedef _HudsWide GoldWide; +typedef _HudsArea HudsArea; +typedef _HudsArea GoldArea; + + +// ------------------------------------------------------------------ + +extern HudsWide* hudsonwide; +extern GoldWide* goldbasewide; + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmohuds1.cpp b/goldlib/gmb3/gmohuds1.cpp new file mode 100644 index 0000000..57e8501 --- /dev/null +++ b/goldlib/gmb3/gmohuds1.cpp @@ -0,0 +1,372 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson / Goldbase msgbase handling +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +template +void _HudsArea::data_open() { + + wide = (HudsWide*) (__HUDSON ? (void *)hudsonwide : (void *)goldbasewide); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::data_close() { + +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::exit() { + + if(__HUDSON) { + delete hudsonwide->user; + throw_release(hudsonwide->msgidxptr); + } + else { + delete goldbasewide->user; + throw_release(goldbasewide->msgidxptr); + } +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::init() { + + GFTRK("HudsInit"); + + if(WideDebug) + WideLog->printf("- Begin init for %s.", path); + + fhusr = -1; + fhtxt = fhhdr = fhidx = -1; + fhinf = fhlrd = fhtoi = -1; + isopen = 0; + islocked = false; + timesposted = 0; + msgidxsize = 0; + msgidxptr = NULL; + pmscan = NULL; + scn = NULL; + + // Open complete msgbase, create if none exists + if(NOT fexist(AddPath(path, __HUDSON ? "msghdr" HUDS_EXT : "msghdr" GOLD_EXT))) { + WideLog->printf("* Creating new msgbase at %s", path); + raw_open(O_CREAT); + if(filelength(fhinf) == 0) { + memset(&msginfo, 0, sizeof(HudsInfo)); + write(fhinf, &msginfo, sizeof(HudsInfo)); + } + if(filelength(fhlrd) == 0) { + memset(lastrec, 0, sizeof(HudsLast)); + write(fhlrd, lastrec, sizeof(HudsLast)); + } + } + else { + raw_open(); + } + + // Lock msgbase to ensure data integrity + lock(); + + // Check if MSGTXT.BBS is approaching dangerous size + if(__HUDSON and (filelength(fhtxt) > sizewarn)) + HudsSizewarn(); + + // Check for mismatch between the header and the index files + long _hdrsize = filelength(fhhdr)/(long)sizeof(HudsHdr); + long _idxsize = filelength(fhidx)/(long)sizeof(HudsIdx); + long _toisize = filelength(fhtoi)/(long)sizeof(HudsToIdx); + if((_hdrsize != _idxsize) OR (_hdrsize != _toisize)) { + raw_close(); + HGWarnRebuild(); + WideLog->ErrIndex(); + WideLog->printf("! The %s msgbase files do not have the same number of records.", __HUDSON ? HUDS_NAME : GOLD_NAME); + WideLog->printf(": %smsghdr%s (%lu records).", path, __HUDSON ? HUDS_EXT : GOLD_EXT, _hdrsize); + WideLog->printf(": %smsgidx%s (%lu records).", path, __HUDSON ? HUDS_EXT : GOLD_EXT, _idxsize); + WideLog->printf(": %smsgtoidx%s (%lu records).", path, __HUDSON ? HUDS_EXT : GOLD_EXT, _toisize); + WideLog->printf("+ Advice: You need to run a msgbase index rebuild utility."); + IndexErrorExit(); + } + + // Detect USERS.BBS format unless user has configured it + if(__HUDSON and (ra2usersbbs == 0)) { + + // Get size of USERS.BBS + long len = filelength(fhusr); + + // Does size match Hudson format? + int hudsmatch = (len % sizeof(HudsUsers)) == 0; + if(hudsmatch) + ra2usersbbs = 1; + + // Does size match RA2 format? + int ra2match = (len % sizeof(RA2Users)) == 0; + if(ra2match) + ra2usersbbs = 2; + + // If it matches both of them + if(hudsmatch AND ra2match) { + + // Check version in CONFIG.RA to make sure + Path rapath, file; + char* ptr = getenv("RA"); + if(ptr) + AddBackslash(strcpy(rapath, ptr)); + MakePathname(file, rapath, "messages.ra"); + int fh = ::sopen(file, O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(fh != -1) { + word VersionID = 0; + read(fh, &VersionID, sizeof(word)); + if(VersionID >= 0x200) + ra2usersbbs = 2; + else + ra2usersbbs = 1; + ::close(fh); + } + } + + // If it does not match either of them + if(NOT hudsmatch AND NOT ra2match) { + WideLog->ErrIndex(); + WideLog->printf("! The users.bbs file has an incorrect size."); + WideLog->printf(": %susers.bbs, %lu bytes.", path, len); + WideLog->printf(": Should be %lu bytes if it's in RA2 format.", (len/(long)sizeof(RA2Users))*(long)sizeof(RA2Users)); + WideLog->printf(": Should be %lu bytes if it's in Hudson format.", (len/(long)sizeof(HudsUsers))*(long)sizeof(HudsUsers)); + if(ra2usersbbs) + WideLog->printf(": It appears to be in %s format.", (ra2usersbbs == 2) ? "RA2" : "Hudson"); + WideLog->printf("+ Advice: Run a userbase packing utility."); + IndexErrorExit(); + } + } + + if(__HUDSON) { + fhuix = fhuxi = -1; + if(ra2usersbbs == 2) { + if(WideDebug) + WideLog->printf("- Using a RA2 format userbase."); + user = new RA2User; + } + else { + if(WideDebug) + WideLog->printf("- Using a Hudson format userbase."); + user = new HudsonUser; + } + } + else + user = new GoldbaseUser; + throw_new(user); + + // Open RA2 files + if(__HUDSON and (ra2usersbbs == 2)) { + RA2User* _user2 = (RA2User*)user; + _user2->idxfh = fhuix = test_open("usersidx.bbs", O_CREAT); + _user2->xifh = fhuxi = test_open("usersxi.bbs", O_CREAT); + } + + // Find user + const char* _username = WideUsername[0]; + if(userno == -1) { + user->fh = fhusr; + user->find(_username); + if(NOT user->found) { + WideLog->printf("* User \"%s\" not found in %susers%s.", _username, path, __HUDSON ? HUDS_EXT : GOLD_EXT); + user->add(_username); + WideLog->printf("* Now added with user number %u.", user->index); + } + userno = user->index; + } + + if(WideDebug) + WideLog->printf("- Using user record number %u.", userno); + + // Close RA2 files + if(__HUDSON and (ra2usersbbs == 2)) { + ::close(fhuix); + ::close(fhuxi); + } + + // Unlock and close + unlock(); + raw_close(); + + if(WideDebug) + WideLog->printf("- End init for %s.", path); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::save_lastread(board_t board, msgn_t msgno) { + + GFTRK("HudsSaveLast"); + + // Update lastread record + msgn_t _lastread = lastrec[board-1] = msgno; + lseekset(fhlrd, (long)userno*(long)sizeof(HudsLast)); + write(fhlrd, lastrec, sizeof(HudsLast)); + + // Update user record + user->fh = fhusr; + user->moveto(userno); + if(user->lastread() < _lastread) + user->lastread(_lastread); + if(timesposted) { + user->inctimesposted(timesposted); + timesposted = 0; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::open() { + + GFTRK("HudsOpen"); + + data_open(); + wide->isopen++; + if(wide->isopen == 1) { + wide->raw_open(); + wide->refresh(); + wide->timesposted = 0; + } + if(wide->isopen > 2) { + WideLog->ErrTest(); + goto error; + } + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + goto error; + } + + scan(); + goto done; + +error: + WideLog->printf("! Trying to open a %s msgbase more than twice.", __HUDSON ? HUDS_NAME : GOLD_NAME); + WideLog->printf(": %s, board %u.", echoid(), board()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + +done: + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::close() { + + GFTRK("HudsClose"); + + if(isopen) { + if(isopen == 1) { + wide->save_lastread((board_t)board(), (msgn_t)Msgn->CvtReln(lastread)); + Msgn->Reset(); + } + isopen--; + } + else { + WideLog->ErrTest(); + goto error; + } + + if(wide->isopen) { + if(wide->isopen == 1) { + if(wide->islocked) + wide->unlock(); + wide->raw_close(); + throw_release(wide->msgidxptr); + } + wide->isopen--; + } + else { + WideLog->ErrTest(); + goto error; + } + goto done; + +error: + WideLog->printf("! Trying to close an already closed %s msgbase.", __HUDSON ? HUDS_NAME : GOLD_NAME); + WideLog->printf(": %s, board %u.", echoid(), board()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + +done: + data_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::suspend() { + + GFTRK("HudsSuspend"); + + wide->save_lastread((board_t)board(), (msgn_t)Msgn->CvtReln(lastread)); + wide->raw_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::resume() { + + GFTRK("HudsResume"); + + wide->raw_open(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmohuds2.cpp b/goldlib/gmb3/gmohuds2.cpp new file mode 100644 index 0000000..69d2c51 --- /dev/null +++ b/goldlib/gmb3/gmohuds2.cpp @@ -0,0 +1,727 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson / Goldbase msgbase handling +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +template +void _HudsWide::raw_close() { + + GFTRK("HudsRawClose"); + + if(fhtxt != -1) ::close(fhtxt); fhtxt = -1; + if(fhhdr != -1) ::close(fhhdr); fhhdr = -1; + if(fhidx != -1) ::close(fhidx); fhidx = -1; + if(fhinf != -1) ::close(fhinf); fhinf = -1; + if(fhlrd != -1) ::close(fhlrd); fhlrd = -1; + if(fhtoi != -1) ::close(fhtoi); fhtoi = -1; + if(fhusr != -1) ::close(fhusr); fhusr = -1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +int _HudsWide::test_open(char* __file, int __oaccess) { + + GFTRK("HudsTestOpen"); + + int _fh; + long _tries = 0; + + __oaccess |= O_RDWR|O_BINARY; + + do { + + Path _testfn; + strcpy(_testfn, AddPath(path, __file)); + int _omode = (__oaccess & O_CREAT) ? S_STDRW : S_STDRD; + _fh = ::sopen(_testfn, __oaccess, WideSharemode, _omode); + if(_fh == -1) { + + if(errno == ENOENT) { + if(_tries == 0) { + __oaccess |= O_CREAT; + _tries++; + continue; + } + } + + // Request the other program to unlock + if(errno != ENOENT) + TouchFile(AddPath(path, "mbunlock.now")); + + // Tell the world + if(PopupLocked(++_tries, false, _testfn) == false) { + + // User requested to exit + WideLog->ErrOpen(); + raw_close(); + WideLog->printf("! A %s msgbase file could not be opened.", __HUDSON ? HUDS_NAME : GOLD_NAME); + WideLog->printf(": %s.", _testfn); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::raw_open(int __oaccess, int __all) { + + GFTRK("HudsRawOpen"); + + fhidx = test_open(__HUDSON ? "msgidx" HUDS_EXT : "msgidx" GOLD_EXT, __oaccess); + fhinf = test_open(__HUDSON ? "msginfo" HUDS_EXT : "msginfo" GOLD_EXT, __oaccess); + fhlrd = test_open(__HUDSON ? "lastread" HUDS_EXT : "lastread" GOLD_EXT, __oaccess); + fhtoi = test_open(__HUDSON ? "msgtoidx" HUDS_EXT : "msgtoidx" GOLD_EXT, __oaccess); + if(__all) { + fhhdr = test_open(__HUDSON ? "msghdr" HUDS_EXT : "msghdr" GOLD_EXT, __oaccess); + fhtxt = test_open(__HUDSON ? "msgtxt" HUDS_EXT : "msgtxt" GOLD_EXT, __oaccess); + fhusr = test_open(__HUDSON ? "users" HUDS_EXT : "users" GOLD_EXT, __oaccess); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::raw_open_scan() { + + GFTRK("HudsRawOpenScan"); + + raw_open(0, false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::refresh() { + + GFTRK("HudsRefresh"); + + // (Re)Allocate memory to hold the complete MSGIDX.BBS/DAT + msgidxsize = filelength(fhidx); + msgidxptr = (HudsIdx*)throw_realloc(msgidxptr, (uint)(msgidxsize+sizeof(HudsIdx))); + + // Load MSGIDX.BBS/DAT + lseek(fhidx, 0, SEEK_SET); + read(fhidx, msgidxptr, (uint)msgidxsize); + + // Load MSGINFO.BBS/DAT + lseek(fhinf, 0, SEEK_SET); + read(fhinf, &msginfo, sizeof(HudsInfo)); + + // Load LASTREAD.BBS/DAT + lseek(fhlrd, (long)userno*(long)sizeof(HudsLast), SEEK_SET); + read(fhlrd, lastrec, sizeof(HudsLast)); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::open() { + + GFTRK("HudsWideOpen"); + + isopen = 1; + iswideopen = true; + ispmscanned = false; + iswidescanned = false; + raw_open_scan(); + lock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::close() { + + GFTRK("HudsWideClose"); + + unlock(); + raw_close(); + throw_release(msgidxptr); + throw_release(pmscan); + throw_release(scn); + iswideopen = false; + isopen = 0; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::lock() { + + GFTRK("HudsLock"); + + if(NOT islocked AND WideCanLock) { + + long _tries = 0; + + // Try to get the lock + while(::lock(fhinf, sizeof(HudsInfo)+1, 1) == -1) { + + // Tell the world + if(PopupLocked(++_tries, true, AddPath(path, __HUDSON ? "msginfo" HUDS_EXT : "msginfo" GOLD_EXT)) == false) { + + // User requested to exit + WideLog->ErrLock(); + raw_close(); + WideLog->printf("! A %s msgbase file could not be locked.", __HUDSON ? HUDS_NAME : GOLD_NAME); + WideLog->printf(": %smsginfo%s.", path, __HUDSON ? HUDS_EXT : GOLD_EXT); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + + // Request the other program to unlock + TouchFile(AddPath(path, "mbunlock.now")); + } + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + // We got the lock + islocked = true; + } + + // Refresh msgbase data + refresh(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::unlock() { + + GFTRK("HudsUnlock"); + + if(islocked AND WideCanLock) { + ::unlock(fhinf, sizeof(HudsInfo)+1, 1); + islocked = false; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::lock() { + + wide->lock(); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::unlock() { + + wide->unlock(); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::scan() { + + GFTRK("HudsWideScan"); + + iswidescanned = true; + + // Alloc scan array + throw_free(scn); + scn = (HudsScan*)throw_calloc((__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD), sizeof(HudsScan)); + + // Board and scan array pointer + register int _board; + register HudsScan* _scan = scn; + + // Init wide scan array + _board = 0; + while(_board < (__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD)) { + _scan->active = msginfo.active[_board]; + _scan->lastread = lastrec[_board]; + _board++; + _scan++; + } + + // Setup MSGIDX pointer and counters + register HudsIdx* _msgidx_ptr = msgidxptr; + register uint _msgidx_count = 0; + register uint _msgidx_total = (uint)(msgidxsize/sizeof(HudsIdx)); + int _invalidboards = 0; + + // Scan the index + while(_msgidx_count < _msgidx_total) { + + // Is the msg not deleted? + if(_msgidx_ptr->msgno != (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO)) { + + register int _idxboard = _msgidx_ptr->board; + if(_idxboard AND (_idxboard <= (__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD))) { + + _scan = scn + (_idxboard - 1); + + // Get message number + _scan->lastmsgno = _msgidx_ptr->msgno; + _scan->count++; + + // Set first message number + if(NOT _scan->firstmsgno) + _scan->firstmsgno = _scan->lastmsgno; + + // Set lastread pointer + if((_scan->lastmsgno >= _scan->lastread) AND (_scan->lastreadreln == 0)) { + _scan->lastreadfound = _scan->lastmsgno; + _scan->lastreadreln = _scan->count - (_scan->lastmsgno != _scan->lastread ? 1 : 0); + } + } + else { + _invalidboards++; + } + } + + // Go to next record + _msgidx_count++; + _msgidx_ptr++; + } + + if(_invalidboards) { + WideLog->printf("! Found %u msgs with an invalid board number (0 or >%u).", _invalidboards, (__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD)); + WideLog->printf("! In the %s msgbase at %s.", __HUDSON ? HUDS_NAME : GOLD_NAME, path); + WideLog->printf(": Info: Your msgbase may be partially corrupted."); + WideLog->printf("+ Advice: Run a msgbase index rebuild/recover utility."); + } + + // Check/fix boards + _board = 0; + _scan = scn; + while(_board < (__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD)) { + + // Check/fix lastreads + if(_scan->count AND (_scan->lastreadfound != _scan->lastread)) { + if(_scan->lastread > _scan->lastmsgno) + _scan->lastreadreln = _scan->count; + else if(_scan->lastread < _scan->firstmsgno) + _scan->lastreadreln = 0; + } + + if(WideDebug) { + WideLog->printf("- b:%u: t:%u, l:%u, fm:%lu, hm:%lu, lr:%lu, u:%u", + _board, + _scan->count, + _scan->lastreadreln, + _scan->firstmsgno, + _scan->lastmsgno, + _scan->lastread, + userno + ); + } + + // Check active message count and log it if different + if(_scan->active != _scan->count) { + WideLog->printf("! Counted %u active msgs in %s board %u.", _scan->count, __HUDSON ? HUDS_NAME : GOLD_NAME, _board+1); + WideLog->printf("! According to msginfo%s there should be %u active msgs.", __HUDSON ? HUDS_EXT : GOLD_EXT, _scan->active); + WideLog->printf(": Info: A program did not update msginfo%s correctly.", __HUDSON ? HUDS_EXT : GOLD_EXT); + WideLog->printf("+ Advice: Run a msgbase index rebuild utility."); + } + + _board++; + _scan++; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::raw_scan(int __keep_index) { + + GFTRK("HudsRawScan"); + + if(!wide) + wide = (HudsWide*) (__HUDSON ? (void *)hudsonwide : (void *)goldbasewide); + + if(wide->iswideopen AND NOT wide->iswidescanned) + wide->scan(); + + // Get wide scan data if any + if(wide->scn) { + + // Update area data + register HudsScan* _scan = wide->scn + (board() - 1); + Msgn->SetCount(_scan->count); + lastread = _scan->lastreadreln; + lastreadentry = _scan->lastreadfound; + } + else { + + // Open the msgbase if it wasn't already + int _was_open = wide->isopen; + if(NOT _was_open) + wide->open(); + + // Get the number of active msgs in the area + register board_t _board = (board_t)board(); + register uint _active = wide->msginfo.active[_board-1]; + register msgn_t _lastread = wide->lastrec[_board-1]; + + // Setup pointers and counts + register uint _msg_count = 0; + register HudsIdx* _msgidx_ptr = wide->msgidxptr; + register uint _msgidx_count = 0; + register uint _msgidx_total = (uint)(wide->msgidxsize/sizeof(HudsIdx)); + register uint _lastread_reln = 0; + + // (Re)Allocate index + if(__keep_index) + Msgn->Resize(_active); + + // Index pointers + register ulong* _msgno_ptr = Msgn->tag; + + // Fill index + register ulong _firstmsgno = 0; + register ulong _lastmsgno = 0; + register ulong _lastreadfound = 0; + while(_msgidx_count < _msgidx_total) { + + // Is it our board and is the msg not deleted? + if((_msgidx_ptr->board == _board) AND (_msgidx_ptr->msgno != (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO))) { + + // Get message number + _lastmsgno = _msgidx_ptr->msgno; + _msg_count++; + + // Set first message number + if(NOT _firstmsgno) + _firstmsgno = _lastmsgno; + + // Transfer data to the index + if(__keep_index) + *_msgno_ptr++ = _lastmsgno; + + // Set lastread pointer + if((_lastmsgno >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = _lastmsgno; + _lastread_reln = _msg_count - (_lastmsgno != _lastread ? 1 : 0); + } + + // Break loop as soon as we have all we need + if(_msg_count == _active) + break; + } + + // Go to next record + _msgidx_count++; + _msgidx_ptr++; + } + + // If the exact lastread was not found + if(_msg_count AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _msg_count; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + + // Check active message count and log it if different + if(_active != _msg_count) { + WideLog->printf("! Counted %u active msgs in %s board %u (%s).", _msg_count, __HUDSON ? HUDS_NAME : GOLD_NAME, board(), echoid()); + WideLog->printf("! According to msginfo%s there should be %u active msgs.", __HUDSON ? HUDS_EXT : GOLD_EXT, _active); + WideLog->printf(": Info: A program did not update msginfo%s correctly.", __HUDSON ? HUDS_EXT : GOLD_EXT); + WideLog->printf("+ Advice: Run a msgbase index rebuild utility."); + } + + // Update area data + Msgn->SetCount(_msg_count); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + if(WideDebug) { + WideLog->printf("- b:%u: t:%u, l:%u, fm:%lu, hm:%lu, lr:%lu, u:%u", + board(), + Msgn->Count(), + lastread, + _firstmsgno, + _lastmsgno, + (ulong)_lastread, + wide->userno + ); + } + + // Close the msgbase again if we opened it in here + if(NOT _was_open) + wide->close(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::scan() { + + GFTRK("HudsScan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::scan_area() { + + GFTRK("HudsScanArea"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +#define HudsIdxCmp(a,b) ((a.board-b.board != 0) ? a.board-b.board : ((int)(a.msgno-b.msgno))) + + +// ------------------------------------------------------------------ + +#define TOIDXBUFSZ 100u +#define PMSCANBUFSZ 50u + +template +void _HudsWide::realloc_pm_scan() { + + pmscan = (HudsIdx*)throw_realloc(pmscan, (pmscantotal+PMSCANBUFSZ)*sizeof(HudsIdx)); +} + + +// ------------------------------------------------------------------ + +template +void _HudsWide::scan_pm() { + + GFTRK("HudsWideScanPM"); + + if(NOT iswidescanned) + scan(); + + ispmscanned = true; + + HudsToIdx* toidxbuf = (HudsToIdx*)throw_calloc(TOIDXBUFSZ, sizeof(HudsToIdx)); + uint totrecs = (uint)(filelength(fhtoi) / sizeof(HudsToIdx)); + HudsIdx* idxptr = msgidxptr; + throw_release(pmscan); + pmscantotal = 0; + int invalidboards = 0; + int gotpm, idxboard, umax, u; + uint getrecs, rec; + HudsToIdx* toidx; + + do { + + rec = 0; + gotpm = false; + getrecs = MinV(TOIDXBUFSZ, totrecs); + read(fhtoi, toidxbuf, getrecs*sizeof(HudsToIdx)); + + for(toidx=toidxbuf; recmsgno == (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO)) + continue; + + // Skip msgs in invalid boards + idxboard = idxptr->board; + if(NOT(idxboard AND (idxboard <= (__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD)))) { + invalidboards++; + continue; + } + + // If after lastread + if(idxptr->msgno <= scn[idxboard-1].lastreadfound) + continue; + + // Convert name string + strnp2c(toidx->name, sizeof(HudsToIdx)-1); + + // Is it a PM? + umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; + for(u=0; uname, WideUsername[u])) { + gotpm = true; + break; + } + } + + if(gotpm) { + if((pmscantotal % PMSCANBUFSZ) == 0) + realloc_pm_scan(); + pmscan[pmscantotal++] = *idxptr; + scn[idxboard-1].pmcount++; + gotpm = false; + } + } + totrecs -= getrecs; + } while(totrecs); + + throw_free(toidxbuf); + pmscan = (HudsIdx*)throw_realloc(pmscan, (pmscantotal+1)*sizeof(HudsIdx)); + + // Sort all pm records in board/msgno order + for(uint k=pmscantotal >> 1; k; k >>= 1) + for(uint i=k; i < pmscantotal; i++) + for(uint j=i-k; (j >= 0) and HudsIdxCmp(pmscan[j], pmscan[j+k]) > 0; j-=k) { + HudsIdx e = pmscan[j]; + pmscan[j] = pmscan[j+k]; + pmscan[j+k] = e; + } + + if(invalidboards) { + WideLog->printf("! Found %u msgs with an invalid board number (0 or >%u).", invalidboards, (__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD)); + WideLog->printf("! In the %s msgbase at %s.", __HUDSON ? HUDS_NAME : GOLD_NAME, path); + WideLog->printf(": Info: Your msgbase may be partially corrupted."); + WideLog->printf("+ Advice: Run a msgbase index rebuild/recover utility."); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::scan_area_pm() { + + GFTRK("HudsScanAreaPM"); + + PMrk->ResetAll(); + + if(!wide) + wide = (HudsWide*) (__HUDSON ? (void *)hudsonwide : (void *)goldbasewide); + + if(wide->iswideopen AND NOT wide->ispmscanned) + wide->scan_pm(); + + // Get wide scan data if any + if(wide->scn) { + + register board_t _board = (board_t)board(); + register HudsScan* _scan = wide->scn + (_board - 1); + + if(wide->pmscan) { + if(_scan->pmcount) { + + register HudsIdx* pmscanptr = wide->pmscan; + while(pmscanptr->board != _board) + pmscanptr++; + + register uint n = 0; + register uint cnt = _scan->pmcount; + while(n < cnt) { + PMrk->Append(pmscanptr->msgno); + pmscanptr++; + n++; + } + } + } + + // Update area data + Msgn->SetCount(_scan->count); + lastread = _scan->lastreadreln; + lastreadentry = _scan->lastreadfound; + + if(WideDebug) { + WideLog->printf("- b:%u: t:%u, l:%u, fm:%lu, hm:%lu, lr:%lu, u:%u, pm:%i", + _board, + _scan->count, + _scan->lastreadreln, + _scan->firstmsgno, + _scan->lastmsgno, + _scan->lastread, + wide->userno, + PMrk->Count() + ); + } + + } + else { + if(WideDebug) + WideLog->printf("- Oops! Fell into empty bracket."); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmohuds3.cpp b/goldlib/gmb3/gmohuds3.cpp new file mode 100644 index 0000000..33c152e --- /dev/null +++ b/goldlib/gmb3/gmohuds3.cpp @@ -0,0 +1,238 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson / Goldbase msgbase handling +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +template +msgn_t _HudsArea::get_hdr_idx(gmsg* __msg, char* __file__, int __line__) { + + GFTRK("HudsGetHdrIdx"); + + msgn_t _count = 0; + msgn_t _total = (msgn_t)(wide->msgidxsize/sizeof(HudsIdx)); + HudsIdx* _msgidx_ptr = wide->msgidxptr; + + register ulong _msgno = __msg->msgno; + if(_msgidx_ptr) { + while(_count <= _total) { + if(_msgno == _msgidx_ptr->msgno) { + GFTRK(NULL); + return _count; + } + _msgidx_ptr++; + _count++; + } + } + + // Report error + ulong _lmsgno = lastread ? Msgn->at(lastread-1) : Msgn->at(0); + ulong _lread = wide->lastrec[board()-1]; + ulong _active = wide->msginfo.active[board()-1]; + WideLog->errindex(__file__, __line__); + WideLog->printf("! Failed to locate a msgno in an internal %s index.", __HUDSON ? HUDS_NAME : GOLD_NAME); + WideLog->printf(": Msgno %lu (%lXh) in board %u (%s,%u,%u).", _msgno, _msgno, board(), echoid(), Msgn->Count(), lastread); + WideLog->printf(": First Msgno : %lu (%lXh).", Msgn->at(0), Msgn->at(0)); + WideLog->printf(": Msgno at lastread : %lu (%lXh).", _lmsgno, _lmsgno); + WideLog->printf(": Real lastread msg : %lu (%lXh).", _lread, _lread); + WideLog->printf(": Real active msgs : %lu (%lXh).", _active, _active); + if(Msgn->Count() > 2) { + _lmsgno = Msgn->at(Msgn->Count()-3); + WideLog->printf(": Highest-2 msgno : %lu (%lXh).", _lmsgno, _lmsgno); + } + if(Msgn->Count() > 1) { + _lmsgno = Msgn->at(Msgn->Count()-2); + WideLog->printf(": Highest-1 msgno : %lu (%lXh).", _lmsgno, _lmsgno); + } + if(Msgn->Count()) { + _lmsgno = Msgn->at(Msgn->Count()-1); + WideLog->printf(": Highest msgno : %lu (%lXh).", _lmsgno, _lmsgno); + } + if(_msgno == 0xEEEEEEEEL) { + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + } + WideLog->printf("+ Advice: Restart or run a msgbase index rebuild utility."); + IndexErrorExit(); + + GFTRK(NULL); + + return (msgn_t)(__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO); +} + + +// ------------------------------------------------------------------ + +template +int _HudsArea::load_message(int __mode, gmsg* __msg, HudsHdr& __hdr) { + + if(__msg->msgno == 0) { + GFTRK(NULL); + return false; + } + + // Read header + msgn_t _hdridx = get_hdr_idx(__msg, __FILE__, __LINE__); + lseek(wide->fhhdr, (long)_hdridx*(long)sizeof(HudsHdr), SEEK_SET); + read(wide->fhhdr, &__hdr, sizeof(HudsHdr)); + + __msg->msgno = __hdr.msgno; + __msg->link.to_set(__hdr.replyto); + __msg->link.first_set(__hdr.reply1st); + + __msg->cost = __hdr.cost; + __msg->board = __hdr.board; + __msg->timesread = __hdr.timesread; + + strnp2cc(__msg->by, __hdr.by, 35); + strnp2cc(__msg->to, __hdr.to, 35); + strnp2cc(__msg->re, __hdr.re, 72); + + __msg->orig.zone = __msg->oorig.zone = __hdr.origzone; + __msg->orig.net = __msg->oorig.net = __hdr.orignet; + __msg->orig.node = __msg->oorig.node = __hdr.orignode; + __msg->orig.point = __msg->oorig.point = 0; + + __msg->dest.zone = __msg->odest.zone = __hdr.destzone; + __msg->dest.net = __msg->odest.net = __hdr.destnet; + __msg->dest.node = __msg->odest.node = __hdr.destnode; + __msg->dest.point = __msg->odest.point = 0; + + // Convert date and time + int _year, _month, _day, _hour, _minute; + sscanf(__hdr.date+1, "%d%*c%d%*c%2d", &_month, &_day, &_year); + sscanf(__hdr.time+1, "%d%*c%2d", &_hour, &_minute); + struct tm _tm; + _tm.tm_year = (_year < 80) ? (_year+100) : _year; + _tm.tm_mon = _month - 1; + _tm.tm_mday = _day; + _tm.tm_hour = _hour; + _tm.tm_min = _minute; + _tm.tm_sec = 0; + _tm.tm_isdst = -1; + time_t a = mktime(&_tm); + time_t b = mktime(gmtime(&a)); + __msg->written = a + a - b; + __msg->arrived = 0; + + // Convert attributes + __msg->attr.del(__hdr.msgattr & HUDS_DELETED); + __msg->attr.pvt(__hdr.msgattr & HUDS_PVT); + __msg->attr.rcv(__hdr.msgattr & HUDS_RECEIVED); + __msg->attr.loc(__hdr.msgattr & HUDS_LOCAL); + __msg->attr.grp(__hdr.msgattr & HUDS_GROUPMSG); + __msg->attr.k_s(__hdr.netattr & HUDS_KILLSENT); + __msg->attr.att(__hdr.netattr & HUDS_ATTACH); + __msg->attr.cra(__hdr.netattr & HUDS_CRASH); + __msg->attr.rrq(__hdr.netattr & HUDS_RETRECREQ); + __msg->attr.arq(__hdr.netattr & HUDS_AUDITREQ); + __msg->attr.rrc(__hdr.netattr & HUDS_RETREC); + __msg->attr.frq(__hdr.netattr & HUDS_FREQ); + __msg->attr.uns((__hdr.netattr & HUDS_SENT) ? 0 : ((__hdr.msgattr & (HUDS_NETTRANS|HUDS_ECHOTRANS)) ? 1 : 0)); + __msg->attr.snt(__msg->attr.loc() and not (__msg->attr.uns() or __msg->attr.rcv())); + + __msg->txtstart = __hdr.startrec; + __msg->txtlength = __hdr.numrecs; + + // If message text is used + if(__mode & GMSG_TXT) { + + // Get length of message text and adjust if necessary + uint _numrecs = __hdr.numrecs; + long _txtlen = (long)(_numrecs+1)*256L; + if(_txtlen > WideMsgSize) { + _txtlen = WideMsgSize; + _numrecs = (uint)(_txtlen/256L); + } + + // Allocate memory for message text + __msg->txt = (char*)throw_realloc(__msg->txt, (_numrecs+1)*256); + *__msg->txt = NUL; + + // Read message text and convert it to a NUL-terminated C string + if(_numrecs) { + + // Seek to, and read the raw text + lseek(wide->fhtxt, (long)__hdr.startrec*256L, SEEK_SET); + read(wide->fhtxt, __msg->txt, _numrecs*256); + + // Set up loop variables + char* _src = __msg->txt; + char* _dst = _src; + uint _count = 0; + + // Conversion loop + while(_count++ < _numrecs) { + + // Get block length + byte _len = *_src++; + + // Move text over the length byte + memmove(_dst, _src, _len); + + // Move pointers + _dst += _len; + _src += _len; + } + + // NUL-terminate the text + *_dst = NUL; + } + } + + GFTRK(NULL); + + return true; +} + + +// ------------------------------------------------------------------ + +template +int _HudsArea::load_hdr(gmsg* __msg) { + + GFTRK("HudsLoadHdr"); + + HudsHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +template +int _HudsArea::load_msg(gmsg* __msg) { + + GFTRK("HudsLoadMsg"); + + HudsHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmohuds4.cpp b/goldlib/gmb3/gmohuds4.cpp new file mode 100644 index 0000000..1757bf7 --- /dev/null +++ b/goldlib/gmb3/gmohuds4.cpp @@ -0,0 +1,373 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson / Goldbase msgbase handling +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +template +void _HudsWide::update_netecho(char* __name, msgn_t __hdridx, int __delete) { + + GFTRK("HudsUpdateNetEcho"); + + Path name; + strcpy(name, AddPath(syspath, __name)); + int _fh = test_open(name, O_CREAT); + + // Get size of the file + uint _total = (uint)(filelength(_fh)/sizeof(msgn_t)); + + // Allocate memory for the scanning index + msgn_t* _scanidx = (msgn_t*)throw_calloc(_total+5, sizeof(msgn_t)); + + // Read the scanning index + read(_fh, _scanidx, _total*sizeof(msgn_t)); + + // Close the file + ::close(_fh); + + // Search for the specified header index + uint _pos = 0; + uint _closest = 0; + while(_pos < _total) { + if(_scanidx[_pos] <= __hdridx) + _closest = _pos; + if(_scanidx[_pos] == __hdridx) + break; + _pos++; + } + + // Delete or add the header index + if(__delete) { + if(_pos < _total) { + memmove(_scanidx+_pos, _scanidx+_pos+1, (_total-_pos-1)*sizeof(msgn_t)); + _total--; + } + } + else { + if(_scanidx[_closest] != __hdridx) { + _scanidx[_total++] = __hdridx; + for(uint k=_total >> 1; k; k >>= 1) + for(uint i=k; i < _total; i++) + for(uint j=i-k; (j >= 0) and CmpV(_scanidx[j], _scanidx[j+k]) > 0; j-=k) { + msgn_t e = _scanidx[j]; + _scanidx[j] = _scanidx[j+k]; + _scanidx[j+k] = e; + } + } + } + + // Write the changed scanning file from scratch + if(_total) { + _fh = test_open(__name, O_CREAT|O_TRUNC); + write(_fh, _scanidx, _total*sizeof(msgn_t)); + ::close(_fh); + } + else { + // If the last header index was removed, delete the file + remove(__name); + } + + // Free the memory + throw_free(_scanidx); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::save_message(int __mode, gmsg* __msg, HudsHdr& __hdr) { + + // Lock msgbase before doing anything + int _was_locked = wide->islocked; + if(NOT _was_locked) + lock(); + + // Find header index + msgn_t _hdridx; + if(__mode & GMSG_NEW) { + __msg->msgno = wide->msginfo.high + 1; + _hdridx = (msgn_t)(filelength(wide->fhhdr)/(long)sizeof(HudsHdr)); + } + else { + _hdridx = get_hdr_idx(__msg, __FILE__, __LINE__); + } + + __hdr.board = (board_t)board(); + __hdr.msgno = (msgn_t)__msg->msgno; + __hdr.replyto = (msgn_t)__msg->link.to(); + __hdr.reply1st = (msgn_t)__msg->link.first(); + + struct tm* _tmp = gmtime(&__msg->written); + strc2p(strftimei(__hdr.date, 9, "%m-%d-%y", _tmp)); + strc2p(strftimei(__hdr.time, 6, "%H:%M", _tmp)); + + strc2p(strxcpy(__hdr.to, __msg->to, sizeof(__hdr.to))); + strc2p(strxcpy(__hdr.by, __msg->by, sizeof(__hdr.by))); + strc2p(strxcpy(__hdr.re, __msg->re, sizeof(__hdr.re))); + + __hdr.origzone = (byte)__msg->oorig.zone; + __hdr.orignet = __msg->oorig.net; + __hdr.orignode = __msg->oorig.node; + + __hdr.destzone = (byte)__msg->odest.zone; + __hdr.destnet = __msg->odest.net; + __hdr.destnode = __msg->odest.node; + + __hdr.cost = (word)__msg->cost; + __hdr.timesread = (word)__msg->timesread; + + // Transfer attributes + __hdr.msgattr = __hdr.netattr = 0; + __hdr.msgattr |= (byte)(__msg->attr.del() ? HUDS_DELETED : 0); + __hdr.msgattr |= (byte)(__msg->attr.pvt() ? HUDS_PVT : 0); + __hdr.msgattr |= (byte)(__msg->attr.rcv() ? HUDS_RECEIVED : 0); + __hdr.msgattr |= (byte)(__msg->attr.loc() ? HUDS_LOCAL : 0); + __hdr.msgattr |= (byte)(__msg->attr.grp() ? HUDS_GROUPMSG : 0); + __hdr.netattr |= (byte)(__msg->attr.k_s() ? HUDS_KILLSENT : 0); + __hdr.netattr |= (byte)(__msg->attr.snt() ? HUDS_SENT : 0); + __hdr.netattr |= (byte)(__msg->attr.att() ? HUDS_ATTACH : 0); + __hdr.netattr |= (byte)(__msg->attr.cra() ? HUDS_CRASH : 0); + __hdr.netattr |= (byte)(__msg->attr.rrq() ? HUDS_RETRECREQ : 0); + __hdr.netattr |= (byte)(__msg->attr.arq() ? HUDS_AUDITREQ : 0); + __hdr.netattr |= (byte)(__msg->attr.rrc() ? HUDS_RETREC : 0); + __hdr.netattr |= (byte)(__msg->attr.frq() ? HUDS_FREQ : 0); + if(isnet()) + __hdr.msgattr |= HUDS_NETMSG; + if(__msg->attr.uns()) { + if(isnet()) + __hdr.msgattr |= HUDS_NETTRANS; + else if(isecho()) + __hdr.msgattr |= HUDS_ECHOTRANS; + } + + if(__mode & GMSG_DELETE) + __hdr.msgattr |= HUDS_DELETED; + + __hdr.startrec = (msgn_t)__msg->txtstart; + __hdr.numrecs = (word)__msg->txtlength; + + // Write to MSGTXT.BBS/DAT + if(__mode & GMSG_TXT) { + + // If the msg is new or the text is too large to fit + uint _txtlen = strlen(__msg->txt)+1; + if((__mode & GMSG_NEW) OR (_txtlen > ((long)__msg->txtlength*255L))) + __hdr.startrec = (msgn_t)(filelength(wide->fhtxt)/256L); + + // Calculate the number of text records to write + register uint _fullrecs = _txtlen / 255; + register byte _extrarec = (byte)(_txtlen % 255); + __hdr.numrecs = (word)(_fullrecs + (_extrarec ? 1 : 0)); + + // Seek to the text write position + lseek(wide->fhtxt, (long)__hdr.startrec*256L, SEEK_SET); + + // Write the message text + register uint _count = 0; + register char* _txt = __msg->txt; + char _txtbuf[256]; + char* _txtptr = _txtbuf + 1; + *_txtbuf = 255; + while(_count < _fullrecs) { + memcpy(_txtptr, _txt, 255); + write(wide->fhtxt, _txtbuf, 256); + _txt += 255; + _count++; + } + if(_extrarec) { + *_txtbuf = _extrarec; + memset(_txtptr, 0, 255); + memcpy(_txtptr, _txt, _extrarec); + write(wide->fhtxt, _txtbuf, 256); + } + } + + // Write to MSGHDR.BBS/DAT + lseek(wide->fhhdr, (long)_hdridx*(long)sizeof(HudsHdr), SEEK_SET); + write(wide->fhhdr, &__hdr, sizeof(HudsHdr)); + + // Write to MSGIDX.BBS/DAT + if(__mode & GMSG_NEW) { + wide->msgidxsize += sizeof(HudsIdx); + wide->msgidxptr = (HudsIdx*)throw_realloc(wide->msgidxptr, (uint)(wide->msgidxsize+sizeof(HudsIdx))); + } + HudsIdx* _idxp = wide->msgidxptr + (uint)_hdridx; + _idxp->board = __hdr.board; + _idxp->msgno = (msgn_t)((__mode & GMSG_DELETE) ? (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO) : __hdr.msgno); + lseek(wide->fhidx, (long)_hdridx*(long)sizeof(HudsIdx), SEEK_SET); + write(wide->fhidx, _idxp, sizeof(HudsIdx)); + + // Write to MSGTOIDX.BBS/DAT + lseek(wide->fhtoi, (long)_hdridx*(long)sizeof(HudsToIdx), SEEK_SET); + if(__mode & GMSG_DELETE) + write(wide->fhtoi, "\xB* Deleted *\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(HudsToIdx)); + else if(__hdr.msgattr & HUDS_RECEIVED) + write(wide->fhtoi, "\xC* Received *\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(HudsToIdx)); + else + write(wide->fhtoi, __hdr.to, sizeof(HudsToIdx)); + + // Write to MSGINFO.BBS/DAT + if(__mode & GMSG_DELETE) { + wide->msginfo.total--; + wide->msginfo.active[__hdr.board-1]--; + if(__hdr.msgno == wide->msginfo.low) { + register uint _count = 0; + register msgn_t _total = (msgn_t)(wide->msgidxsize/sizeof(HudsIdx)); + register HudsIdx* _msgidx_ptr = wide->msgidxptr; + while((_count++) < _total) { + if(_msgidx_ptr->msgno != (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO)) { + wide->msginfo.low = _msgidx_ptr->msgno; + break; + } + _msgidx_ptr++; + } + } + if(__hdr.msgno == wide->msginfo.high) { + register uint _count = (uint)(wide->msgidxsize/sizeof(HudsIdx)); + register HudsIdx* _msgidx_ptr = wide->msgidxptr + (_count-1); + while(_count--) { + if(_msgidx_ptr->msgno != (__HUDSON ? HUDS_DELETEDMSGNO : GOLD_DELETEDMSGNO)) { + wide->msginfo.high = _msgidx_ptr->msgno; + break; + } + _msgidx_ptr--; + } + } + } + else if(__mode & GMSG_NEW) { + wide->msginfo.total++; + wide->msginfo.active[__hdr.board-1]++; + if(__hdr.msgno < wide->msginfo.low) + wide->msginfo.low = __hdr.msgno; + if(__hdr.msgno > wide->msginfo.high) + wide->msginfo.high = __hdr.msgno; + } + lseek(wide->fhinf, 0, SEEK_SET); + write(wide->fhinf, &wide->msginfo, sizeof(HudsInfo)); + + // Update scanning files + if((__hdr.msgattr & HUDS_NETTRANS) OR (__mode & GMSG_DELETE)) + wide->update_netecho(__HUDSON ? "netmail" HUDS_EXT : "netmail" GOLD_EXT, _hdridx, __hdr.msgattr & HUDS_DELETED); + if((__hdr.msgattr & HUDS_ECHOTRANS) OR (__mode & GMSG_DELETE)) + wide->update_netecho(__HUDSON ? "echomail" HUDS_EXT : "echomail" GOLD_EXT, _hdridx, __hdr.msgattr & HUDS_DELETED); + + if(__mode & GMSG_NEW) { + + // Count our msgs + wide->timesposted++; + + // Add new msgno to index + Msgn->Append(__msg->msgno); + } + + // Unlock msgbase after use + if(NOT _was_locked) + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("HudsSaveHdr"); + + HudsHdr _hdr; + save_message(__mode|GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("HudsSaveMsg"); + + HudsHdr _hdr; + save_message(__mode|GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::del_msg(gmsg* __msg) { + + GFTRK("HudsDelMsg"); + + HudsHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::new_msgno(gmsg* __msg) { + + GFTRK("HudsNewMsgno"); + + __msg->msgno = wide->msginfo.high + 1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +template +void _HudsArea::update_timesread(gmsg* msg) { + + GFTRK("HudsArea::update_timesread"); + + lock(); + + msgn_t hdridx = get_hdr_idx(msg, __FILE__, __LINE__); + ::lseekset(wide->fhhdr, (long)hdridx*(long)sizeof(HudsHdr)); + + HudsHdr hdr; + ::read(wide->fhhdr, &hdr, sizeof(HudsHdr)); + + hdr.timesread = (word)msg->timesread; + + ::lseekset(wide->fhhdr, (long)hdridx*(long)sizeof(HudsHdr)); + ::write(wide->fhhdr, &hdr, sizeof(HudsHdr)); + + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmohuds5.cpp b/goldlib/gmb3/gmohuds5.cpp new file mode 100644 index 0000000..91a0847 --- /dev/null +++ b/goldlib/gmb3/gmohuds5.cpp @@ -0,0 +1,137 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alex. S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Hudson / Goldbase msgbase handling +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +template +char* _HudsArea::user_lookup(char* __lookfor) { + + wide->user->fh = wide->fhusr; + wide->user->findwild(__lookfor, __lookfor); + + if(wide->user->found) + return __lookfor; + else + return NULL; +} + + +// ------------------------------------------------------------------ + +template +int _HudsArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ + +template +Line* _HudsArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) { + + GFTRK("HudsMakeDump"); + + HudsHdr _hdr; + load_message(GMSG_HDRTXT, msg, _hdr); + + strnp2c(_hdr.date,9); + strnp2c(_hdr.time,5); + + char buf[100]; + Line* line = lin = + AddLine (NULL, __HUDSON ? "Hexdump of " HUDS_NAME " message header and text" : "Hexdump of " GOLD_NAME " message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Msgbase : %s", wide->path); + AddLineF(line, "BoardNo : %u", board()); + AddLineF(line, "From : %-35.35s", msg->by); + AddLineF(line, "To : %-35.35s", msg->to); + AddLineF(line, "Subject : %-72.72s", msg->re); + AddLineF(line, "DateTime : %8.8s %5.5s", _hdr.date, _hdr.time); + AddLineF(line, "OrigAddr : %u:%u/%u", _hdr.origzone, _hdr.orignet, _hdr.orignode); + AddLineF(line, "DestAddr : %u:%u/%u", _hdr.destzone, _hdr.destnet, _hdr.destnode); + AddLineF(line, "Reply : %lu", (ulong)_hdr.replyto); + AddLineF(line, "See : %lu", (ulong)_hdr.reply1st); + AddLineF(line, "TimesRead : %u", _hdr.timesread); + AddLineF(line, "Cost : %u", _hdr.cost); + AddLineF(line, "MsgAttr : %02Xh (%sb)", _hdr.msgattr, ltob(buf, _hdr.msgattr, 8)); + AddLineF(line, "NetAttr : %02Xh (%sb)", _hdr.netattr, ltob(buf, _hdr.netattr, 8)); + AddLineF(line, "Msgno : %lu", (long)_hdr.msgno); + AddLineF(line, "Board : %u", _hdr.board); + AddLineF(line, "StartRec : %lu", (long)_hdr.startrec); + AddLineF(line, "NumRecs : %lu", (long)_hdr.numrecs); + AddLineF(line, "UserRecno : %u (%s)", wide->userno, WideUsername[0]); + line = AddLine(line, ""); + AddLineF(line, "Dump of msginfo%s:", __HUDSON ? HUDS_EXT : GOLD_EXT); + line = AddLine(line, ""); + AddLineF(line, "Total Active : %lu (%lXh)", (ulong)wide->msginfo.total, (ulong)wide->msginfo.total); + AddLineF(line, "Low/High Msgno: %lu (%lXh) %lu (%lXh)", + (ulong)wide->msginfo.low, (ulong)wide->msginfo.low, + (ulong)wide->msginfo.high, (ulong)wide->msginfo.high + ); + for(int brd=0; brd<(__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD); brd+=10) { + AddLineF(line, "Board %03u-%03u : %5u %5u %5u %5u %5u %5u %5u %5u %5u %5u", + brd+1, brd+10, wide->msginfo.active[brd+0], + wide->msginfo.active[brd+1], wide->msginfo.active[brd+2], wide->msginfo.active[brd+3], + wide->msginfo.active[brd+4], wide->msginfo.active[brd+5], wide->msginfo.active[brd+6], + wide->msginfo.active[brd+7], wide->msginfo.active[brd+8], wide->msginfo.active[brd+9] + ); + } + line = AddLine(line, ""); + AddLineF(line, "Dump of lastread%s:", __HUDSON ? HUDS_EXT : GOLD_EXT); + line = AddLine(line, ""); + for(int lrd=0; lrd<(__HUDSON ? HUDS_MAXBOARD : GOLD_MAXBOARD); lrd+=5) { + AddLineF(line, "Board %03u-%03u : %10lu %10lu %10lu %10lu %10lu", + lrd+1, lrd+5, (ulong)wide->lastrec[lrd+0], + (ulong)wide->lastrec[lrd+1], (ulong)wide->lastrec[lrd+2], + (ulong)wide->lastrec[lrd+3], (ulong)wide->lastrec[lrd+4] + ); + } + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + int _count = 0; + char* _ptr = (char*)&_hdr; + for(;_count < sizeof(HudsHdr); _ptr+=16,_count+=16) { + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, 16, HEX_DUMP2); + line = AddLine(line, buf); + } + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, sizeof(HudsHdr)%16, HEX_DUMP2); + line = AddLine(line, buf); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmojamm.h b/goldlib/gmb3/gmojamm.h new file mode 100644 index 0000000..38f40dd --- /dev/null +++ b/goldlib/gmb3/gmojamm.h @@ -0,0 +1,328 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// JAM msgbase definitions and structures. +// ------------------------------------------------------------------ +// This implementation is based on information in the document +// JAM-001, revision 001, dated 93-07-01 and the associated example +// "JAM API". Here is the JAM copyright notice: +// +// "JAM(mbp) - Copyright 1993 Joaquim Homrighausen, Andrew Milner, +// Mats Birch, Mats Wallin. +// ALL RIGHTS RESERVED." +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GM_JAMM_H +#define __GM_JAMM_H + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// JAM constants + +#define JAM_REVISION 1 +#define JAM_SIGNATURE "JAM\0" +#define JAM_MAXDATLEN 100 + + +// ------------------------------------------------------------------ +// Message status bits + +#define JAMATTR_LOCAL 0x00000001L // Msg created locally +#define JAMATTR_INTRANSIT 0x00000002L // Msg is in-transit +#define JAMATTR_PRIVATE 0x00000004L // Private +#define JAMATTR_READ 0x00000008L // Read by addressee +#define JAMATTR_SENT 0x00000010L // Sent to remote +#define JAMATTR_KILLSENT 0x00000020L // Kill when sent +#define JAMATTR_ARCHIVESENT 0x00000040L // Archive when sent +#define JAMATTR_HOLD 0x00000080L // Hold for pick-up +#define JAMATTR_CRASH 0x00000100L // Crash +#define JAMATTR_IMMEDIATE 0x00000200L // Send Msg now, ignore restrictions +#define JAMATTR_DIRECT 0x00000400L // Send directly to destination +#define JAMATTR_GATE 0x00000800L // Send via gateway +#define JAMATTR_FILEREQUEST 0x00001000L // File request +#define JAMATTR_FILEATTACH 0x00002000L // File(s) attached to Msg +#define JAMATTR_TRUNCFILE 0x00004000L // Truncate file(s) when sent +#define JAMATTR_KILLFILE 0x00008000L // Delete file(s) when sent +#define JAMATTR_RECEIPTREQ 0x00010000L // Return receipt requested +#define JAMATTR_CONFIRMREQ 0x00020000L // Confirmation receipt requested +#define JAMATTR_ORPHAN 0x00040000L // Unknown destination +#define JAMATTR_ENCRYPT 0x00080000L // Msg text is encrypted +#define JAMATTR_COMPRESS 0x00100000L // Msg text is compressed +#define JAMATTR_ESCAPED 0x00200000L // Msg text is seven bit ASCII +#define JAMATTR_FPU 0x00400000L // Force pickup +#define JAMATTR_TYPELOCAL 0x00800000L // Msg is for local use only (not for export) +#define JAMATTR_TYPEECHO 0x01000000L // Msg is for conference distribution +#define JAMATTR_TYPENET 0x02000000L // Msg is direct network mail +#define JAMATTR_NODISP 0x20000000L // Msg may not be displayed to user +#define JAMATTR_LOCKED 0x40000000L // Msg is locked, no editing possible +#define JAMATTR_DELETED 0x80000000L // Msg is deleted + + +// ------------------------------------------------------------------ +// Message header subfield types + +#define JAMSUB_OADDRESS 0 +#define JAMSUB_DADDRESS 1 +#define JAMSUB_SENDERNAME 2 +#define JAMSUB_RECEIVERNAME 3 +#define JAMSUB_MSGID 4 +#define JAMSUB_REPLYID 5 +#define JAMSUB_SUBJECT 6 +#define JAMSUB_PID 7 +#define JAMSUB_TRACE 8 +#define JAMSUB_ENCLOSEDFILE 9 +#define JAMSUB_ENCLOSEDFILEWALIAS 10 +#define JAMSUB_ENCLOSEDFREQ 11 +#define JAMSUB_ENCLOSEDFILEWCARD 12 +#define JAMSUB_ENCLOSEDINDIRECFILE 13 +#define JAMSUB_EMBINDAT 1000 +#define JAMSUB_FTSKLUDGE 2000 +#define JAMSUB_SEENBY2D 2001 +#define JAMSUB_PATH2D 2002 +#define JAMSUB_FLAGS 2003 +#define JAMSUB_TZUTCINFO 2004 +#define JAMSUB_UNKNOWN 0xFFFF + + +// ------------------------------------------------------------------ +// .JHR file header + +struct JamHdrInfo { + + char signature[4]; // followed by + time_t datecreated; // Creation date + ulong modcounter; // Update counter + ulong activemsgs; // Number of active (not deleted) msgs + ulong passwordcrc; // CRC-32 of password to access + ulong basemsgnum; // Lowest message number in index file + ulong highwatermark; // Number of the last msg scanned + byte reserved[996]; // Reserved space +}; + + +// ------------------------------------------------------------------ +// .JHR message headers + +struct JamHdr { + + char signature[4]; // followed by + word revision; // Revision level of header + word reservedword; // Reserved for future use + ulong subfieldlen; // Length of subfields + ulong timesread; // Number of times message read + ulong msgidcrc; // CRC-32 of MSGID line + ulong replycrc; // CRC-32 of REPLY line + ulong replyto; // This msg is a reply to.. + ulong reply1st; // First reply to this msg + ulong replynext; // Next msg in reply chain + time_t datewritten; // When msg was written + time_t datereceived; // When msg was read by recipient + time_t dateprocessed; // When msg was processed by tosser/scanner + ulong messagenumber; // Message number (1-based) + ulong attribute; // Msg attribute, see "Msg Attributes" + ulong attribute2; // Reserved for future use + ulong offset; // Offset of text in ????????.JDT file + ulong txtlen; // Length of message text + ulong passwordcrc; // CRC-32 of password to access message + ulong cost; // Cost of message +}; + + +// ------------------------------------------------------------------ +// .JHR subfield headers + +struct JamSubFieldHdr { + + word loid; // Field ID, 0-65535 + word hiid; // Reserved for future use + ulong datlen; // Length of buffer that follows +}; + + +// ------------------------------------------------------------------ +// .JHR subfields + +struct JamSubField { + + word loid; // Field ID, 0-65535 + word hiid; // Reserved for future use + ulong datlen; // Length of buffer that follows + char buffer[101]; // DATLEN bytes of data +}; + + +// ------------------------------------------------------------------ +// .JDX message index + +struct JamIndex { + + dword usercrc; // CRC-32 of destination username + ulong hdroffset; // Offset of header in .JHR file +}; + + +// ------------------------------------------------------------------ +// .JLR lastread records + +struct JamLast { + + dword usercrc; // CRC-32 of user name (lowercase) + dword userid; // Unique UserID + dword lastread; // Last read message number + dword highread; // Highest read message number +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct JamData { + int fhjhr; + int fhjdt; + int fhjdx; + int fhjlr; + int islocked; // Area is locked? + int timesposted; + long lastpos; // Lastread position + JamLast lastrec; // .JLR Lastread record + JamHdrInfo hdrinfo; // .JHR Header info record +}; + + +// ------------------------------------------------------------------ + +struct JamWide { + dword usercrc; + dword userid; + int lookreplies; + const char* jampath; + int harddelete; +}; + + +// ------------------------------------------------------------------ + +class JamArea : public gmo_area { + +protected: + + JamData* data; + JamWide* wide; + + int just_scanning; + + void data_open(); + void data_close(); + + void open_area(); + + void raw_open(); + void raw_close(); + + void save_lastread(); + + int test_open(const char* file); + + void raw_scan(int __keep_index, int __scanpm=false); + + int load_message(int __mode, gmsg* __msg, JamHdr& __hdr); + + void add_subfield(JamHdr& __hdr, byte*& __subfield, word __loid, word __hiid, char* __data); + + void save_message(int __mode, gmsg* __msg, JamHdr& __hdr); + +public: + + JamArea() { wide = NULL; data = NULL; just_scanning = false; } + virtual ~JamArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern JamWide* jamwide; +extern JamData* jamdata; +extern int jamdatano; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmojamm1.cpp b/goldlib/gmb3/gmojamm1.cpp new file mode 100644 index 0000000..1da1288 --- /dev/null +++ b/goldlib/gmb3/gmojamm1.cpp @@ -0,0 +1,205 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// JAM msgbase implementation, initialization. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +JamWide* jamwide = NULL; +JamData* jamdata = NULL; +int jamdatano = 0; + + +// ------------------------------------------------------------------ + +void JamExit() { + + throw_xrelease(jamwide); + throw_xrelease(jamdata); +} + + +// ------------------------------------------------------------------ + +void JamInit(const char* jampath, int harddelete) { + + GFTRK("JamInit"); + + jamdata = (JamData*)throw_calloc(2, sizeof(JamData)); + jamwide = (JamWide*)throw_calloc(1, sizeof(JamWide)); + + jamwide->jampath = jampath; + jamwide->harddelete = harddelete; + + // Calculate CRC32 of our username for the lastreads + INam _name; + strlwr(strcpy(_name, WideUsername[0])); + jamwide->userid = jamwide->usercrc = strCrc32(_name, NO, CRC32_MASK_CCITT); + + // Enable replies lookahead feature + jamwide->lookreplies = true; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::open() { + + GFTRK("JamArea::open"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a JAM msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + open_area(); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::save_lastread() { + + GFTRK("JamArea::save_lastread"); + + // Lock area while we are updating + lock(); + + // Update .JLR record + data->lastrec.lastread = Msgn->CvtReln(lastread); + if(data->lastrec.lastread > data->lastrec.highread) + data->lastrec.highread = data->lastrec.lastread; + + // Seek to users lastread position + lseekset(data->fhjlr, data->lastpos, sizeof(JamLast)); + + // Write the .JLR record + write(data->fhjlr, &data->lastrec, sizeof(JamLast)); + + // Update header info record + data->hdrinfo.modcounter++; + if(data->hdrinfo.basemsgnum == 0) + data->hdrinfo.basemsgnum = 1; + + // Seek to beginning of the .JHR + lseekset(data->fhjhr, 0); + + // Write header info record + write(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + + // Update userfile + if(data->timesposted) { + + // Currently not supported ... + data->timesposted = 0; + } + + // Unlock area + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::close() { + + GFTRK("JamArea::close"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + if(data->islocked) + unlock(); + raw_close(); + Msgn->Reset(); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed JAM msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::suspend() { + + GFTRK("JamArea::suspend"); + + save_lastread(); + raw_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::resume() { + + GFTRK("JamSuspendOff"); + + raw_open(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmojamm2.cpp b/goldlib/gmb3/gmojamm2.cpp new file mode 100644 index 0000000..9c8649a --- /dev/null +++ b/goldlib/gmb3/gmojamm2.cpp @@ -0,0 +1,367 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// JAM msgbase implementation, scanning. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void JamArea::data_open() { + + wide = jamwide; + data = jamdata + (jamdatano++); + data->fhjhr = data->fhjdt = data->fhjdx = data->fhjlr = -1; + data->islocked = false; + data->timesposted = 0; + data->lastpos = 0; +} + + +// ------------------------------------------------------------------ + +void JamArea::data_close() { + + jamdatano--; +} + + +// ------------------------------------------------------------------ + +int JamArea::test_open(const char* file) { + + GFTRK("JamArea::test_open"); + + int fh; + long tries = 0; + + do { + + fh = ::sopen(file, O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(fh == -1) { + + // Tell the world + if((errno != EACCES) OR (PopupLocked(++tries, false, file) == false)) { + WideLog->ErrOpen(); + raw_close(); + WideLog->printf("! A JAM msgbase file could not be opened."); + WideLog->printf(": %s.", file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(fh == -1); + + // Remove the popup window + if(tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return fh; +} + + +// ------------------------------------------------------------------ + +void JamArea::raw_open() { + + GFTRK("JamArea::raw_open"); + + Path file; + sprintf(file, "%s.jhr", path()); data->fhjhr = test_open(file); + sprintf(file, "%s.jdx", path()); data->fhjdx = test_open(file); + sprintf(file, "%s.jlr", path()); data->fhjlr = test_open(file); + if(NOT just_scanning) { + sprintf(file, "%s.jdt", path()); data->fhjdt = test_open(file); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::raw_close() { + + GFTRK("JamArea::raw_close"); + + if(data->fhjlr != -1) ::close(data->fhjlr); data->fhjlr = -1; + if(data->fhjdx != -1) ::close(data->fhjdx); data->fhjdx = -1; + if(data->fhjdt != -1) ::close(data->fhjdt); data->fhjdt = -1; + if(data->fhjhr != -1) ::close(data->fhjhr); data->fhjhr = -1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::open_area() { + + GFTRK("JamArea::open_area"); + + // Open the msgbase files + raw_open(); + + // Read the header info + memset(&data->hdrinfo, 0, sizeof(JamHdrInfo)); + read(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + + // Is the signature invalid? + if(memcmp(data->hdrinfo.signature, JAM_SIGNATURE, 4)) { + + // Initialize header info + memcpy(data->hdrinfo.signature, JAM_SIGNATURE, 4); + time_t a = time(NULL); + time_t b = mktime(gmtime(&a)); + data->hdrinfo.datecreated = a + a - b; + data->hdrinfo.passwordcrc = 0xFFFFFFFFL; + data->hdrinfo.basemsgnum = 1; + + // Write header info + lseekset(data->fhjhr, 0); + write(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + } + + // Adjust base msg number if necessary + if(data->hdrinfo.basemsgnum == 0) + data->hdrinfo.basemsgnum = 1; + + // Seek to beginning of the .JLR + lseekset(data->fhjlr, 0); + + // Search for the userid (not the usercrc?!) + data->lastpos = 0; + int founduser = false; + while(read(data->fhjlr, &data->lastrec, sizeof(JamLast)) == sizeof(JamLast)) { + if(data->lastrec.usercrc == wide->usercrc) { + founduser = true; + break; + } + data->lastpos++; + } + + // If user was not found, init the lastread with our values + if(NOT founduser) { + data->lastrec.usercrc = wide->usercrc; + data->lastrec.userid = wide->userid; + data->lastrec.lastread = 0; + data->lastrec.highread = 0; + } + + data->timesposted = 0; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::raw_scan(int __keep_index, int __scanpm) { + + GFTRK("JamRawScan"); + + // Open the msgbase if it wasn't already + int _was_open = isopen; + if(NOT _was_open) { + if(NOT __keep_index OR __scanpm) + just_scanning = true; + isopen++; + data_open(); + open_area(); + just_scanning = false; + } + + // Get some sizes + long _jdxlen = filelength(data->fhjdx); + uint _jdxsize = (uint)_jdxlen; + uint _jdxtotal = _jdxsize / sizeof(JamIndex); + + // (Re)Allocate message index + if(__keep_index) + Msgn->Resize(_jdxtotal); + + // Allocate buffer to hold .JDX data + JamIndex* _jdxbuf = (JamIndex*)throw_malloc(_jdxsize+1); + + // Read the entire .JDX file into memory + lseekset(data->fhjdx, 0); + read(data->fhjdx, _jdxbuf, _jdxsize); + + // Variables for the loop + register uint _active = 0; + register ulong _firstmsgno = 0; + register ulong _lastmsgno = 0; + register ulong _lastreadfound = 0; + register ulong _msgno = data->hdrinfo.basemsgnum; + register ulong _total = data->hdrinfo.basemsgnum + _jdxtotal; + register ulong _lastread = data->lastrec.lastread; + register uint _lastread_reln = 0; + register ulong* _msgndxptr = Msgn->tag; + register JamIndex* _jdxptr = _jdxbuf; + + // Fill message index + while(_msgno<_total) { + if(_jdxptr->hdroffset != 0xFFFFFFFFL) { + _active++; + if(NOT _firstmsgno) + _firstmsgno = _msgno; + if(__keep_index) + *_msgndxptr++ = _msgno; + if((_msgno >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = _msgno; + _lastread_reln = (uint)(_active - (_msgno != _lastread ? 1 : 0)); + } + _lastmsgno = _msgno; + } + _jdxptr++; + _msgno++; + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + + // Update area data + Msgn->SetCount(_active); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + // Scan for personal mail + if(__scanpm) { + INam uname; + int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; + dword* ucrc = (dword*)throw_calloc(umax, sizeof(dword)); + for(int uc=0; ucResetAll(); + register uint n = lastread + 1; + register uint cnt = Msgn->Count(); + register int gotpm = false; + while(n <= cnt) { + JamIndex* idx = _jdxbuf + (uint)(Msgn->at(n-1) - data->hdrinfo.basemsgnum); + for(int u=0; uusercrc == ucrc[u]) { + gotpm = true; + break; + } + } + if(gotpm) { + JamHdr hdr; + lseekset(data->fhjhr, idx->hdroffset); + read(data->fhjhr, &hdr, sizeof(JamHdr)); + if(NOT (hdr.attribute & JAMATTR_READ)) { + if(NOT (hdr.attribute & JAMATTR_DELETED)) { + PMrk->Append(hdr.messagenumber); + } + } + gotpm = false; + } + n++; + } + throw_free(ucrc); + } + + if(WideDebug) { + WideLog->printf("- %s: t:%u, l:%u, fm:%lu, hm:%lu, lr:%lu, u:%lu, pm:%i", + echoid(), + Msgn->Count(), + lastread, + _firstmsgno, + _lastmsgno, + _lastread, + data->lastpos, + __scanpm ? (int)PMrk->Count() : -1 + ); + } + + + // Free the .JDX buffer + throw_free(_jdxbuf); + + // Close the msgbase again if we opened it in here + if(NOT _was_open) { + raw_close(); + data_close(); + isopen--; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::scan() { + + GFTRK("JamArea::scan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::scan_area() { + + GFTRK("JamArea::scan_area"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::scan_area_pm() { + + GFTRK("JamArea::scan_area_pm"); + + raw_scan(true, true); + Msgn->Reset(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmojamm3.cpp b/goldlib/gmb3/gmojamm3.cpp new file mode 100644 index 0000000..cb6cb6f --- /dev/null +++ b/goldlib/gmb3/gmojamm3.cpp @@ -0,0 +1,388 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// JAM msgbase implementation, load. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include + +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +int JamArea::load_message(int __mode, gmsg* __msg, JamHdr& __hdr) { + + // Read index record for msg + JamIndex _idx; + memset(&_idx, 0, sizeof(JamIndex)); + lseekset(data->fhjdx, __msg->msgno-data->hdrinfo.basemsgnum, sizeof(JamIndex)); + read(data->fhjdx, &_idx, sizeof(JamIndex)); + + if(_idx.hdroffset == 0xFFFFFFFFL) { + GFTRK(NULL); + return false; + } + + // Read message header + memset(&__hdr, 0, sizeof(JamHdr)); + lseekset(data->fhjhr, _idx.hdroffset); + read(data->fhjhr, &__hdr, sizeof(JamHdr)); + + __msg->link.to_set(__hdr.replyto); + __msg->link.first_set(__hdr.reply1st); + __msg->link.next_set(__hdr.replynext); + + __msg->cost = (uint)__hdr.cost; + __msg->timesread = (uint)__hdr.timesread; + + __msg->written = __hdr.datewritten; + __msg->arrived = __hdr.dateprocessed; + __msg->received = __hdr.datereceived; + + __msg->attr.loc(__hdr.attribute & JAMATTR_LOCAL); + __msg->attr.trs(__hdr.attribute & JAMATTR_INTRANSIT); + __msg->attr.pvt(__hdr.attribute & JAMATTR_PRIVATE); + __msg->attr.rcv(__hdr.attribute & JAMATTR_READ); + __msg->attr.snt(__hdr.attribute & JAMATTR_SENT); + __msg->attr.k_s(__hdr.attribute & JAMATTR_KILLSENT); + __msg->attr.a_s(__hdr.attribute & JAMATTR_ARCHIVESENT); + __msg->attr.hld(__hdr.attribute & JAMATTR_HOLD); + __msg->attr.cra(__hdr.attribute & JAMATTR_CRASH); + __msg->attr.imm(__hdr.attribute & JAMATTR_IMMEDIATE); + __msg->attr.dir(__hdr.attribute & JAMATTR_DIRECT); + __msg->attr.zon(__hdr.attribute & JAMATTR_GATE); + __msg->attr.frq(__hdr.attribute & JAMATTR_FILEREQUEST); + __msg->attr.att(__hdr.attribute & JAMATTR_FILEATTACH); + __msg->attr.tfs(__hdr.attribute & JAMATTR_TRUNCFILE); + __msg->attr.kfs(__hdr.attribute & JAMATTR_KILLFILE); + __msg->attr.rrq(__hdr.attribute & JAMATTR_RECEIPTREQ); + __msg->attr.cfm(__hdr.attribute & JAMATTR_CONFIRMREQ); + __msg->attr.orp(__hdr.attribute & JAMATTR_ORPHAN); + __msg->attr.lok(__hdr.attribute & JAMATTR_LOCKED); + __msg->attr.del(__hdr.attribute & JAMATTR_DELETED); + + if(isnet() OR isecho()) + __msg->attr.uns(__msg->attr.loc() AND NOT __msg->attr.snt()); + else + __msg->attr.uns0(); + + __msg->txtstart = __hdr.offset; + __msg->txtlength = __hdr.txtlen; + + // Allocate space for the subfields + __msg->jam.subfieldlen = __hdr.subfieldlen; + byte* _subfield = (byte*)throw_malloc((uint)(__hdr.subfieldlen+1)); + + // Allocate space for kludge versions of the subfields + char* _kludges = (char*)throw_malloc((uint)(__hdr.subfieldlen*2)+1); + *_kludges = NUL; + + // Allocate space for seenby/paths + char* _kludges2 = (char*)throw_malloc((uint)(__hdr.subfieldlen*2)+1); + *_kludges2 = NUL; + + // Read the subfields + read(data->fhjhr, _subfield, (uint)__hdr.subfieldlen); + + // Pointer to the subfields + JamSubField* _subfieldptr = (JamSubField*)_subfield; + + // Process the subfields + int _got_oaddr = false; + int _got_daddr = false; + uint _subfieldpos = 0; + + while(_subfieldpos < __hdr.subfieldlen) { + + _subfieldpos += sizeof(JamSubFieldHdr); + uint _datlen = (uint)_subfieldptr->datlen; + + if(_subfieldpos > __hdr.subfieldlen) + break; + + if((_subfieldpos + _datlen) > __hdr.subfieldlen) + _datlen = (uint)(__hdr.subfieldlen - _subfieldpos); + + char* _buf = _subfieldptr->buffer; + char _bufendchar = _buf[_datlen]; + _buf[_datlen] = NUL; + + char* _ptr; + + switch(_subfieldptr->loid) { + + case JAMSUB_OADDRESS: + if(NOT _got_oaddr) { + _got_oaddr = true; + __msg->oorig.set(_buf, __msg->odom); + __msg->orig = __msg->oorig; + if(_got_daddr) { + add_intl_topt_fmpt: + if(isnet()) { + sprintf(_kludges+strlen(_kludges), "\001INTL %u:%u/%u %u:%u/%u\r", + __msg->dest.zone, __msg->dest.net, __msg->dest.node, + __msg->orig.zone, __msg->orig.net, __msg->orig.node + ); + if(__msg->dest.point) + sprintf(_kludges+strlen(_kludges), "\001TOPT %u\r", __msg->dest.point); + if(__msg->orig.point) + sprintf(_kludges+strlen(_kludges), "\001FMPT %u\r", __msg->orig.point); + } + } + } + break; + + case JAMSUB_DADDRESS: + if(NOT _got_daddr) { + _got_daddr = true; + __msg->odest.set(_buf, __msg->ddom); + __msg->dest = __msg->odest; + if(_got_oaddr) + goto add_intl_topt_fmpt; + } + break; + + case JAMSUB_SENDERNAME: + strxcpy(__msg->by, _buf, sizeof(__msg->by)); + break; + + case JAMSUB_RECEIVERNAME: + strxcpy(__msg->to, _buf, sizeof(__msg->by)); + break; + + case JAMSUB_MSGID: + sprintf(_kludges+strlen(_kludges), "\001MSGID: %s\r", _buf); + strxcpy(__msg->msgids, _buf, sizeof(__msg->msgids)); + __msg->msgid.reset_fast(); + if(atoi(__msg->msgids)) { + __msg->msgid.set(__msg->msgids, __msg->odom); + if(__msg->msgid.net AND (__msg->orig.net == 0)) + __msg->orig = __msg->msgid; + } + break; + + case JAMSUB_REPLYID: + sprintf(_kludges+strlen(_kludges), "\001REPLY: %s\r", _buf); + strxcpy(__msg->replys, _buf, sizeof(__msg->replys)); + break; + + case JAMSUB_SUBJECT: + strxcpy(__msg->re, _buf, sizeof(__msg->re)); + break; + + case JAMSUB_PID: + sprintf(_kludges+strlen(_kludges), "\001PID: %s\r", _buf); + strcpy(__msg->pid, _buf); + break; + + case JAMSUB_TRACE: + sprintf(_kludges+strlen(_kludges), "\001VIA: %s\r", _buf); + // Not processed + break; + + case JAMSUB_ENCLOSEDFILE: + sprintf(_kludges+strlen(_kludges), "\001ENCLFILE: %s\r", _buf); + // Not processed + break; + + case JAMSUB_ENCLOSEDFILEWALIAS: + sprintf(_kludges+strlen(_kludges), "\001ENCLFILEWALIAS: %s\r", _buf); + // Not processed + break; + + case JAMSUB_ENCLOSEDFREQ: + sprintf(_kludges+strlen(_kludges), "\001ENCLFREQ: %s\r", _buf); + // Not processed + break; + + case JAMSUB_ENCLOSEDFILEWCARD: + sprintf(_kludges+strlen(_kludges), "\001ENCLFILEWCARD: %s\r", _buf); + // Not processed + break; + + case JAMSUB_ENCLOSEDINDIRECFILE: + sprintf(_kludges+strlen(_kludges), "\001ENCLINDIRFILE: %s\r", _buf); + // Not processed + break; + + case JAMSUB_EMBINDAT: + // Not processed + break; + + case JAMSUB_FTSKLUDGE: + sprintf(_kludges+strlen(_kludges), "\001%s\r", _buf); + // Not processed + break; + + case JAMSUB_SEENBY2D: + _ptr = _buf; + while(strlen(_ptr) > 70) { + char* _tmp = _ptr; + _ptr += 70; + while(*_ptr != ' ') + _ptr--; + *_ptr++ = NUL; + sprintf(_kludges2+strlen(_kludges2), "SEEN-BY: %s\r", _tmp); + } + sprintf(_kludges2+strlen(_kludges2), "SEEN-BY: %s\r", _ptr); + // Not processed + break; + + // 1 2 3 4 5 6 7 8 + // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 + // SEEN-BY: 123/456 123/456 123/456 123/456 123/456 123/456 123/456 123/456 23/456 123/456 + // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 + // 1 2 3 4 5 6 7 8 + + case JAMSUB_PATH2D: + _ptr = _buf; + while(strlen(_ptr) > 72) { + char* _tmp = _ptr; + _ptr += 72; + while(*_ptr != ' ') + _ptr--; + *_ptr++ = NUL; + sprintf(_kludges2+strlen(_kludges2), "\001PATH: %s\r", _tmp); + } + sprintf(_kludges2+strlen(_kludges2), "\001PATH: %s\r", _ptr); + // Not processed + break; + + case JAMSUB_FLAGS: + sprintf(_kludges+strlen(_kludges), "\001FLAGS %s\r", _buf); + GetAttribstr(&__msg->attr, _buf); + break; + + case JAMSUB_TZUTCINFO: + sprintf(_kludges+strlen(_kludges), "\001TZUTCINFO: %s\r", _buf); + // Not processed + break; + } + + _buf[_datlen] = _bufendchar; + + _subfieldpos += _datlen; + _subfieldptr = (JamSubField*)(_subfield + _subfieldpos); + } + + // Free subfield buffer + throw_free(_subfield); + + // Get reply numbers in chain + if(wide->lookreplies AND __msg->link.first()) { + int r = 0; + ulong m = __msg->link.first(); + while(m AND (r<__msg->link.list_max())) { + JamHdr _rhdr; + memset(&_rhdr, 0, sizeof(JamHdr)); + lseekset(data->fhjdx, m-data->hdrinfo.basemsgnum, sizeof(JamIndex)); + read(data->fhjdx, &_idx, sizeof(JamIndex)); + lseekset(data->fhjhr, _idx.hdroffset); + read(data->fhjhr, &_rhdr, sizeof(JamHdr)); + m = _rhdr.replynext; + if(m) + __msg->link.list_set(r++, m); + } + } + + // If message text is used + if(__mode & GMSG_TXT) { + + // Get size of kludges + uint _kludgelen1 = strlen(_kludges); + uint _kludgelen2 = strlen(_kludges2); + uint _kludgelen = _kludgelen1 + _kludgelen2; + + // Make sure the msg size is within user/system limits + ulong _msgsize = __hdr.txtlen; + if((_msgsize+_kludgelen) > (uint) WideMsgSize) + _msgsize = WideMsgSize - _kludgelen; + + // Allocate memory for the message text + __msg->txt = (char*)throw_realloc(_kludges, (uint)(_msgsize+_kludgelen+256)); + + // Read the message text + lseekset(data->fhjdt, __hdr.offset); + read(data->fhjdt, __msg->txt+_kludgelen1, (uint)_msgsize); + + // Is there a CR at the end? + { + char* ptr = __msg->txt+_kludgelen1+_msgsize-1; + if(*ptr != '\r') { + if(*ptr) { + ptr++; + _msgsize++; + } + *ptr = '\r'; + } + } + + memcpy(__msg->txt+_kludgelen1+(uint)_msgsize, _kludges2, _kludgelen2); + __msg->txt[(uint)_msgsize+_kludgelen] = NUL; + } + else { + + // Free kludge buffer + throw_free(_kludges); + } + + throw_free(_kludges2); + + GFTRK(NULL); + + return true; +} + + +// ------------------------------------------------------------------ + +int JamArea::load_hdr(gmsg* __msg) { + + GFTRK("JamArea::load_hdr"); + + JamHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int JamArea::load_msg(gmsg* __msg) { + + GFTRK("JamArea::load_msg"); + + JamHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmojamm4.cpp b/goldlib/gmb3/gmojamm4.cpp new file mode 100644 index 0000000..9240dc6 --- /dev/null +++ b/goldlib/gmb3/gmojamm4.cpp @@ -0,0 +1,503 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// JAM msgbase implementation, save/delete. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void JamArea::lock() { + + GFTRK("JamArea::lock"); + + if(NOT data->islocked AND WideCanLock) { + + long _tries = 0; + + // Try to get the lock + while(::lock(data->fhjhr, 0, 1) == -1) { + + // Tell the world + if(PopupLocked(++_tries, true, path()) == false) { + WideLog->ErrLock(); + raw_close(); + WideLog->printf("! A JAM msgbase file could not be locked."); + WideLog->printf(": %s.JHR.", path()); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + } + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + data->islocked = true; + } + + // Load fresh copy of the header info + lseekset(data->fhjhr, 0); + read(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::unlock() { + + GFTRK("JamArea::unlock"); + + if(data->islocked) { + ::unlock(data->fhjhr, 0, 1); + data->islocked = false; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::add_subfield(JamHdr& __hdr, byte*& __subfield, word __loid, word __hiid, char* __data) { + + uint _datlen = strlen(__data); + __subfield = (byte*)throw_realloc(__subfield, (uint)__hdr.subfieldlen+sizeof(JamSubFieldHdr)+_datlen); + JamSubField* _subfieldptr = (JamSubField*)(__subfield + (uint)__hdr.subfieldlen); + _subfieldptr->loid = __loid; + _subfieldptr->hiid = __hiid; + _subfieldptr->datlen = _datlen; + memcpy(_subfieldptr->buffer, __data, _datlen); + __hdr.subfieldlen += sizeof(JamSubFieldHdr) + _datlen; +} + + +// ------------------------------------------------------------------ + +void JamArea::save_message(int __mode, gmsg* __msg, JamHdr& __hdr) { + + int _was_locked = data->islocked; + if(NOT _was_locked) + lock(); + + // Reset header + memset(&__hdr, 0, sizeof(JamHdr)); + + // Init paragraph class + GParagraph _para; + if(WideDispsoftcr) + _para.softcr = SOFTCR; + + // Set default msg text offset and length + __hdr.offset = __msg->txtstart; + __hdr.txtlen = __msg->txtlength; + + // Get message text size + char* _txtcpy = NULL; + if(__msg->txt AND (__mode & GMSG_TXT)) { + + // Work on a copy of the original msg text + _txtcpy = throw_strdup(__msg->txt); + + // Convert message text to a paragraph list + _para.ConvertText(_txtcpy, strlen(_txtcpy)); + + // Mark control lines and calculate pure message text size + __hdr.txtlen = _para.CheckCtrlLines(); + } + + // Determine where to write the message text + if((__mode & GMSG_NEW) or (__hdr.txtlen > __msg->txtlength)) + __hdr.offset = filelength(data->fhjdt); + + byte* _subfield = NULL; + char _buf[1024]; + __hdr.subfieldlen = __msg->jam.subfieldlen; + + if(__mode & GMSG_TXT) { + + // Build the subfields + __hdr.subfieldlen = 0; + + // Process addressing kludges + int _line = 0; + GParaData* _pdptr = _para.paraidx; + while(_line < _para.lines) { + if(_pdptr->control > CTRL_KLUDGE) { + word fmpt, topt; + char buf1[201], buf2[201]; + switch(_pdptr->control) { + case CTRL_INTL: + fmpt = __msg->orig.point; + topt = __msg->dest.point; + sscanf(_pdptr->text+6, "%s %s", buf1, buf2); + __msg->dest.set(buf1); + __msg->orig.set(buf2); + __msg->orig.point = fmpt; + __msg->dest.point = topt; + break; + case CTRL_FMPT: + __msg->orig.point = atow(_pdptr->text+6); + break; + case CTRL_TOPT: + __msg->dest.point = atow(_pdptr->text+6); + break; + case CTRL_MSGID: + __msg->msgid.reset(_pdptr->text+8, __msg->odom); + break; + } + } + _pdptr++; + _line++; + } + + if(*__msg->by) + add_subfield(__hdr, _subfield, JAMSUB_SENDERNAME, 0, __msg->by); + + if(__msg->orig.net) { + __msg->orig.make_string(_buf, __msg->odom); + add_subfield(__hdr, _subfield, JAMSUB_OADDRESS, 0, _buf); + } + + if(*__msg->to) + add_subfield(__hdr, _subfield, JAMSUB_RECEIVERNAME, 0, __msg->to); + + if(__msg->dest.net) { + __msg->dest.make_string(_buf, __msg->ddom); + add_subfield(__hdr, _subfield, JAMSUB_DADDRESS, 0, _buf); + } + + if(*__msg->re) + add_subfield(__hdr, _subfield, JAMSUB_SUBJECT, 0, __msg->re); + + // Convert kludges + _line = 0; + _pdptr = _para.paraidx; + while(_line < _para.lines) { + if(_pdptr->control > CTRL_KLUDGE) { + uint _offset = 0; + word _loid = 0; + switch(_pdptr->control) { + case CTRL_INTL: + case CTRL_FMPT: + case CTRL_TOPT: + // Strip these. Data is stored in the address subfields + break; + case CTRL_MSGID: + _loid = JAMSUB_MSGID; + _offset = 8; + strxcpy(__msg->msgids, _pdptr->text+_offset, sizeof(__msg->msgids)); + break; + case CTRL_REPLY: + _loid = JAMSUB_REPLYID; + _offset = 8; + strxcpy(__msg->replys, _pdptr->text+_offset, sizeof(__msg->replys)); + break; + case CTRL_PID: + _loid = JAMSUB_PID; + _offset = 6; + break; + case CTRL_VIA: + _loid = JAMSUB_TRACE; + _offset = 6; + break; + case CTRL_SEENBY: + _loid = JAMSUB_SEENBY2D; + _offset = 9; + break; + case CTRL_SEENBY1: + _loid = JAMSUB_SEENBY2D; + _offset = 10; + break; + case CTRL_PATH: + _loid = JAMSUB_PATH2D; + _offset = 7; + break; + case CTRL_FLAGS: + _loid = JAMSUB_FLAGS; + _offset = 7; + break; + default: + _loid = JAMSUB_FTSKLUDGE; + _offset = 1; + } + if(_offset) + add_subfield(__hdr, _subfield, _loid, 0, _pdptr->text+_offset); + } + _pdptr++; + _line++; + } + } + + JamIndex _idx; + bool was_deleted = false; + if(__mode & GMSG_NEW) { + __msg->msgno = data->hdrinfo.basemsgnum + (filelength(data->fhjdx)/sizeof(JamIndex)); + __hdr.messagenumber = __msg->msgno; + _idx.hdroffset = filelength(data->fhjhr); + } + else { + __hdr.messagenumber = __msg->msgno; + lseekset(data->fhjdx, __hdr.messagenumber-data->hdrinfo.basemsgnum, sizeof(JamIndex)); + read(data->fhjdx, &_idx, sizeof(JamIndex)); + if(_idx.hdroffset != 0xFFFFFFFFL) { + lseekset(data->fhjhr, _idx.hdroffset); + JamHdr oldhdr; + read(data->fhjhr, &oldhdr, sizeof(JamHdr)); + was_deleted = oldhdr.attribute & JAMATTR_DELETED ? true : false; + if(oldhdr.subfieldlen != __hdr.subfieldlen) { + oldhdr.attribute |= JAMATTR_DELETED; + oldhdr.txtlen = 0; + lseekset(data->fhjhr, _idx.hdroffset); + write(data->fhjhr, &oldhdr, sizeof(JamHdr)); + _idx.hdroffset = filelength(data->fhjhr); + } + } + } + + if(_idx.hdroffset != 0xFFFFFFFFL) { + + memcpy(__hdr.signature, JAM_SIGNATURE, 4); + __hdr.revision = JAM_REVISION; + + __hdr.replyto = __msg->link.to(); + __hdr.reply1st = __msg->link.first(); + __hdr.replynext = __msg->link.next(); + + __hdr.cost = __msg->cost; + __hdr.timesread = __msg->timesread; + __hdr.passwordcrc = 0xFFFFFFFFL; + + __hdr.msgidcrc = strCrc32(strlwr(strcpy(_buf, __msg->msgids)), NO, CRC32_MASK_CCITT); + __hdr.replycrc = strCrc32(strlwr(strcpy(_buf, __msg->replys)), NO, CRC32_MASK_CCITT); + _idx.usercrc = strCrc32(strlwr(strcpy(_buf, __msg->to)), NO, CRC32_MASK_CCITT); + + __hdr.datewritten = __msg->written; + __hdr.datereceived = __msg->received; + __hdr.dateprocessed = __msg->arrived; + + __hdr.attribute |= __msg->attr.loc() ? JAMATTR_LOCAL : 0; + __hdr.attribute |= __msg->attr.trs() ? JAMATTR_INTRANSIT : 0; + __hdr.attribute |= __msg->attr.pvt() ? JAMATTR_PRIVATE : 0; + __hdr.attribute |= __msg->attr.rcv() ? JAMATTR_READ : 0; + __hdr.attribute |= __msg->attr.snt() ? JAMATTR_SENT : 0; + __hdr.attribute |= __msg->attr.k_s() ? JAMATTR_KILLSENT : 0; + __hdr.attribute |= __msg->attr.a_s() ? JAMATTR_ARCHIVESENT : 0; + __hdr.attribute |= __msg->attr.hld() ? JAMATTR_HOLD : 0; + __hdr.attribute |= __msg->attr.cra() ? JAMATTR_CRASH : 0; + __hdr.attribute |= __msg->attr.imm() ? JAMATTR_IMMEDIATE : 0; + __hdr.attribute |= __msg->attr.dir() ? JAMATTR_DIRECT : 0; + __hdr.attribute |= __msg->attr.zon() ? JAMATTR_GATE : 0; + __hdr.attribute |= __msg->attr.frq() ? JAMATTR_FILEREQUEST : 0; + __hdr.attribute |= __msg->attr.att() ? JAMATTR_FILEATTACH : 0; + __hdr.attribute |= __msg->attr.tfs() ? JAMATTR_TRUNCFILE : 0; + __hdr.attribute |= __msg->attr.kfs() ? JAMATTR_KILLFILE : 0; + __hdr.attribute |= __msg->attr.rrq() ? JAMATTR_RECEIPTREQ : 0; + __hdr.attribute |= __msg->attr.cfm() ? JAMATTR_CONFIRMREQ : 0; + __hdr.attribute |= __msg->attr.orp() ? JAMATTR_ORPHAN : 0; + __hdr.attribute |= __msg->attr.lok() ? JAMATTR_LOCKED : 0; + __hdr.attribute |= __msg->attr.del() ? JAMATTR_DELETED : 0; + + if(isnet()) + __hdr.attribute |= JAMATTR_TYPENET; + else if(isecho()) + __hdr.attribute |= JAMATTR_TYPEECHO; + else + __hdr.attribute |= JAMATTR_TYPELOCAL; + + lseekset(data->fhjhr, _idx.hdroffset); + write(data->fhjhr, &__hdr, sizeof(JamHdr)); + + // Only write subfields if the msg body is written + if(__mode & GMSG_TXT) + write(data->fhjhr, _subfield, (uint)__hdr.subfieldlen); + + // Delete msg if requested + if(__mode & GMSG_DELETE) { + if(NOT was_deleted) + data->hdrinfo.activemsgs--; + __hdr.attribute |= JAMATTR_DELETED; + _idx.usercrc = 0xFFFFFFFFL; + if(wide->harddelete) + _idx.hdroffset = 0xFFFFFFFFL; + } + + // Write msg index + lseekset(data->fhjdx, __hdr.messagenumber-data->hdrinfo.basemsgnum, sizeof(JamIndex)); + write(data->fhjdx, &_idx, sizeof(JamIndex)); + + // Free subfield buffer + throw_release(_subfield); + + // Update the header info + if(__mode & GMSG_NEW) + data->hdrinfo.activemsgs++; + data->hdrinfo.modcounter++; + lseekset(data->fhjhr, 0); + write(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + + // If message text is used + if(__mode & GMSG_TXT) { + + char* _txt = (char*)throw_malloc((uint)(__hdr.txtlen+256)); + + // Copy text paragraphs, excluding kludges + int _line = 0; + char* _tptr = _txt; + GParaData* _pdptr = _para.paraidx; + while(_line < _para.lines) { + if(_pdptr->control < CTRL_KLUDGE) { + memcpy(_tptr, _pdptr->text, _pdptr->length); + _tptr += _pdptr->length; + *_tptr++ = CR; + } + _pdptr++; + _line++; + } + *_tptr = NUL; + + // Seek to start position of the message text + lseekset(data->fhjdt, __hdr.offset); + + // Write the message text + write(data->fhjdt, _txt, (uint)__hdr.txtlen); + + // Release the memory we have used + throw_free(_txtcpy); + throw_free(_txt); + } + + // Update internals if new + if(__mode & GMSG_NEW) { + + // Count our msgs + data->timesposted++; + + // Update internal array + Msgn->Append(__msg->msgno); + } + } + else { + scan(); + } + + if(NOT _was_locked) { + lseekset(data->fhjhr, 0); + write(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + unlock(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("JamArea::save_hdr"); + + JamHdr _hdr; + save_message(__mode | GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void JamArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("JamArea::save_msg"); + + JamHdr _hdr; + save_message(__mode | GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void JamArea::del_msg(gmsg* __msg) { + + GFTRK("JamArea::del_msg"); + + JamHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void JamArea::new_msgno(gmsg* __msg) { + + GFTRK("JamArea::new_msgno"); + + __msg->msgno = data->hdrinfo.basemsgnum + (filelength(data->fhjdx)/sizeof(JamIndex)); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void JamArea::update_timesread(gmsg* msg) { + + GFTRK("JamArea::update_timesread"); + + lock(); + + lseekset(data->fhjdx, msg->msgno-data->hdrinfo.basemsgnum, sizeof(JamIndex)); + + JamIndex idx; + read(data->fhjdx, &idx, sizeof(JamIndex)); + + JamHdr hdr; + lseekset(data->fhjhr, idx.hdroffset); + read(data->fhjhr, &hdr, sizeof(JamHdr)); + + hdr.timesread = msg->timesread; + + lseekset(data->fhjhr, idx.hdroffset); + write(data->fhjhr, &hdr, sizeof(JamHdr)); + + data->hdrinfo.modcounter++; + lseekset(data->fhjhr, 0); + write(data->fhjhr, &data->hdrinfo, sizeof(JamHdrInfo)); + + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmojamm5.cpp b/goldlib/gmb3/gmojamm5.cpp new file mode 100644 index 0000000..16a426e --- /dev/null +++ b/goldlib/gmb3/gmojamm5.cpp @@ -0,0 +1,190 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// JAM msgbase implementation, utilities. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +char* JamArea::user_lookup(char* lookfor) { + + NW(lookfor); + return NULL; +} + + +// ------------------------------------------------------------------ + +int JamArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ + +Line* JamArea::make_dump_msg(Line*& lin, gmsg* __msg, char* lng_head) { + + GFTRK("JamArea::make_dump_msg"); + + // Read base header + JamHdrInfo* _base = (JamHdrInfo*)throw_calloc(1, sizeof(JamHdrInfo)); + lseekset(data->fhjhr, 0); + read(data->fhjhr, _base, sizeof(JamHdrInfo)); + + // Read index record for msg + JamIndex _idx; + lseekset(data->fhjdx, __msg->msgno-data->hdrinfo.basemsgnum, sizeof(JamIndex)); + read(data->fhjdx, &_idx, sizeof(JamIndex)); + + // Allocate space for the header + JamHdr* _hdr = (JamHdr*)throw_calloc(1, (uint)(sizeof(JamHdr)+17)); + + // Read message header + lseekset(data->fhjhr, _idx.hdroffset); + read(data->fhjhr, _hdr, sizeof(JamHdr)); + + // Allocate space for the subfields + byte* _subfield = (byte*)throw_calloc(1, (uint)(_hdr->subfieldlen+17)); + + // Read the subfields + read(data->fhjhr, _subfield, (uint)_hdr->subfieldlen); + + // Allocate memory for the raw message text + throw_free(__msg->txt); + __msg->txt = (char*)throw_calloc(1, (uint)_hdr->txtlen+16); + + // Read the message text + lseekset(data->fhjdt, _hdr->offset); + read(data->fhjdt, __msg->txt, (uint)_hdr->txtlen); + + char buf[100]; + Line* line = lin = + AddLine (NULL, "Hexdump of JAM message header, subfields and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Msgbase : %s", path()); + AddLineF(line, "Signature : %s", _hdr->signature); + AddLineF(line, "Revision : %u", _hdr->revision); + AddLineF(line, "ReservedWord : %u", _hdr->reservedword); + AddLineF(line, "SubfieldLen : %lu", _hdr->subfieldlen); + AddLineF(line, "TimesRead : %lu", _hdr->timesread); + AddLineF(line, "MSGIDcrc : %08lXh", _hdr->msgidcrc); + AddLineF(line, "REPLYcrc : %08lXh", _hdr->replycrc); + AddLineF(line, "ReplyTo : %lu", _hdr->replyto); + AddLineF(line, "Reply1st : %lu", _hdr->reply1st); + AddLineF(line, "ReplyNext : %lu", _hdr->replynext); + AddLineF(line, "DateWritten : %s (%08lXh)", TimeToStr(buf, _hdr->datewritten), _hdr->datewritten); + AddLineF(line, "DateReceived : %s (%08lXh)", TimeToStr(buf, _hdr->datereceived), _hdr->datereceived); + AddLineF(line, "DateProcessed : %s (%08lXh)", TimeToStr(buf, _hdr->dateprocessed), _hdr->dateprocessed); + AddLineF(line, "MessageNumber : %lu", _hdr->messagenumber); + AddLineF(line, "Attribute : %08lXh (%sb)", _hdr->attribute, ltob(buf, _hdr->attribute, 0)); + AddLineF(line, "Attribute2 : %08lXh (%sb)", _hdr->attribute2, ltob(buf, _hdr->attribute2, 0)); + AddLineF(line, "Offset : %lu", _hdr->offset); + AddLineF(line, "TxtLen : %lu", _hdr->txtlen); + AddLineF(line, "PasswordCRC : %08lXh", _hdr->passwordcrc); + AddLineF(line, "Cost : %lu", _hdr->cost); + line = AddLine(line, ""); + AddLineF(line, "Index Record:"); + line = AddLine(line, ""); + AddLineF(line, "UserCrc : %08lXh", _idx.usercrc); + AddLineF(line, "HeaderOffset : %08lXh (%lu)", _idx.hdroffset, _idx.hdroffset); + line = AddLine(line, ""); + AddLineF(line, "Lastread Record:"); + line = AddLine(line, ""); + AddLineF(line, "Index : %lu", data->lastpos); + AddLineF(line, "UserCrc : %08lXh", data->lastrec.usercrc); + AddLineF(line, "UserId : %08lXh", data->lastrec.userid); + AddLineF(line, "Lastread : %lu", data->lastrec.lastread); + AddLineF(line, "Highread : %lu", data->lastrec.highread); + line = AddLine(line, ""); + AddLineF(line, "Base Header:"); + line = AddLine(line, ""); + AddLineF(line, "DateCreated : %s (%08lXh)", TimeToStr(buf, _base->datecreated), _base->datecreated); + AddLineF(line, "ModCounter : %lu", _base->modcounter); + AddLineF(line, "ActiveMsgs : %lu", _base->activemsgs); + AddLineF(line, "PasswordCRC : %08lXh", _base->passwordcrc); + AddLineF(line, "BaseMsgNum : %lu", _base->basemsgnum); + AddLineF(line, "HighWaterMark : %lu", _base->highwatermark); + line = AddLine(line, ""); + AddLineF(line, "Subfields:"); + line = AddLine(line, ""); + + AddHexdump(line, _subfield, (uint)_hdr->subfieldlen); + line = AddLine(line, ""); + + // Process the subfields + JamSubField* _subfieldptr = (JamSubField*)_subfield; + uint _subfieldpos = 0; + while(_subfieldpos < _hdr->subfieldlen) { + _subfieldpos += sizeof(JamSubFieldHdr); + uint _datlen = (uint)_subfieldptr->datlen; + if(_subfieldpos > _hdr->subfieldlen) { + AddLineF(line, "Error: SubfieldHdr at pos %u exceeds SubfieldLen (%lu)!", _subfieldpos-sizeof(JamSubFieldHdr), _hdr->subfieldlen); + break; + } + if((_subfieldpos + _datlen) > _hdr->subfieldlen) { + _datlen = (uint)(_hdr->subfieldlen - _subfieldpos); + AddLineF(line, "Error: SubfieldData at pos %u is too long (%u)! Cut to %u.", _subfieldpos, (uint)_subfieldptr->datlen, _datlen); + } + AddLineF(line, "%05u [%3u]: \"%-*.*s\"", + _subfieldptr->loid, _datlen, + MinV(60, (int)_datlen), + MinV(60, (int)_datlen), + _subfieldptr->buffer + ); + _subfieldpos += _datlen; + _subfieldptr = (JamSubField*)(_subfield + _subfieldpos); + } + + // Free subfield buffer + throw_free(_subfield); + + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + AddHexdump(line, _hdr, sizeof(JamHdr)); + + // Free header and base + throw_free(_hdr); + throw_free(_base); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmopcbd.h b/goldlib/gmb3/gmopcbd.h new file mode 100644 index 0000000..ba65ede --- /dev/null +++ b/goldlib/gmb3/gmopcbd.h @@ -0,0 +1,239 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard Structures. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GMPCBD_H +#define __GMPCBD_H + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef char PcbName[25+1]; + + +// ------------------------------------------------------------------ +// PCBoard Message Base Header (. file) + +struct PcbBase { + + long highmsgno; // High Message Number (0 to 16,700,000) + long lowmsgno; // Low Message Number (0 to 16,700,000) + long active; // Number of Active Messages (0 to 32,767) + long callers; // Number of System Callers (Main Message Base Only) + char locked[6]; // The "LOCKED" field for pre-14.2 systems (see note 1) + byte reserved[106]; // Reserved for future use +}; + + +// ------------------------------------------------------------------ +// PCBoard Individual Message Header (in . file) + +struct PcbHdr { + + char status; // Message Status Flag (see note 2) + long msgno; // Message Number (0 to 16,700,000) + long refno; // Reference Number (0 to 16,700,000) + byte blocks; // Number of 128 Byte Blocks in Message (see note 3) + char date[8]; // Date of Message Entry (in "mm-dd-yy" format) + char time[5]; // Time of Message Entry (in "hh:mm" format) + char destname[25]; // Name of the User to whom the Message is Addressed + long replydate; // Date of the Reply Message (in yymmdd format) + char replytime[5]; // Time of the Reply Message (in "hh:mm" format) + char hasreply; // The Letter "R" if the Message has a Reply + char origname[25]; // Name of the User who wrote the Message + char subject[25]; // Subject of the Message + char password[12]; // Password Need to Read the Message (if any) + byte activestatus; // Active Status (225 = active, 226 = inactive) + char echoed; // The Letter "E" if the Message is to be Echoed + byte reserved[4]; // Reserved for future use + byte exthdrflags; // Extended Header Flags (version 15.0) + byte reserved2; // Reserved for future use +}; + + +// ------------------------------------------------------------------ +// PCBoard Extended Header (version 15.0) (in . file) + +struct PcbExtHdr { + + short id; // Extended Header ID = must be equal to 40FFh + char function[7]; // Extended Header Function + char colon; // A colon (:) character + char desc[60]; // Extended Header Description (subj, to, from, etc) + char status; // Status (N or R) + char separator; // Line Separator (E3h, or 0Dh for foreign systems) +}; + + +// ------------------------------------------------------------------ +// PCBoard Version 15.0 Style Index (.IDX file) + +struct PcbIdx { + + long offset; // Offset (0 if none, >0 if active, <0 if killed) + long num; // Message Number + char to[25]; // TO Name + char from[25]; // FROM Name + char status; // Status Character (from Message Header) + word date; // Date of Message (in julian date format) + char reserved[3]; // Reserved for future use +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct PcbData { + int fhmsg; + int fhidx; + int islocked; + PcbBase base; +}; + + +// ------------------------------------------------------------------ + +struct PcbWide { + int isopen; + int fhusr; + int fhinf; + int userno; + PcbUser* user; + Path usersidxpath; + Path usersinf; + Path users; + int numareas; + PcbUsers usersrec; + PcbUsersInfHdr usershdr; + long usershdrsize; + long* lastread; + long confbytelen; + long extconflen; + int foreign; + const char* path; +}; + + +// ------------------------------------------------------------------ + +class PcbArea : public gmo_area { + +protected: + + PcbWide* wide; + PcbData* data; + + int just_scanning; + + void data_open(); + void data_close(); + + int test_open(const char* __file); + + void raw_open(); + void raw_close(); + + void save_lastread(); + void raw_scan(int __keep_index, int __scanpm=false); + int load_message(int __mode, gmsg* __msg, PcbHdr& __hdr); + void save_message(int __mode, gmsg* __msg, PcbHdr& __hdr); + +public: + + PcbArea() { wide = NULL; data = NULL; just_scanning = false; } + virtual ~PcbArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern PcbData* pcbdata; +extern PcbWide* pcbwide; +extern int pcbdatano; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmopcbd1.cpp b/goldlib/gmb3/gmopcbd1.cpp new file mode 100644 index 0000000..cb81265 --- /dev/null +++ b/goldlib/gmb3/gmopcbd1.cpp @@ -0,0 +1,283 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard msgbase handling. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +PcbData* pcbdata = NULL; +PcbWide* pcbwide = NULL; +int pcbdatano = 0; + + +// ------------------------------------------------------------------ + +void PcbExit() { + + if(pcbwide) { + throw_free(pcbwide->lastread); + delete pcbwide->user; + } + throw_xrelease(pcbwide); + throw_xrelease(pcbdata); +} + + +// ------------------------------------------------------------------ + +void PcbInit(const char* path, int userno) { + + pcbdata = (PcbData*)throw_calloc(2, sizeof(PcbData)); + pcbwide = (PcbWide*)throw_calloc(1, sizeof(PcbWide)); + + pcbwide->path = path; + pcbwide->userno = userno; + + pcbwide->fhusr = pcbwide->fhinf = -1; + + pcbwide->user = new PcbUser; + throw_new(pcbwide->user); + + // Get PCBoard path + Path _path; + char* _ptr = getenv("PCBOARD"); + if(_ptr) + AddBackslash(strcpy(_path, _ptr)); + else + strcpy(_path, path); + + Path _cnamespath; + *_cnamespath = NUL; + + // Open PCBOARD.DAT + gfile fp; + const char* _file = AddPath(_path, "PCBOARD.DAT"); + fp.fopen(_file, "rt", WideSharemode); + if(fp.isopen()) { + + // Get some paths/filenames + int _line = 0; + char _buf[256]; + fp.setvbuf(NULL, _IOFBF, 8192); + while(fp.fgets(_buf, sizeof(_buf))) { + _line++; + if(_line == 28) + strxcpy(pcbwide->usersidxpath, strbtrim(_buf), sizeof(Path)); + else if(_line == 29) + strxcpy(pcbwide->users, strbtrim(_buf), sizeof(Path)); + else if(_line == 31) + strxcpy(_cnamespath, strbtrim(_buf), sizeof(Path)); + else if(_line == 180) + strxcpy(pcbwide->usersinf, strbtrim(_buf), sizeof(Path)); + else if(_line == 208) + pcbwide->foreign = atoi(_buf); + } + fp.fclose(); + + // Open CNAMES.@@@ + _file = AddPath(_cnamespath, ".@@@"); + fp.fopen(_file, "rb", WideSharemode); + + // Get board numbers for lastread indexing in the userfiles + word _recsize = 0; + fp.setvbuf(NULL, _IOFBF, 8192); + fp.fread(&_recsize, 2); + if(_recsize) { + PcbConf* _cnames = (PcbConf*)throw_calloc(1, _recsize); + int _rec = 0; + pcbwide->numareas = (int)((fp.filelength()-2)/(long)_recsize); + pcbwide->confbytelen = (pcbwide->numareas/8) + ((pcbwide->numareas%8) != 0 ? 1 : 0); + if(pcbwide->confbytelen < 5) + pcbwide->confbytelen = 5; + pcbwide->extconflen = pcbwide->confbytelen - 5; + pcbwide->lastread = (long*)throw_calloc(pcbwide->numareas, sizeof(long)); + while(fp.fread(_cnames, _recsize) == 1) { + PcbAdjustArea((uint)_rec, _cnames->msgfile); + _rec++; + } + throw_free(_cnames); + } + fp.fclose(); + + const char* _username = WideUsername[0]; + pcbwide->user->fh = ::sopen(AddPath(_path, pcbwide->users), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(pcbwide->user->fh != -1) { + pcbwide->user->fhinf = ::sopen(AddPath(_path, pcbwide->usersinf), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(pcbwide->user->fhinf != -1) { + ::read(pcbwide->user->fhinf, &pcbwide->usershdr, sizeof(PcbUsersInfHdr)); + pcbwide->usershdrsize = sizeof(PcbUsersInfHdr) + (pcbwide->usershdr.numofapps*sizeof(PcbUsersInfApp)); + pcbwide->user->usershdr = &pcbwide->usershdr; + pcbwide->user->usershdrsize = pcbwide->usershdrsize; + if(pcbwide->userno == -1) { + pcbwide->user->find(_username); + if(NOT pcbwide->user->found) { + pcbwide->userno = 0; + //WideLog->printf("* User \"%s\" not found in %sUSERS.", _username, _path); + //pcbwide->user->add(_username); + //WideLog->printf("* Now added with user number %u.", pcbwide->user->index); + } + } + close(pcbwide->user->fhinf); + } + close(pcbwide->user->fh); + } + pcbwide->userno = pcbwide->user->index; + } + else { + + WideLog->ErrOpen(); + WideLog->printf("! Configured for PCBoard, but can't find it."); + WideLog->printf(": %s.", _file); + WideLog->printf("+ Advice: Add or correct the PCBOARDPATH keyword."); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } +} + + +// ------------------------------------------------------------------ + +void PcbArea::open() { + + GFTRK("PcbOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a PCBoard msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + PcbWideOpen(); + data_open(); + raw_open(); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::save_lastread() { + + GFTRK("PcbSaveLastread"); + + dword tmplr = Msgn->CvtReln(lastread); + if(board() < 40) { + // Write lastreads to USERS file + lseekset(wide->fhusr, (long)wide->userno*(long)sizeof(PcbUsers)); + read(wide->fhusr, &wide->usersrec, sizeof(PcbUsers)); + wide->usersrec.lastmsgread[board()] = L2B(tmplr); + lseekset(wide->fhusr, (long)wide->userno*(long)sizeof(PcbUsers)); + write(wide->fhusr, &wide->usersrec, sizeof(PcbUsers)); + } + else { + // Write lastreads to USERS.INF file + if(wide->extconflen) { + long _offset = (wide->usersrec.usersinfrec-1)*wide->usershdr.totalrecsize; + _offset += wide->usershdrsize; + _offset += wide->usershdr.sizeofrec; + _offset += 2 * wide->confbytelen; + _offset += 3 * wide->extconflen; + _offset += sizeof(dword) * (board() - 40); + lseekset(wide->fhinf, _offset); + write(wide->fhinf, &tmplr, sizeof(dword)); + } + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::close() { + + GFTRK("PcbClose"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + raw_close(); + Msgn->Reset(); + data_close(); + PcbWideClose(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed PCBoard msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::suspend() { + + GFTRK("PcbSuspend"); + + save_lastread(); + raw_close(); + PcbWideClose(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::resume() { + + GFTRK("PcbResume"); + + PcbWideOpen(); + raw_open(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmopcbd2.cpp b/goldlib/gmb3/gmopcbd2.cpp new file mode 100644 index 0000000..074b478 --- /dev/null +++ b/goldlib/gmb3/gmopcbd2.cpp @@ -0,0 +1,392 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard msgbase handling. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void PcbArea::data_open() { + + wide = pcbwide; + data = pcbdata + (pcbdatano++); + data->fhmsg = data->fhidx = -1; + memset(&data->base, 0x20, sizeof(PcbBase)); + data->base.highmsgno = 0; + data->base.lowmsgno = 0; + data->base.active = 0; +} + + +// ------------------------------------------------------------------ + +void PcbArea::data_close() { + + pcbdatano--; +} + + +// ------------------------------------------------------------------ + +int PcbWideTestOpen(char* __file) { + + GFTRK("PcbWideTestOpen"); + + int _fh; + long _tries = 0; + + do { + + _fh = ::sopen(__file, O_RDWR|O_BINARY|O_CREAT, WideSharemode, S_STDRW); + if(_fh == -1) { + + // Tell the world + if(PopupLocked(++_tries, false, __file) == false) { + WideLog->ErrOpen(); + PcbWideClose(); + WideLog->printf("! A PCBoard msgbase file could not be opened."); + WideLog->printf(": %s.", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void PcbWideOpen() { + + GFTRK("PcbWideOpen"); + + if(NOT pcbwide->isopen) { + + pcbwide->fhusr = PcbWideTestOpen(pcbwide->users); + pcbwide->fhinf = PcbWideTestOpen(pcbwide->usersinf); + pcbwide->user->fh = pcbwide->fhusr; + pcbwide->user->fhinf = pcbwide->fhinf; + + // Read lastreads from USERS file + lseekset(pcbwide->fhusr, (long)pcbwide->userno*(long)sizeof(PcbUsers)); + read(pcbwide->fhusr, &pcbwide->usersrec, sizeof(PcbUsers)); + int _maxlr = MinV(pcbwide->numareas, 40); + for(int n=0; n<_maxlr; n++) + pcbwide->lastread[n] = B2L(pcbwide->usersrec.lastmsgread[n]); + + // Read lastreads from USERS.INF file + if(pcbwide->extconflen) { + long _offset = (pcbwide->usersrec.usersinfrec-1)*pcbwide->usershdr.totalrecsize; + _offset += pcbwide->usershdrsize; + _offset += pcbwide->usershdr.sizeofrec; + _offset += 2 * pcbwide->confbytelen; + _offset += 3 * pcbwide->extconflen; + lseekset(pcbwide->fhinf, _offset); + read(pcbwide->fhinf, pcbwide->lastread+40, (pcbwide->numareas-40)*sizeof(long)); + } + + pcbwide->isopen = true; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbWideClose() { + + GFTRK("PcbWideClose"); + + if(pcbwide->isopen) { + if(pcbwide->fhinf != -1) ::close(pcbwide->fhinf); pcbwide->fhinf = -1; + if(pcbwide->fhusr != -1) ::close(pcbwide->fhusr); pcbwide->fhusr = -1; + pcbwide->isopen = false; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::raw_close() { + + GFTRK("PcbRawClose"); + + if(data->fhidx != -1) ::close(data->fhidx); data->fhidx = -1; + if(data->fhmsg != -1) ::close(data->fhmsg); data->fhmsg = -1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +int PcbArea::test_open(const char* __file) { + + GFTRK("PcbArea::test_open"); + + int _fh; + long _tries = 0; + + do { + + _fh = ::sopen(__file, O_RDWR|O_BINARY|O_CREAT, WideSharemode, S_STDRW); + if(_fh == -1) { + + // Tell the world + if(PopupLocked(++_tries, false, __file) == false) { + WideLog->ErrOpen(); + raw_close(); + PcbWideClose(); + WideLog->printf("! A PCBoard msgbase file could not be opened."); + WideLog->printf(": %s.", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void PcbArea::raw_open() { + + GFTRK("PcbRawOpen"); + + if(NOT just_scanning) + data->fhmsg = test_open(path()); + data->fhidx = test_open(AddPath(path(), ".idx")); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::raw_scan(int __keep_index, int __scanpm) { + + GFTRK("PcbRawScan"); + + // Open the msgbase if it wasn't already + int _was_open = isopen; + if(NOT _was_open) { + if(NOT __keep_index) + just_scanning = true; + isopen++; + data_open(); + raw_open(); + just_scanning = false; + } + + int _was_wideopen = wide->isopen; + if(NOT _was_wideopen) + PcbWideOpen(); + + // Load the base header + if(__keep_index) { + lseekset(data->fhmsg, 0); + read(data->fhmsg, &data->base, sizeof(PcbBase)); + data->base.highmsgno = B2L(data->base.highmsgno); + data->base.lowmsgno = B2L(data->base.lowmsgno); + data->base.active = B2L(data->base.active); + } + + // Get some sizes + long _idxlen = filelength(data->fhidx); + uint _idxsize = (uint)_idxlen; + uint _idxtotal = _idxsize / sizeof(PcbIdx); + + // (Re)Allocate message index + if(__keep_index) + Msgn->Resize(_idxtotal); + + // Allocate buffer to hold .IDX data + PcbIdx* _idxbuf = (PcbIdx*)throw_malloc(_idxsize+1); + + // Read the entire .IDX file into memory + lseekset(data->fhidx, 0); + read(data->fhidx, _idxbuf, _idxsize); + + // Variables for the loop + register uint _active = 0; + register ulong _firstmsgno = 0; + register ulong _lastmsgno = 0; + register ulong _lastreadfound = 0; + register ulong _totalmsgs = _idxtotal; + register ulong _lastread = wide->lastread[board()]; + register uint _lastread_reln = 0; + register ulong* _msgndxptr = Msgn->tag; + register PcbIdx* _idxptr = _idxbuf; + + // Fill message index + register uint n = 0; + while((n++) < _totalmsgs) { + if(_idxptr->offset > 0) { + _active++; + _lastmsgno = _idxptr->num; + if(NOT _firstmsgno) + _firstmsgno = _lastmsgno; + if(__keep_index) + *_msgndxptr++ = _lastmsgno; + if((_lastmsgno >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = _lastmsgno; + _lastread_reln = (uint)(_active - (_lastmsgno != _lastread ? 1 : 0)); + } + } + _idxptr++; + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + + // Update area data + Msgn->SetCount(_active); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + // Scan for personal mail + if(__scanpm) { + int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; + PcbName* uname = (PcbName*)throw_calloc(umax, sizeof(PcbName)); + for(int un=0; unResetAll(); + register uint n = lastread + 1; + register uint cnt = Msgn->Count(); + register int gotpm = false; + while(n <= cnt) { + PcbIdx* idx = _idxbuf + (uint)(Msgn->at(n-1) - data->base.lowmsgno); + for(int u=0; uto, uname[u], 25)) { + gotpm = true; + break; + } + } + if(gotpm) { + switch(idx->status) { + case '+': + case '-': + case '`': + case '^': + case '#': + break; + default: + PMrk->Append(idx->num); + } + gotpm = false; + } + n++; + } + throw_free(uname); + } + + // Free the .IDX buffer + throw_free(_idxbuf); + + if(NOT _was_wideopen) + PcbWideClose(); + + // Close the msgbase again if we opened it in here + if(NOT _was_open) { + raw_close(); + data_close(); + isopen--; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::scan() { + + GFTRK("PcbScan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::scan_area() { + + GFTRK("PcbScanArea"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::scan_area_pm() { + + GFTRK("PcbScanArea*M"); + + raw_scan(true, true); + Msgn->Reset(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmopcbd3.cpp b/goldlib/gmb3/gmopcbd3.cpp new file mode 100644 index 0000000..e35f953 --- /dev/null +++ b/goldlib/gmb3/gmopcbd3.cpp @@ -0,0 +1,259 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard msgbase handling. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +int PcbArea::load_message(int __mode, gmsg* __msg, PcbHdr& __hdr) { + + // Read index record for msg + PcbIdx _idx; + lseekset(data->fhidx, (__msg->msgno-data->base.lowmsgno)*(long)sizeof(PcbIdx)); + read(data->fhidx, &_idx, sizeof(PcbIdx)); + __msg->txtstart = _idx.offset; + + // Read message header + lseekset(data->fhmsg, AbsV(_idx.offset)); + read(data->fhmsg, &__hdr, sizeof(PcbHdr)); + __msg->txtlength = (__hdr.blocks-1)*128; + __msg->txtblocks = __hdr.blocks; + + __msg->timesread = 1; + + // Convert attributes + __msg->pcboard.status = __hdr.status; + if(NOT islocal()) + __msg->attr.uns(__hdr.date[5] != '\xC4'); + __msg->attr.pvt(__hdr.status == '*' OR __hdr.status == '+'); + __msg->attr.rcv(__hdr.status == '+' OR __hdr.status == '-' OR __hdr.status == '`' OR __hdr.status == '^' OR __hdr.status == '#'); + __msg->attr.del(__hdr.activestatus == 226); + __msg->pcboard.exthdrflags = __hdr.exthdrflags; + + // Convert msgno and replylinks + __hdr.msgno = B2L(__hdr.msgno); + __hdr.refno = B2L(__hdr.refno); + __msg->link.to_set(__hdr.refno); + + // Convert date and time + int _year, _month, _day, _hour, _minute; + sscanf(__hdr.date, "%d%*c%d%*c%2d", &_month, &_day, &_year); + sscanf(__hdr.time, "%d%*c%2d", &_hour, &_minute); + struct tm _tm; + _tm.tm_year = (_year < 80) ? (_year+100) : _year; + _tm.tm_mon = _month - 1; + _tm.tm_mday = _day; + _tm.tm_hour = _hour; + _tm.tm_min = _minute; + _tm.tm_sec = 0; + _tm.tm_isdst = -1; + time_t a = mktime(&_tm); + time_t b = mktime(gmtime(&a)); + __msg->written = a + a - b; + __msg->arrived = 0; + + // Convert names and subject and password + strtrim(strncpy(__msg->by, __hdr.origname, 25)); + strtrim(strncpy(__msg->to, __hdr.destname, 25)); + strtrim(strncpy(__msg->re, __hdr.subject, 25)); + strtrim(strncpy(__msg->pcboard.password, __hdr.password, 12)); + + // Make sure the msg size is within user/system limits + uint _msgsize = (uint)__msg->txtlength; + if(_msgsize > WideMsgSize) + _msgsize = (uint)WideMsgSize; + + // Allocate memory for the message text + __msg->txt = (char*)throw_realloc(__msg->txt, _msgsize+256); + char* _tmptxt = (char*)throw_calloc(1, _msgsize+1); + + // Read the message text, trim spaces and translate PCB linefeeds + read(data->fhmsg, _tmptxt, _msgsize); + strtrim(_tmptxt); + if(NOT wide->foreign) + strchg(_tmptxt, 0xE3, 0x0D); + + //int _line = 0; + char _eby[122] = {""}; + char _eto[122] = {""}; + char* _dst = __msg->txt; + char* _src = _tmptxt; + while(*_src) { + //char* _begline = _src; + + // Check for extended header + PcbExtHdr* _ehdr = (PcbExtHdr*)_src; + if(_ehdr->id == 0x40FF) { + if( strnieql(_ehdr->function, "TO ", 7)) + strncpy(_eto, _ehdr->desc, 60); + else if(strnieql(_ehdr->function, "TO2 ", 7)) + strncpy(_eto+60, _ehdr->desc, 60); + else if(strnieql(_ehdr->function, "FROM ", 7)) + strncpy(_eby, _ehdr->desc, 60); + else if(strnieql(_ehdr->function, "FROM2 ", 7)) + strncpy(_eby+60, _ehdr->desc, 60); + else if(strnieql(_ehdr->function, "SUBJECT", 7)) + strtrim(strncpy(__msg->re, _ehdr->desc, 60)); + _src += sizeof(PcbExtHdr); +} + else { + while(*_src) { + *_dst++ = *_src; + if(*_src++ == CR) { + #if 0 + // Get address and attribute from FidoPCB + if(isnet()) { + _line++; + if((_line == 1) AND (*_begline == '(' /*)*/)) { + Addr _addr; + _addr.ResetFast(); + char* _ptr = _begline + 1; + int _incoming = false; + if(strnieql(_ptr, "FROM:", 5)) { + _incoming = true; + _ptr += 5; + } + _addr.set(strskip_wht(_ptr)); + if(NOT _incoming AND strieql(__msg->by, WideUsername[0])) { + __msg->dest = _addr; + __msg->odest = _addr; + } + else { + __msg->orig = _addr; + __msg->oorig = _addr; + } + } + else if((_line == 2) AND (*_begline == '(' /*)*/)) { + _src[-1] = NUL; + if(striinc("HOLD", _begline)) + __msg->attr.hld1(); + if(striinc("IMM", _begline)) + __msg->attr.imm1(); + if(striinc("CRASH", _begline)) + __msg->attr.cra1(); + if(striinc("INTL", _begline)) + __msg->attr.zon1(); + _src[-1] = CR; + } + } + #endif + break; + } + } + } + } + *_dst = NUL; + strtrim(_eby); + if(*_eby) + strxcpy(__msg->by, _eby, sizeof(__msg->by)); + strtrim(_eto); + if(*_eto) + strxcpy(__msg->to, _eto, sizeof(__msg->to)); + + if(isnet() AND NOT isemail()) { + char* ptr = strchr(__msg->by, '@'); + if(ptr) { + *ptr++ = NUL; + __msg->orig.reset(ptr); + __msg->oorig = __msg->orig; + } + ptr = strchr(__msg->to, '@'); + if(ptr) { + *ptr++ = NUL; + char* ptr2 = strskip_txt(ptr); + if(*ptr2) { + *ptr2++ = NUL; + while(*ptr2) { + if(*ptr2 == '+') { + // get flags + switch(toupper(*(++ptr2))) { + case 'C': __msg->attr.cra1(); break; + case 'D': __msg->attr.dir1(); break; + } + } + else if(*ptr2 == '[') { + // get from-aka address + ptr2++; + char* ptr3 = ptr2; + ptr2 = strskip_to(ptr2, ']'); + if(*ptr2) { + *ptr2++ = NUL; + __msg->orig.reset(ptr3); + __msg->oorig = __msg->orig; + } + } + ptr2++; + } + } + __msg->dest.reset(ptr); + __msg->odest = __msg->dest; + } + } + + throw_free(_tmptxt); + + if(NOT(__mode & GMSG_TXT)) + throw_release(__msg->txt); + + GFTRK(NULL); + + return true; +} + + +// ------------------------------------------------------------------ + +int PcbArea::load_hdr(gmsg* __msg) { + + GFTRK("PcbLoadHdr"); + + PcbHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int PcbArea::load_msg(gmsg* __msg) { + + GFTRK("PcbLoadMsg"); + + PcbHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmopcbd4.cpp b/goldlib/gmb3/gmopcbd4.cpp new file mode 100644 index 0000000..2ed7808 --- /dev/null +++ b/goldlib/gmb3/gmopcbd4.cpp @@ -0,0 +1,443 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard msgbase handling. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +void PcbArea::lock() { + + GFTRK("PcbLock"); + + if(NOT data->islocked) { + if(WideCanLock) { + long _tries = 0; + while(::lock(data->fhmsg, 16, 6) == -1) { + if(PopupLocked(++_tries, true, path()) == false) { + WideLog->ErrLock(); + raw_close(); + WideLog->printf("! A PCBoard msgbase file could not be locked."); + WideLog->printf(": %s.", path()); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + } + if(_tries) + PopupLocked(0, 0, NULL); + } + lseekset(data->fhmsg, 0); + read(data->fhmsg, &data->base, sizeof(PcbBase)); + lseekset(data->fhmsg, 0); + memcpy(data->base.locked, "LOCKED", 6); + write(data->fhmsg, &data->base, sizeof(PcbBase)); + data->base.highmsgno = B2L(data->base.highmsgno); + data->base.lowmsgno = B2L(data->base.lowmsgno); + data->base.active = B2L(data->base.active); + data->islocked = true; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::unlock() { + + GFTRK("PcbUnlock"); + + if(WideCanLock AND data->islocked) + ::unlock(data->fhmsg, 16, 6); + lseekset(data->fhmsg, 0); + memset(data->base.locked, ' ', 6); + data->base.highmsgno = L2B(data->base.highmsgno); + data->base.lowmsgno = L2B(data->base.lowmsgno); + data->base.active = L2B(data->base.active); + write(data->fhmsg, &data->base, sizeof(PcbBase)); + data->base.highmsgno = B2L(data->base.highmsgno); + data->base.lowmsgno = B2L(data->base.lowmsgno); + data->base.active = B2L(data->base.active); + data->islocked = false; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::save_message(int __mode, gmsg* __msg, PcbHdr& __hdr) { + + // Lock and refresh base + int _was_locked = data->islocked; + if(NOT _was_locked) + lock(); + + // Reset header + memset(&__hdr, 0, sizeof(PcbHdr)); + + // Find msgno and index offset + PcbIdx _idx; + ulong oldmsgno = __msg->msgno; + long oldtxtstart = __msg->txtstart; + long oldtxtlength = __msg->txtlength; + if(__mode & GMSG_TXT) { + if(data->base.lowmsgno == 0) + data->base.lowmsgno = 1; + data->base.highmsgno++; + data->base.active++; + __msg->msgno = data->base.highmsgno; + Msgn->Append(__msg->msgno); + } + long _idxoffset = (__msg->msgno-data->base.lowmsgno)*(long)sizeof(PcbIdx); + __hdr.blocks = (byte)__msg->txtblocks; + _idx.num = __msg->msgno; + _idx.reserved[0] = _idx.reserved[1] = _idx.reserved[2] = 0; + + // Convert msgno and replylinks + __hdr.msgno = L2B(__msg->msgno); + __hdr.refno = L2B(__msg->link.to()); + + // Convert attributes + char _status = __msg->pcboard.status; + int _pvt = __msg->attr.pvt(); + int _rcv = __msg->attr.rcv(); + if(_rcv) { + switch(_status) { + case '$': __hdr.status = '#'; break; + case '!': __hdr.status = '#'; break; + case '%': __hdr.status = '^'; break; + case '~': __hdr.status = '`'; break; + case '*': __hdr.status = '+'; break; + case ' ': __hdr.status = '-'; break; + default: __hdr.status = _pvt ? '+' : '-'; + } + } + else { + if(_status AND NOT _pvt) + __hdr.status = _status; + else if(_pvt) + __hdr.status = '*'; + else + __hdr.status = ' '; + } + _idx.status = __hdr.status; + __hdr.activestatus = (__mode & GMSG_DELETE) ? '\xE2' : '\xE1'; + __hdr.echoed = ((isnet() OR isecho()) AND NOT isinternet()) ? 'E' : ' '; + + // Convert dates and times + char _dtbuf[9]; + struct tm* _tm = gmtime(&__msg->written); + memcpy(__hdr.date, strftimei(_dtbuf, 9, __msg->attr.uns() ? "%d-%m-%y" : "%d-%m\xC4%y", _tm), 8); + memcpy(__hdr.time, strftimei(_dtbuf, 6, "%H:%M", _tm), 5); + int _year = _tm->tm_year % 100; + _idx.date = (word)YMD2JDN(1900+_year, _tm->tm_mon+1, _tm->tm_mday); + if(__msg->link.first()) { + __hdr.hasreply = 'R'; + _tm = gmtime(&__msg->pcboard.reply_written); + _year = _tm->tm_year % 100; + __hdr.replydate = L2B((10000L*_year) + (100L*(_tm->tm_mon+1)) + _tm->tm_mday); + memcpy(__hdr.replytime, strftimei(_dtbuf, 6, "%H:%M", _tm), 5); + } + else { + __hdr.hasreply = ' '; + __hdr.replydate = L2B(0); + memcpy(__hdr.replytime, " ", 5); + } + + // Convert names, subject and password + char tobuf[150]; + char bybuf[150]; + strcpy(tobuf, __msg->to); + strcpy(bybuf, __msg->by); + int _tolen = strlen(tobuf); + int _bylen = strlen(bybuf); + int _relen = strlen(__msg->re); + int _pwlen = strlen(__msg->pcboard.password); + memset(__hdr.destname, ' ', 25); + memset(__hdr.origname, ' ', 25); + memset(__hdr.subject, ' ', 25); + memset(__hdr.password, ' ', 12); + strncpy(__hdr.destname, tobuf, MinV(_tolen, 25)); + strncpy(__hdr.origname, bybuf, MinV(_bylen, 25)); + strncpy(__hdr.subject, __msg->re, MinV(_relen, 25)); + strncpy(__hdr.password, __msg->pcboard.password, MinV(_pwlen, 12)); + memcpy(_idx.to, __hdr.destname, 25); + memcpy(_idx.from, __hdr.origname, 25); + if(isnet()) { + char toaddr[40]; + char byaddr[40]; + __msg->dest.make_string(toaddr); + strcpy(byaddr, " ["); + __msg->orig.make_string(byaddr+2); + strcat(byaddr, "]"); + sprintf(tobuf+strlen(tobuf), "@%s%s%s%s", + toaddr, + __msg->attr.cra() ? " +C" : "", + __msg->attr.dir() ? " +D" : "", + byaddr + ); + _tolen = strlen(tobuf); + _bylen = strlen(bybuf); + } + + // Determine size of the msg text including extended headers + uint _txtlen = 0; + if(__mode & GMSG_TXT) { + __msg->txtlength = _txtlen = strlen(__msg->txt); + if((_tolen > 25) OR isnet()) { + __msg->txtlength += sizeof(PcbExtHdr); + __hdr.exthdrflags |= 0x01; + } + if((_bylen > 25) OR isnet()) { + __msg->txtlength += sizeof(PcbExtHdr); + __hdr.exthdrflags |= 0x02; + } + if(_relen > 25) { + __msg->txtlength += sizeof(PcbExtHdr); + __hdr.exthdrflags |= 0x04; + } + + // Translate msg text to PCB linefeeds if running non-foreign system + if(NOT wide->foreign) + strchg(__msg->txt, 0x0D, 0xE3); + + // Calculate new number of blocks + __hdr.blocks = (byte)(1 + (__msg->txtlength/128) + ((__msg->txtlength%128)?1:0)); + + // Determine where to write the message text + __msg->txtstart = filelength(data->fhmsg); + __msg->txtblocks = __hdr.blocks; + } + + // Write index + _idx.offset = (__mode & GMSG_DELETE) ? -__msg->txtstart : __msg->txtstart; + lseekset(data->fhidx, _idxoffset); + write(data->fhidx, &_idx, sizeof(PcbIdx)); + + // Write header + lseekset(data->fhmsg, AbsV(_idx.offset)); + write(data->fhmsg, &__hdr, sizeof(PcbHdr)); + + // Writing msg text? + if(__mode & GMSG_TXT) { + + uint _txtlenwritten = 0; + + // Write extended headers + if((_tolen > 25) OR isnet()) { + PcbExtHdr _ehdr; + _ehdr.id = 0x40FF; + _ehdr.colon = ':'; + _ehdr.status = 'N'; + _ehdr.separator = wide->foreign ? '\x0D' : '\xE3'; + memcpy(_ehdr.function, "TO ", 7); + memset(_ehdr.desc, ' ', 60); + memcpy(_ehdr.desc, tobuf, MinV(60,_tolen)); + write(data->fhmsg, &_ehdr, sizeof(PcbExtHdr)); + _txtlenwritten += sizeof(PcbExtHdr); + if(_tolen > 60) { + memcpy(_ehdr.function, "TO2 ", 7); + memset(_ehdr.desc, ' ', 60); + memcpy(_ehdr.desc, tobuf+60, MinV(60,(_tolen-60))); + write(data->fhmsg, &_ehdr, sizeof(PcbExtHdr)); + _txtlenwritten += sizeof(PcbExtHdr); + } + } + if((_bylen > 25) OR isnet()) { + PcbExtHdr _ehdr; + _ehdr.id = 0x40FF; + _ehdr.colon = ':'; + _ehdr.status = 'N'; + _ehdr.separator = wide->foreign ? '\x0D' : '\xE3'; + memcpy(_ehdr.function, "FROM ", 7); + memset(_ehdr.desc, ' ', 60); + memcpy(_ehdr.desc, bybuf, MinV(60,_bylen)); + write(data->fhmsg, &_ehdr, sizeof(PcbExtHdr)); + _txtlenwritten += sizeof(PcbExtHdr); + if(_bylen > 60) { + memcpy(_ehdr.function, "FROM2 ", 7); + memset(_ehdr.desc, ' ', 60); + memcpy(_ehdr.desc, bybuf+60, MinV(60,(_bylen-60))); + write(data->fhmsg, &_ehdr, sizeof(PcbExtHdr)); + _txtlenwritten += sizeof(PcbExtHdr); + } + } + if(_relen > 25) { + PcbExtHdr _ehdr; + _ehdr.id = 0x40FF; + memcpy(_ehdr.function, "SUBJECT", 7); + _ehdr.colon = ':'; + memset(_ehdr.desc, ' ', 60); + memcpy(_ehdr.desc, __msg->re, MinV(60,_relen)); + _ehdr.status = 'N'; + _ehdr.separator = wide->foreign ? '\x0D' : '\xE3'; + write(data->fhmsg, &_ehdr, sizeof(PcbExtHdr)); + _txtlenwritten += sizeof(PcbExtHdr); + } + + // Special handling of netmails + #if 0 + if(isnet()) { + + // Write destination address in netmail for FidoPCB + char _abuf[40], _sbuf[45]; + sprintf(_sbuf, "(%s)%c", + __msg->dest.make_string(_abuf), + wide->foreign ? '\x0D' : '\xE3' + ); + uint _sbuflen = strlen(_sbuf); + write(data->fhmsg, _sbuf, _sbuflen); + _txtlenwritten += _sbuflen; + + // Write flags + int _hld = __msg->attr.hld(); + int _imm = __msg->attr.imm(); + int _cra = __msg->attr.cra(); + int _zon = __msg->attr.zon(); + if(_hld OR _imm OR _cra OR _zon) { + strcpy(_sbuf, "(" /*)*/); + if(_hld) + strcat(_sbuf, "HOLD,"); + if(_imm) + strcat(_sbuf, "IMM,"); + if(_cra) + strcat(_sbuf, "CRASH,"); + if(_zon) + strcat(_sbuf, "INTL,"); + _sbuf[strlen(_sbuf)] = /*(*/ ')'; + _sbuflen = strlen(_sbuf); + write(data->fhmsg, _sbuf, _sbuflen); + _txtlenwritten += _sbuflen; + } + } + #endif + + // Write message text + write(data->fhmsg, __msg->txt, _txtlen); + _txtlenwritten += _txtlen; + + // Write remainder of the last message block (if any) + uint _remainlen = ((__hdr.blocks-1)*128) - _txtlenwritten; + if(_remainlen) { + byte _remainrecord[128]; + memset(_remainrecord, ' ', 128); + write(data->fhmsg, _remainrecord, _remainlen); + } + + // Translate back + if(NOT wide->foreign) + strchg(__msg->txt, 0xE3, 0x0D); + } + + if(NOT(__mode & GMSG_DELETE)) { + // Set the mail waiting flag + int _status = true; + // Reset it if the msg is being received + if((__mode & GMSG_UPDATE) AND __msg->attr.rcv()) + _status = false; + // Don't touch the flag if the msg was already received + if(NOT (_status AND __msg->attr.rcv())) + pcbwide->user->update_mail_waiting(__msg->to, board(), _status); + } + + if((__mode & GMSG_TXT) AND (__mode & GMSG_UPDATE)) { + __msg->msgno = oldmsgno; + __msg->txtstart = oldtxtstart; + __msg->txtlength = oldtxtlength; + del_msg(__msg); + } + + // Unlock and update base + if(NOT _was_locked) + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("PcbSaveHdr"); + + PcbHdr _hdr; + save_message(__mode|GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void PcbArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("PcbSaveMsg"); + + PcbHdr _hdr; + save_message(__mode|GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void PcbArea::del_msg(gmsg* __msg) { + + GFTRK("PcbDelMsg"); + + PcbHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void PcbArea::new_msgno(gmsg* msg) { + + GFTRK("PcbNewMsgno"); + + msg->msgno = data->base.highmsgno + 1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void PcbArea::update_timesread(gmsg*) { + +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmopcbd5.cpp b/goldlib/gmb3/gmopcbd5.cpp new file mode 100644 index 0000000..e448635 --- /dev/null +++ b/goldlib/gmb3/gmopcbd5.cpp @@ -0,0 +1,176 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// PCBoard msgbase handling. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +char* PcbArea::user_lookup(char* lookfor) { + + NW(lookfor); + return NULL; +} + + +// ------------------------------------------------------------------ + +int PcbArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ + +Line* PcbArea::make_dump_msg(Line*& lin, gmsg* __msg, char* lng_head) { + + GFTRK("PcbMakeDump"); + + // Read lastread records + byte _mailwaiting = 0; + dword* dumplr = (dword*)throw_calloc(wide->numareas, sizeof(dword)); + lseekset(wide->fhusr, (long)wide->userno*(long)sizeof(PcbUsers)); + read(wide->fhusr, &wide->usersrec, sizeof(PcbUsers)); + int _maxlr = MinV(wide->numareas, 40); + int n; + for(n=0; n<_maxlr; n++) + dumplr[n] = wide->usersrec.lastmsgread[n]; + long _offset = (wide->usersrec.usersinfrec-1)*wide->usershdr.totalrecsize; + _offset += wide->usershdrsize; + _offset += wide->usershdr.sizeofrec; + long _offset2 = _offset; + _offset2 += board() / 8; + lseekset(wide->fhinf, _offset2); + read(wide->fhinf, &_mailwaiting, 1); + byte bitmask = (byte)(1 << (board() % 8)); + _mailwaiting &= bitmask; + _offset += 2 * wide->confbytelen; + _offset += 3 * wide->extconflen; + if(wide->extconflen) { + lseekset(wide->fhinf, _offset); + read(wide->fhinf, dumplr+40, (wide->numareas-40)*sizeof(long)); + } + + // Read index record for msg + PcbIdx _idx; + lseekset(data->fhidx, (__msg->msgno-data->base.lowmsgno)*(long)sizeof(PcbIdx)); + read(data->fhidx, &_idx, sizeof(PcbIdx)); + + // Read message header + PcbHdr _hdr; + lseekset(data->fhmsg, AbsV(_idx.offset)); + read(data->fhmsg, &_hdr, sizeof(PcbHdr)); + + // Read the message text + uint _msgsize = (_hdr.blocks-1)*128; + __msg->txt = (char*)throw_realloc(__msg->txt, _msgsize+256); + memset(__msg->txt, 0, _msgsize+256); + read(data->fhmsg, __msg->txt, _msgsize); + + // Convert Julian date in the index + unsigned _year, _month, _day; + JDN2YMD(_idx.date, &_year, &_month, &_day); + + Line* line = lin = + AddLine (NULL, "Hexdump of PCBoard message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Msgbase : %s", path()); + AddLineF(line, "BoardNo : %u", board()); + AddLineF(line, "MsgOffset : %li", _idx.offset); + AddLineF(line, "Status : \'%c\'", _hdr.status); + AddLineF(line, "Msgno : %li (%08lXh)", B2L(_hdr.msgno), _hdr.msgno); + AddLineF(line, "Refno : %li (%08lXh)", B2L(_hdr.refno), _hdr.refno); + AddLineF(line, "Blocks : %i", _hdr.blocks); + AddLineF(line, "Date/Time : %8.8s %5.5s", _hdr.date, _hdr.time); + AddLineF(line, "IdxDate : %02u-%02u-%02u (%u)", _month, _day, _year-1900, _idx.date); + AddLineF(line, "DestName : %-25.25s", _hdr.destname); + AddLineF(line, "ReplyDate : %li", B2L(_hdr.replydate)); + AddLineF(line, "ReplyTime : %5.5s", _hdr.replytime); + AddLineF(line, "HasReply : \'%c\'", _hdr.hasreply); + AddLineF(line, "OrigName : %-25.25s", _hdr.origname); + AddLineF(line, "Subject : %-25.25s", _hdr.subject); + AddLineF(line, "Password : %-12.12s", _hdr.password); + AddLineF(line, "Active : %u%s", _hdr.activestatus, (_hdr.activestatus == 226) ? " (Deleted)" : ""); + AddLineF(line, "Echoed : \'%c\'", _hdr.echoed); + AddLineF(line, "Reserved : %02Xh %02Xh %02Xh %02Xh ", _hdr.reserved[0], _hdr.reserved[1], _hdr.reserved[2], _hdr.reserved[3]); + AddLineF(line, "ExtHdrFlg : %02Xh", _hdr.exthdrflags); + AddLineF(line, "Reserved2 : %02Xh", _hdr.reserved2); + line = AddLine(line, ""); + AddLineF(line, "Message Base Header:"); + line = AddLine(line, ""); + AddLineF(line, "HighMsgno : %li", data->base.highmsgno); + AddLineF(line, "LowMsgno : %li", data->base.lowmsgno); + AddLineF(line, "Active : %li", data->base.active); + AddLineF(line, "Locked : %6.6s", data->base.locked); + + line = AddLine(line, ""); + AddLineF(line, "Mail Waiting: %s", _mailwaiting ? "Yes" : "No"); + line = AddLine(line, ""); + AddLineF(line, "Lastreads from the USERS file:"); + line = AddLine(line, ""); + for(n=0; n<_maxlr; n++) { + dword tmplr = B2L(dumplr[n]); + AddLineF(line, "Board %4u : %10lu / %08lXh / %08lXh", n, tmplr, tmplr, dumplr[n]); + } + + line = AddLine(line, ""); + AddLineF(line, "Lastreads from the USERS.INF file:"); + line = AddLine(line, ""); + for(; nnumareas; n++) + AddLineF(line, "Board %4u : %10lu / %08lXh", n, dumplr[n], dumplr[n]); + + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + char _buf[256]; + char* _ptr = (char*)&_hdr; + for(n=0; n < sizeof(PcbHdr); _ptr+=16,n+=16) { + sprintf(_buf, "%04X ", n); + HexDump16(_buf+7, _ptr, 16, HEX_DUMP2); + line = AddLine(line, _buf); + } + + throw_free(dumplr); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoprot.h b/goldlib/gmb3/gmoprot.h new file mode 100644 index 0000000..2a81c9c --- /dev/null +++ b/goldlib/gmb3/gmoprot.h @@ -0,0 +1,139 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Messagebase function prototypes +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include + +// ------------------------------------------------------------------ + +void EzycomInit(const char* msgbasepath, const char* userbasepath, int userno); +void EzycomExit(); + +void EzycomWideOpen(); +void EzycomWideClose(); + + +// ------------------------------------------------------------------ + +void FidoInit(const char* fidolastread, int fidohwmarks, int fidonullfix, int fidouserno, const char* squishuserpath); +void FidoExit(); +void FidoRenumberProgress(const char* s); + +void FidoWideOpen(); +void FidoWideClose(); + + +// ------------------------------------------------------------------ + +void GoldInit(const char* path, const char* syspath, int userno, long sizewarn=0, int ra2usersbbs=0); +void GoldExit(); + +void GoldWideOpen(); +void GoldWideClose(); + + +// ------------------------------------------------------------------ + +void HudsInit(const char* path, const char* syspath, int userno, long sizewarn, int ra2usersbbs); +void HudsExit(); +void HudsSizewarn(); + +void HudsWideOpen(); +void HudsWideClose(); + +void HGWarnRebuild(); + + +// ------------------------------------------------------------------ + +void JamInit(const char* jampath, int harddelete); +void JamExit(); + +void JamWideOpen(); +void JamWideClose(); + + +// ------------------------------------------------------------------ + +void PcbInit(const char* path, int userno); +void PcbExit(); +void PcbAdjustArea(uint rec, const char* msgfile); + +void PcbWideOpen(); +void PcbWideClose(); + + +// ------------------------------------------------------------------ + +void SquishInit(const char* userpath, int userno, int direct, int recycle, int squishscan); +void SquishExit(); + + +// ------------------------------------------------------------------ + +void SMBInit(); +void SMBExit(); + + +// ------------------------------------------------------------------ + +void WCatInit(int userno); +void WCatExit(); + +void WCatWideOpen(); +void WCatWideClose(); + + +// ------------------------------------------------------------------ + +void XbbsInit(const char* path, int userno); +void XbbsExit(); + +void XbbsWideOpen(); +void XbbsWideClose(); + + +// ------------------------------------------------------------------ +// When not in OS/2, use DUMMY AdeptXBBS functions + +#if not defined(__OS2__) + +#ifndef GMB_NOXBBS +inline void XbbsInit(const char*, int) { } +inline void XbbsExit() { } + +inline void XbbsWideOpen() { } +inline void XbbsWideClose() { } +#endif + +#endif + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmosmb.h b/goldlib/gmb3/gmosmb.h new file mode 100644 index 0000000..9da0820 --- /dev/null +++ b/goldlib/gmb3/gmosmb.h @@ -0,0 +1,475 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on freeware sources from Digital Dynamics +// ------------------------------------------------------------------ +// Synchronet message base +// ------------------------------------------------------------------ + +#ifndef __GMOSMB_H +#define __GMOSMB_H + + +// ------------------------------------------------------------------ + +#include + + +// ------------------------------------------------------------------ +// SMB library version used as reference (1.21a) + +const int SMB_VERSION = 0x0121; // SMB format version (High byte major, low byte minor) + + +// ------------------------------------------------------------------ + +const int SDT_BLOCK_LEN = 256; // Size of data blocks +const int SHD_BLOCK_LEN = 256; // Size of header blocks + +const int SMB_SELFPACK = 0; // Self-packing storage allocation +const int SMB_FASTALLOC = 1; // Fast allocation +const int SMB_HYPERALLOC = 2; // No allocation + +const int SMB_EMAIL = 1; // User numbers stored in Indexes + +// Time zone macros for when_t.zone +const int DAYLIGHT = 0x8000; // Daylight savings is active +const int US_ZONE = 0x4000; // U.S. time zone +const int WESTERN_ZONE = 0x2000; // Non-standard zone west of UT +const int EASTERN_ZONE = 0x1000; // Non-standard zone east of UT + +// Valid hfield_t.types +const int SENDER = 0x00; +const int SENDERAGENT = 0x01; +const int SENDERNETTYPE = 0x02; +const int SENDERNETADDR = 0x03; +const int SENDEREXT = 0x04; +const int SENDERPOS = 0x05; +const int SENDERORG = 0x06; + +const int AUTHOR = 0x10; +const int AUTHORAGENT = 0x11; +const int AUTHORNETTYPE = 0x12; +const int AUTHORNETADDR = 0x13; +const int AUTHOREXT = 0x14; +const int AUTHORPOS = 0x15; +const int AUTHORORG = 0x16; + +const int REPLYTO = 0x20; +const int REPLYTOAGENT = 0x21; +const int REPLYTONETTYPE = 0x22; +const int REPLYTONETADDR = 0x23; +const int REPLYTOEXT = 0x24; +const int REPLYTOPOS = 0x25; +const int REPLYTOORG = 0x26; + +const int RECIPIENT = 0x30; +const int RECIPIENTAGENT = 0x31; +const int RECIPIENTNETTYPE = 0x32; +const int RECIPIENTNETADDR = 0x33; +const int RECIPIENTEXT = 0x34; +const int RECIPIENTPOS = 0x35; +const int RECIPIENTORG = 0x36; + +const int FORWARDTO = 0x40; +const int FORWARDTOAGENT = 0x41; +const int FORWARDTONETTYPE = 0x42; +const int FORWARDTONETADDR = 0x43; +const int FORWARDTOEXT = 0x44; +const int FORWARDTOPOS = 0x45; +const int FORWARDTOORG = 0x46; + +const int FORWARDED = 0x48; + +const int RECEIVEDBY = 0x50; +const int RECEIVEDBYAGENT = 0x51; +const int RECEIVEDBYNETTYPE = 0x52; +const int RECEIVEDBYNETADDR = 0x53; +const int RECEIVEDBYEXT = 0x54; +const int RECEIVEDBYPOS = 0x55; +const int RECEIVEDBYORG = 0x56; + +const int RECEIVED = 0x58; + +const int SUBJECT = 0x60; +const int SUMMARY = 0x61; +const int SMBCOMMENT = 0x62; +const int CARBONCOPY = 0x63; +const int GROUP = 0x64; +const int EXPIRATION = 0x65; +const int PRIORITY = 0x66; + +const int FILEATTACH = 0x70; +const int DESTFILE = 0x71; +const int FILEATTACHLIST = 0x72; +const int DESTFILELIST = 0x73; +const int FILEREQUEST = 0x74; +const int FILEPASSWORD = 0x75; +const int FILEREQUESTLIST = 0x76; +const int FILEPASSWORDLIST = 0x77; + +const int IMAGEATTACH = 0x80; +const int ANIMATTACH = 0x81; +const int FONTATTACH = 0x82; +const int SOUNDATTACH = 0x83; +const int PRESENTATTACH = 0x84; +const int VIDEOATTACH = 0x85; +const int APPDATAATTACH = 0x86; + +const int IMAGETRIGGER = 0x90; +const int ANIMTRIGGER = 0x91; +const int FONTTRIGGER = 0x92; +const int SOUNDTRIGGER = 0x93; +const int PRESENTTRIGGER = 0x94; +const int VIDEOTRIGGER = 0x95; +const int APPDATATRIGGER = 0x96; + +const int FIDOCTRL = 0xa0; +const int FIDOAREA = 0xa1; +const int FIDOSEENBY = 0xa2; +const int FIDOPATH = 0xa3; +const int FIDOMSGID = 0xa4; +const int FIDOREPLYID = 0xa5; +const int FIDOPID = 0xa6; +const int FIDOFLAGS = 0xa7; + +const int RFC822HEADER = 0xb0; +const int RFC822MSGID = 0xb1; +const int RFC822REPLYID = 0xb2; + +const int UNKNOWN = 0xf1; +const int UNKNOWNASCII = 0xf2; +const int UNUSED = 0xff; + +// Valid dfield_t.types +const int TEXT_BODY = 0x00; +const int TEXT_SOUL = 0x01; +const int TEXT_TAIL = 0x02; +const int TEXT_WING = 0x03; +const int IMAGEEMBED = 0x20; +const int ANIMEMBED = 0x21; +const int FONTEMBED = 0x22; +const int SOUNDEMBED = 0x23; +const int PRESENTEMBED = 0x24; +const int VIDEOEMBED = 0x25; +const int APPDATAEMBED = 0x26; +//const int UNUSED = 0xff; + +// Message attributes +const int MSG_PRIVATE = (1<<0); +const int MSG_READ = (1<<1); +const int MSG_PERMANENT = (1<<2); +const int MSG_LOCKED = (1<<3); +const int MSG_DELETE = (1<<4); +const int MSG_ANONYMOUS = (1<<5); +const int MSG_KILLREAD = (1<<6); +const int MSG_MODERATED = (1<<7); +const int MSG_VALIDATED = (1<<8); + +// Auxillary header attributes +const int MSG_FILEREQUEST = (1<<0); // File request +const int MSG_FILEATTACH = (1<<1); // File(s) attached to Msg +const int MSG_TRUNCFILE = (1<<2); // Truncate file(s) when sent +const int MSG_KILLFILE = (1<<3); // Delete file(s) when sent +const int MSG_RECEIPTREQ = (1<<4); // Return receipt requested +const int MSG_CONFIRMREQ = (1<<5); // Confirmation receipt requested +const int MSG_NODISP = (1<<6); // Msg may not be displayed to user + +// Message network attributes +const int MSG_LOCAL = (1<<0); // Msg created locally +const int MSG_INTRANSIT = (1<<1); // Msg is in-transit +const int MSG_SENT = (1<<2); // Sent to remote +const int MSG_KILLSENT = (1<<3); // Kill when sent +const int MSG_ARCHIVESENT = (1<<4); // Archive when sent +const int MSG_HOLD = (1<<5); // Hold for pick-up +const int MSG_CRASH = (1<<6); // Crash +const int MSG_IMMEDIATE = (1<<7); // Send Msg now, ignore restrictions +const int MSG_DIRECT = (1<<8); // Send directly to destination +const int MSG_GATE = (1<<9); // Send via gateway +const int MSG_ORPHAN = (1<<10); // Unknown destination +const int MSG_FPU = (1<<11); // Force pickup +const int MSG_TYPELOCAL = (1<<12); // Msg is for local use only +const int MSG_TYPEECHO = (1<<13); // Msg is for conference distribution +const int MSG_TYPENET = (1<<14); // Msg is direct network mail + +enum { + NET_NONE, + NET_UNKNOWN, + NET_FIDO, + NET_POSTLINK, + NET_QWK, + NET_INTERNET, + NET_WWIV, + NET_MHS, + // Add new ones here + NET_TYPES +}; + +enum { + AGENT_PERSON, + AGENT_PROCESS, + // Add new ones here + AGENT_TYPES +}; + +enum { + XLAT_NONE, // No translation/End of translation list + XLAT_ENCRYPT, // Encrypted data + XLAT_ESCAPED, // 7-bit ASCII escaping for ctrl and 8-bit data + XLAT_HUFFMAN, // Static and adaptive Huffman coding compression + XLAT_LZW, // Limpel/Ziv/Welch compression + XLAT_MLZ78, // Modified LZ78 compression + XLAT_RLE, // Run length encoding compression + XLAT_IMPLODE, // Implode compression (PkZIP) + XLAT_SHRINK, // Shrink compression (PkZIP) + XLAT_LZH, // LHarc (LHA) Dynamic Huffman coding + // Add new ones here + XLAT_TYPES +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +typedef struct { + time_t time; // Local time (unix format) + sword zone; // Time zone +} when_t; + +typedef struct { + word to; // 16-bit CRC of recipient name (lower case) + word from; // 16-bit CRC of sender name (lower case) + word subj; // 16-bit CRC of subject (lower case, w/o RE:) + word attr; // attributes (read, permanent, etc.) + dword offset; // offset into header file + dword number; // number of message (1 based) + time_t time; // time/date message was imported/posted +} idxrec_t; + +typedef struct { + uchar id[4]; // text or binary unique hdr ID + word version; // version number (initially 100h for 1.00) + word length; // length including this struct +} smbhdr_t; + +typedef struct { + dword last_msg; // last message number + dword total_msgs; // total messages + dword header_offset; // byte offset to first header record + dword max_crcs; // Maximum number of CRCs to keep in history + dword max_msgs; // Maximum number of message to keep in sub + word max_age; // Maximum age of message to keep in sub (in days) + word attr; // Attributes for this message base (SMB_HYPER, etc) +} smbstatus_t; + +typedef struct { + uchar id[4]; // SHD<^Z> + word type; // Message type (normally 0) + word version; // Version of type (initially 100h for 1.00) + word length; // Total length of fixed record + all fields + word attr; // Attributes (bit field) (duped in SID) + dword auxattr; // Auxillary attributes (bit field) + dword netattr; // Network attributes + when_t when_written; // Time message was written (unix format) + when_t when_imported; // Time message was imported + dword number; // Message number + dword thread_orig; // Original message number in thread + dword thread_next; // Next message in thread + dword thread_first; // First reply to this message + uchar reserved[16]; // Reserved for future use + dword offset; // Offset for buffer into data file (0 or mod 256) + word total_dfields; // Total number of data fields +} msghdr_t; + +typedef struct { + word type; // Type of data field + dword offset; // Offset into buffer + dword length; // Length of data field +} dfield_t; + +typedef struct { + word type; + word length; // Length of buffer +} hfield_t; + +typedef struct { + word zone, net, node, point; +} fidoaddr_t; + +typedef struct { + word type; + void *addr; +} net_t; + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +typedef struct { + idxrec_t idx; // Index + msghdr_t hdr; // Header record (fixed portion) + uchar *to, // To name + *to_ext, // To extension + *from, // From name + *from_ext, // From extension + *replyto, // Reply-to name + *replyto_ext, // Reply-to extension */ + *subj; // Subject + word to_agent, // Type of agent message is to + from_agent, // Type of agent message is from + replyto_agent; // Type of agent replies should be sent to + net_t to_net, // Destination network type and address + from_net, // Origin network address + replyto_net; // Network type and address for replies + word total_hfields; // Total number of header fields + hfield_t *hfield; // Header fields (fixed length portion) + void **hfield_dat; // Header fields (variable length portion) + dfield_t *dfield; // Data fields (fixed length portion) + dword offset; // Offset (number of records) into index + uchar forwarded; // Forwarded from agent to another +} smbmsg_t; + + +// ------------------------------------------------------------------ + +struct SMBData { + char shd_buf[SHD_BLOCK_LEN]; + FILE *sdt_fp, *shd_fp, *sid_fp, *sda_fp, *sha_fp; +}; + + +// ------------------------------------------------------------------ + +class SMBArea : public gmo_area { + +protected: + + SMBData* data; + + void data_open(); + void data_close(); + + void raw_scan(bool keep_index=false, bool scanpm=false); + + FILE* smb_openexlusively(const char *file, int retry_time); + int smb_openexlusively2(const char *file, int retry_time); + + int smb_open(int retry_time); + void smb_close(void); + int smb_open_da(int retry_time); + int smb_open_ha(int retry_time); + int smb_create(dword max_crcs, dword max_msgs, word max_age, word attr, int retry_time); + int smb_trunchdr(int retry_time); + int smb_locksmbhdr(int retry_time); + int smb_getstatus(smbstatus_t *status); + int smb_putstatus(smbstatus_t status); + int smb_unlocksmbhdr(void); + int smb_getmsgidx(smbmsg_t *msg); + int smb_getlastidx(idxrec_t *idx); + uint smb_getmsghdrlen(smbmsg_t msg); + dword smb_getmsgdatlen(smbmsg_t msg); + int smb_lockmsghdr(smbmsg_t msg, int retry_time); + int smb_getmsghdr(smbmsg_t *msg); + int smb_unlockmsghdr(smbmsg_t msg); + int smb_addcrc(dword max_crcs, dword crc, int retry_time); + int smb_hfield(smbmsg_t *msg, word type, word length, void *data); + int smb_dfield(smbmsg_t *msg, word type, dword length); + int smb_addmsghdr(smbmsg_t *msg, smbstatus_t *status, int storage, int retry_time); + int smb_putmsg(smbmsg_t msg); + int smb_putmsgidx(smbmsg_t msg); + int smb_putmsghdr(smbmsg_t msg); + void smb_freemsgmem(smbmsg_t msg); + dword smb_hdrblocks(dword length); + dword smb_datblocks(dword length); + long smb_allochdr(dword length); + long smb_fallochdr(dword length); + long smb_hallochdr(dword header_offset); + long smb_allocdat(dword length, word headers); + long smb_fallocdat(dword length, word headers); + long smb_hallocdat(void); + int smb_incdat(dword offset, dword length, word headers); + int smb_freemsg(smbmsg_t msg, smbstatus_t status); + int smb_freemsgdat(dword offset, dword length, word headers); + int smb_freemsghdr(dword offset, dword length); + int load_hdr(gmsg* __msg, smbmsg_t *msg); + +public: + + SMBArea() { data = NULL; } + virtual ~SMBArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg) { return load_hdr(msg, NULL); } + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern SMBData* smbdata; +extern int smbdatano; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmosmb1.cpp b/goldlib/gmb3/gmosmb1.cpp new file mode 100644 index 0000000..de4d35f --- /dev/null +++ b/goldlib/gmb3/gmosmb1.cpp @@ -0,0 +1,1027 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Synchronet message base +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +SMBData* smbdata = NULL; +int smbdatano = 0; + + +// ------------------------------------------------------------------ + +void SMBExit() { + + throw_release(smbdata); +} + + +// ------------------------------------------------------------------ + +void SMBInit() { + + smbdata = (SMBData*)throw_calloc(2, sizeof(SMBData)); +} + + +// ------------------------------------------------------------------ + +FILE* SMBArea::smb_openexlusively(const char *__file, int retry_time) { + + FILE *_f; + long _tries = 0; + + do { + + _f = fsopen(__file, "rb+", SH_DENYRW); + if(_f == NULL) { + + if((errno != EACCES) or (PopupLocked(++_tries, false, __file) == false)) { + + // User requested to exit + WideLog->ErrOpen(); + WideLog->printf("! Synchronet message base could not be opened (exclusively)."); + WideLog->printf(": %s", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_f == NULL); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + return _f; +} + + +// ------------------------------------------------------------------ + +int SMBArea::smb_openexlusively2(const char *__file, int retry_time) { + + int _fh; + long _tries = 0; + + do { + + _fh = ::sopen(__file, O_RDWR|O_CREAT|O_BINARY, SH_DENYRW, S_STDRW); + if(_fh == -1) { + + if((errno != EACCES) or (PopupLocked(++_tries, false, __file) == false)) { + + // User requested to exit + WideLog->ErrOpen(); + WideLog->printf("! Synchronet message base could not be opened (exclusively)."); + WideLog->printf(": %s", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void SMBArea::data_open() { + + data = smbdata + (smbdatano++); + data->sdt_fp = data->shd_fp = data->sid_fp = data->sda_fp = data->sha_fp = NULL; +} + + +// ------------------------------------------------------------------ + +void SMBArea::data_close() { + + smbdatano--; + data = NULL; +} + + +// ------------------------------------------------------------------ +// Open the Synchronet message base + +void SMBArea::open() { + + GFTRK("SMBOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a Synchronet msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + smb_open(10); + if(not fsize(data->shd_fp)) + smb_create(2000, 2000, 0, 0, 10); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SMBArea::close() +{ + GFTRK("SMBClose"); + + if(isopen) { + if(isopen == 1) { + smb_close(); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed Synchronet msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SMBArea::suspend() +{ + smb_close(); +} + + +// ------------------------------------------------------------------ + +void SMBArea::resume() +{ + smb_open(10); + if(not fsize(data->shd_fp)) + smb_create(2000, 2000, 0, 0, 10); +} + + +// ------------------------------------------------------------------ + +void SMBArea::lock() +{ +} + + +// ------------------------------------------------------------------ + +void SMBArea::unlock() +{ +} + + +// ------------------------------------------------------------------ + +int SMBArea::load_hdr(gmsg* __msg, smbmsg_t *smsg) +{ + GFTRK("SMBLoadHdr"); + + smbmsg_t local_smsg, *smsgp; + smsgp = smsg ? smsg : &local_smsg; + ulong reln = Msgn->ToReln(__msg->msgno); + if(reln == 0) { + GFTRK(NULL); + return false; + } + fseek(data->sid_fp, (reln - 1L) * sizeof(idxrec_t), SEEK_SET); + if(not fread(&smsgp->idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(*smsgp, 10) != 0)) { + GFTRK(NULL); + return false; + } + int rv = smb_getmsghdr(smsgp); + smb_unlockmsghdr(*smsgp); + if(rv != 0) { + GFTRK(NULL); + return false; + } + __msg->link.to_set(smsgp->hdr.thread_orig); + __msg->link.next_set(smsgp->hdr.thread_next); + __msg->link.first_set(smsgp->hdr.thread_first); + + strxcpy(__msg->by, (char *)smsgp->from, 36); + strxcpy(__msg->to, (char *)smsgp->to, 36); + strxcpy(__msg->re, (char *)smsgp->subj, 72); + + if(smsgp->from_net.type == NET_FIDO) { + __msg->orig.zone = __msg->oorig.zone = ((fidoaddr_t *)smsgp->from_net.addr)->zone; + __msg->orig.net = __msg->oorig.net = ((fidoaddr_t *)smsgp->from_net.addr)->net; + __msg->orig.node = __msg->oorig.node = ((fidoaddr_t *)smsgp->from_net.addr)->node; + __msg->orig.point = __msg->oorig.point = ((fidoaddr_t *)smsgp->from_net.addr)->point; + } + else { + __msg->orig.zone = __msg->oorig.zone = 0; + __msg->orig.net = __msg->oorig.net = 0; + __msg->orig.node = __msg->oorig.node = 0; + __msg->orig.point = __msg->oorig.point = 0; + } + if(smsgp->to_net.type == NET_FIDO) { + __msg->dest.zone = __msg->odest.zone = ((fidoaddr_t *)smsgp->to_net.addr)->zone; + __msg->dest.net = __msg->odest.net = ((fidoaddr_t *)smsgp->to_net.addr)->net; + __msg->dest.node = __msg->odest.node = ((fidoaddr_t *)smsgp->to_net.addr)->node; + __msg->dest.point = __msg->odest.point = ((fidoaddr_t *)smsgp->to_net.addr)->point; + } + else { + __msg->dest.zone = __msg->odest.zone = 0; + __msg->dest.net = __msg->odest.net = 0; + __msg->dest.node = __msg->odest.node = 0; + __msg->dest.point = __msg->odest.point = 0; + } + + // Transfer attributes + __msg->attr.pvt(smsgp->hdr.attr & MSG_PRIVATE); + __msg->attr.rcv(smsgp->hdr.attr & MSG_READ); + __msg->attr.lok(smsgp->hdr.attr & MSG_LOCKED); + __msg->attr.del(smsgp->hdr.attr & MSG_DELETE); + __msg->attr.r_o(smsgp->hdr.attr & MSG_PERMANENT); + __msg->attr.loc(smsgp->hdr.netattr & MSG_LOCAL); + __msg->attr.cra(smsgp->hdr.netattr & MSG_CRASH); + __msg->attr.imm(smsgp->hdr.netattr & MSG_IMMEDIATE); + __msg->attr.dir(smsgp->hdr.netattr & MSG_DIRECT); + __msg->attr.hld(smsgp->hdr.netattr & MSG_HOLD); + __msg->attr.snt(smsgp->hdr.netattr & MSG_SENT); + __msg->attr.trs(smsgp->hdr.netattr & MSG_INTRANSIT); + __msg->attr.orp(smsgp->hdr.netattr & MSG_ORPHAN); + __msg->attr.k_s(smsgp->hdr.netattr & MSG_KILLSENT); + __msg->attr.a_s(smsgp->hdr.netattr & MSG_ARCHIVESENT); + __msg->attr.zon(smsgp->hdr.netattr & MSG_GATE); + __msg->attr.att(smsgp->hdr.auxattr & MSG_FILEATTACH); + __msg->attr.frq(smsgp->hdr.auxattr & MSG_FILEREQUEST); + __msg->attr.rrq(smsgp->hdr.auxattr & MSG_RECEIPTREQ); + __msg->attr.cfm(smsgp->hdr.auxattr & MSG_CONFIRMREQ); + __msg->attr.tfs(smsgp->hdr.auxattr & MSG_TRUNCFILE); + + time_t a = smsgp->hdr.when_written.time; + time_t b = mktime(gmtime(&a)); + __msg->written = a + a - b; + a = smsgp->hdr.when_imported.time; + b = mktime(gmtime(&a)); + __msg->arrived = a + a - b; + __msg->received = 0; + + if(not smsg) + smb_freemsgmem(*smsgp); + GFTRK(NULL); + return true; +} + + +// ------------------------------------------------------------------ + +int SMBArea::load_msg(gmsg* msg) +{ + smbmsg_t smsg; + ushort xlat; + char *inbuf; + long outlen; + char buf[512]; + int i; + bool lzh; + bool tail = true; + ulong l; + ulong txt_len = 1; + + GFTRK("SMBLoadMsg"); + + if(not load_hdr(msg, &smsg)) { + GFTRK(NULL); + return false; + } + + msg->txt = throw_strdup(""); + + if(smsg.from_net.type == NET_INTERNET) { + sprintf(buf, "\001From: %s (%s)\r", (char *)smsg.from_net.addr, smsg.from); + outlen = strlen(buf); + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + strcpy(msg->txt+txt_len-1, buf); + txt_len+=outlen; + } + if(smsg.to_net.type == NET_INTERNET) { + sprintf(buf, "\001To: %s (%s)\r", (char *)smsg.to_net.addr, smsg.to); + outlen = strlen(buf); + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + strcpy(msg->txt+txt_len-1, buf); + txt_len+=outlen; + } + + for(i = 0; i < smsg.total_hfields; i++) + switch(smsg.hfield[i].type) { + case RFC822MSGID: + sprintf(buf, "\001Message-ID: %s\r", (char *)smsg.hfield_dat[i]); + goto add; + case FIDOMSGID: + sprintf(buf, "\001MSGID: %s\r", (char *)smsg.hfield_dat[i]); + goto add; + case RFC822REPLYID: + sprintf(buf, "\001In-Reply-To: %s\r", (char *)smsg.hfield_dat[i]); + goto add; + case FIDOREPLYID: + sprintf(buf, "\001REPLYID: %s\r", (char *)smsg.hfield_dat[i]); + goto add; + case FIDOPID: + sprintf(buf, "\001PID: %s\r", (char *)smsg.hfield_dat[i]); + strcpy(msg->pid, (char *)smsg.hfield_dat[i]); + goto add; + case FIDOAREA: + sprintf(buf, "\001AREA: %s\r", (char *)smsg.hfield_dat[i]); + goto add; + case FIDOFLAGS: + sprintf(buf, "\001FLAGS: %s\r", (char *)smsg.hfield_dat[i]); + goto add; + case FIDOCTRL: + if(not strncmp((char *)smsg.hfield_dat[i], "Via ", 4) or not strncmp((char *)smsg.hfield_dat[i], "Recd ", 5)) + break; + case RFC822HEADER: + if(not strncmp((char *)smsg.hfield_dat[i], "Via:", 4)) + break; + sprintf(buf, "\001%s\r", (char *)smsg.hfield_dat[i]); +add: + outlen = strlen(buf); + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + strcpy(msg->txt+txt_len-1, buf); + txt_len+=outlen; + break; + default: + break; + } + + for(i = 0; i < smsg.hdr.total_dfields; i++) + switch(smsg.dfield[i].type) { + case TEXT_BODY: + if(tail) + tail = false; + goto common; + case TEXT_TAIL: + if(not tail) { + tail = true; + msg->txt[txt_len-1] = '\r'; + txt_len++; + } +common: + fseek(data->sdt_fp, smsg.hdr.offset + smsg.dfield[i].offset, SEEK_SET); + fread(&xlat, 2, 1, data->sdt_fp); + l = 2; + lzh = false; + while(xlat != XLAT_NONE) { + if(xlat == XLAT_LZH) + lzh = true; + fread(&xlat, 2, 1, data->sdt_fp); + l += 2; + } + if(lzh) { + inbuf = (char *)throw_xmalloc(smsg.dfield[i].length); + fread(inbuf, smsg.dfield[i].length - l, 1, data->sdt_fp); + outlen = *(long *)inbuf; + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + glzh_decode(inbuf, smsg.dfield[i].length - l, msg->txt+txt_len-1); + throw_xfree(inbuf); + } else { + outlen = smsg.dfield[i].length - l; + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + fread(msg->txt+txt_len-1, smsg.dfield[i].length - l, 1, data->sdt_fp); + } + txt_len+=outlen; + msg->txt[txt_len-1] = NUL; + break; + } + + for(i = 0; i < smsg.total_hfields; i++) + switch(smsg.hfield[i].type) { + case FIDOPATH: + sprintf(buf, "\r\001PATH: %s", (char *)smsg.hfield_dat[i]); + goto add2; + case FIDOSEENBY: + sprintf(buf, "\rSEEN-BY: %s", (char *)smsg.hfield_dat[i]); + goto add2; + case FIDOCTRL: + if(strncmp((char *)smsg.hfield_dat[i], "Via ", 4) and strncmp((char *)smsg.hfield_dat[i], "Recd ", 5)) + break; + sprintf(buf, "\r\001%s", (char *)smsg.hfield_dat[i]); +add2: + outlen = strlen(buf); + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + strcpy(msg->txt+txt_len-1, buf); + txt_len+=outlen; + break; + default: + break; + } + + + smb_freemsgmem(smsg); + + GFTRK(NULL); + return true; +} + + +// ------------------------------------------------------------------ + +void SMBArea::save_hdr(int mode, gmsg* msg) +{ + int rv; + char ch; + bool done, cr; + ulong l, m, bodylen, taillen, crc; + char *fbuf, *sbody, *stail; + char buf[256]; + smbmsg_t smsg; + smbstatus_t status; + fidoaddr_t destaddr, origaddr; + + GFTRK("SMBSaveHdr"); + + smb_getstatus(&status); + memset(&smsg, 0, sizeof(smbmsg_t)); + if(not (mode & GMSG_NEW)) { + ulong reln = Msgn->ToReln(msg->msgno); + if(reln == 0) { + GFTRK(NULL); + return; + } + fseek(data->sid_fp, (reln - 1L) * sizeof(idxrec_t), SEEK_SET); + if(not fread(&smsg.idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(smsg, 10) != 0)) { + GFTRK(NULL); + return; + } + int rv = smb_getmsghdr(&smsg); + smb_unlockmsghdr(smsg); + if(rv != 0) { + GFTRK(NULL); + return; + } + smsg.hdr.attr = 0; + smsg.hdr.netattr = 0; + smsg.hdr.auxattr = 0; + } + else { + memcpy(smsg.hdr.id, "SHD\x1a", 4); + smsg.hdr.version = SMB_VERSION; + smsg.hdr.when_written.time = mktime(gmtime(&msg->written)); + } + smsg.hdr.when_imported.time = time(NULL); + + // Transfer attributes + if(msg->attr.pvt()) smsg.hdr.attr |= MSG_PRIVATE; + if(msg->attr.rcv()) smsg.hdr.attr |= MSG_READ; + if(msg->attr.lok()) smsg.hdr.attr |= MSG_LOCKED; + if(msg->attr.del()) smsg.hdr.attr |= MSG_DELETE; + if(msg->attr.r_o()) smsg.hdr.attr |= MSG_PERMANENT; + if(msg->attr.loc()) smsg.hdr.netattr |= MSG_LOCAL; + if(msg->attr.cra()) smsg.hdr.netattr |= MSG_CRASH; + if(msg->attr.imm()) smsg.hdr.netattr |= MSG_IMMEDIATE; + if(msg->attr.dir()) smsg.hdr.netattr |= MSG_DIRECT; + if(msg->attr.hld()) smsg.hdr.netattr |= MSG_HOLD; + if(msg->attr.snt()) smsg.hdr.netattr |= MSG_SENT; + if(msg->attr.trs()) smsg.hdr.netattr |= MSG_INTRANSIT; + if(msg->attr.orp()) smsg.hdr.netattr |= MSG_ORPHAN; + if(msg->attr.k_s()) smsg.hdr.netattr |= MSG_KILLSENT; + if(msg->attr.a_s()) smsg.hdr.netattr |= MSG_ARCHIVESENT; + if(msg->attr.zon()) smsg.hdr.netattr |= MSG_GATE; + if(msg->attr.att()) smsg.hdr.auxattr |= MSG_FILEATTACH; + if(msg->attr.frq()) smsg.hdr.auxattr |= MSG_FILEREQUEST; + if(msg->attr.rrq()) smsg.hdr.auxattr |= MSG_RECEIPTREQ; + if(msg->attr.cfm()) smsg.hdr.auxattr |= MSG_CONFIRMREQ; + if(msg->attr.tfs()) smsg.hdr.auxattr |= MSG_TRUNCFILE; + + smsg.hdr.thread_orig = msg->link.to(); + smsg.hdr.thread_next = msg->link.next(); + smsg.hdr.thread_first = msg->link.first(); + + if((mode & GMSG_UPDATE) and not (mode & GMSG_TXT)) { + if(mode & GMSG_NEW) + smb_addmsghdr(&smsg, &status, 1, 10); + else + smb_putmsghdr(smsg); + smb_freemsgmem(smsg); + GFTRK(NULL); + return; + } + + if(not (mode & GMSG_NEW)) { + if(smb_open_da(10) == 0) { + if(smb_open_ha(10) == 0) { + smb_freemsg(smsg, status); + fclose(data->sha_fp); + } + fclose(data->sda_fp); + } + smb_freemsgmem(smsg); + smsg.dfield = NULL; + smsg.hdr.total_dfields = 0; + smsg.total_hfields = 0; + smsg.hfield = NULL; + smsg.hfield_dat = NULL; + } + + ushort net = NET_FIDO; + origaddr.zone = msg->orig.zone; + origaddr.net = msg->orig.net; + origaddr.node = msg->orig.node; + origaddr.point = msg->orig.point; + smb_hfield(&smsg, SENDERNETTYPE, sizeof(ushort), &net); + smb_hfield(&smsg, SENDERNETADDR, sizeof(fidoaddr_t), &origaddr); + + destaddr.zone = msg->dest.zone; + destaddr.net = msg->dest.net; + destaddr.node = msg->dest.node; + destaddr.point = msg->dest.point; + smb_hfield(&smsg, RECIPIENTNETTYPE, sizeof(ushort), &net); + smb_hfield(&smsg, RECIPIENTNETADDR, sizeof(fidoaddr_t), &destaddr); + + smb_hfield(&smsg, SENDER, strlen(msg->by), msg->by); + strcpy(buf, msg->by); + strlwr(buf); + smsg.idx.from = strCrc16(buf); + + smb_hfield(&smsg, RECIPIENT, strlen(msg->to), msg->to); + strcpy(buf, msg->to); + strlwr(buf); + smsg.idx.to = strCrc16(buf); + + smb_hfield(&smsg, SUBJECT, strlen(msg->re), msg->re); + strcpy(buf, msg->re); + strlwr(buf); + smsg.idx.subj = strCrc16(buf); + + // calculate maximum possible size of sbody/stail + for(l = 0, fbuf = msg->txt; *fbuf != NUL; l++, fbuf++) + if(l == CR) + ++l; + + fbuf = msg->txt; + sbody = (char *)throw_malloc(SDT_BLOCK_LEN*smb_datblocks(l)); + stail = (char *)throw_malloc(SDT_BLOCK_LEN*smb_datblocks(l)); + + for(l = bodylen = taillen = done = 0, cr = true; (ch = fbuf[l]) != NUL; l++) { + if(ch == CTRL_A and cr) { + ++l; + if(not strncmp(fbuf+l, "MSGID:", 6)) { + l += 6; + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOMSGID, m-l, fbuf+l); + } + else if(not strncmp(fbuf+l, "REPLY:", 6)) { + l += 6; + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOREPLYID, m-l, fbuf+l); + } + else if(not strncmp(fbuf+l, "FLAGS:", 6)) { + l += 6; + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOFLAGS, m-l, fbuf+l); + } + else if(not strncmp(fbuf+l, "PATH:", 5)) { + l += 5; + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOPATH, m-l, fbuf+l); + } + else if(not strncmp(fbuf+l, "PID:", 4)) { + l += 4; + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOPID, m-l, fbuf+l); + } + else { + if(strncmp(fbuf+l, "TOPT ", 5) and strncmp(fbuf+l, "FMPT ", 5) and + strncmp(fbuf+l, "INTL ", 5)) { + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOCTRL, m-l, fbuf+l); + } + } + while(fbuf[l] and fbuf[l]!=CR) l++; + continue; + } + if(ch != LF and ch != SOFTCR) { + if(cr) { + if(not done and not strncmp(fbuf+l, "--- ", 4) or not strncmp(fbuf+l, "---\r", 4)) + done = true; // tear line and down go into tail + else if(done and not strncmp(fbuf+l, "SEEN-BY:", 8)) { + l += 8; + while(fbuf[l] and fbuf[l] == ' ') l++; + m = l; + while(fbuf[m] and not iscntrl(fbuf[m])) m++; + if(m != l) + smb_hfield(&smsg, FIDOSEENBY, m-l, fbuf+l); + while(fbuf[l] and fbuf[l]!=CR) l++; + continue; + } + else if(not done and not strncmp(fbuf+l, " * Origin: ", 11)) + done = true; + } + if(done) + stail[taillen++] = ch; + else + sbody[bodylen++] = ch; + if(ch == CR) { + cr = true; + if(done) + stail[taillen++] = LF; + else + sbody[bodylen++] = LF; + } + else + cr = false; + } + } + if(bodylen>=2 && sbody[bodylen-2]==CR && sbody[bodylen-1]==LF) + bodylen-=2; // remove last CRLF if present + + crc = ~memCrc32(sbody, bodylen, false, CRC32_MASK_CCITT); + rv = smb_addcrc(status.max_crcs, crc, 10); + + while(taillen and (iscntrl(stail[taillen-1]) or isspace(stail[taillen-1]))) + taillen--; + + if(smb_open_da(10) == 0) { + l = bodylen+2; + if(taillen) + l += (taillen+2); + smsg.hdr.offset = smb_fallocdat(l, 1); + fclose(data->sda_fp); + if(not (smsg.hdr.offset and smsg.hdr.offset<1L)) { + fseek(data->sdt_fp, smsg.hdr.offset, SEEK_SET); + ushort xlat = XLAT_NONE; + fwrite(&xlat, 2, 1, data->sdt_fp); + l = ftell(data->sdt_fp); + fwrite(sbody, SDT_BLOCK_LEN, smb_datblocks(bodylen), data->sdt_fp); + if(taillen) { + fseek(data->sdt_fp, l+bodylen, SEEK_SET); + fwrite(&xlat, 2, 1, data->sdt_fp); + fwrite(stail, SDT_BLOCK_LEN, smb_datblocks(taillen), data->sdt_fp); + } + fflush(data->sdt_fp); + smb_dfield(&smsg, TEXT_BODY, bodylen+2); + if(taillen) + smb_dfield(&smsg, TEXT_TAIL, taillen+2); + + if(mode & GMSG_NEW) { + smb_addmsghdr(&smsg, &status, 1, 10); + Msgn->Append(smsg.hdr.number); + } + else + smb_putmsghdr(smsg); + } + } + throw_xfree(sbody); + throw_xfree(stail); + smb_freemsgmem(smsg); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SMBArea::save_msg(int mode, gmsg* msg) +{ + GFTRK("SMBSaveMsg"); + + save_hdr(mode | GMSG_HDRTXT, msg); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SMBArea::del_msg(gmsg* msg) +{ + GFTRK("SMBDelMsg"); + + smbmsg_t smsg; + ulong reln = Msgn->ToReln(msg->msgno); + if(reln == 0) { + GFTRK(NULL); + return; + } + fseek(data->sid_fp, (reln - 1L) * sizeof(idxrec_t), SEEK_SET); + if(not fread(&smsg.idx, 1, sizeof(idxrec_t), data->sid_fp) or (smb_lockmsghdr(smsg, 10) != 0)) { + GFTRK(NULL); + return; + } + if(smb_getmsghdr(&smsg) == 0) { + smsg.hdr.attr |= MSG_DELETE; + int rv = smb_putmsghdr(smsg); + smb_unlockmsghdr(smsg); + if(rv == 0) + msg->attr.del1(); + } + else + smb_unlockmsghdr(smsg); + smb_freemsgmem(smsg); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SMBArea::new_msgno(gmsg* msg) +{ + smbstatus_t status; + int res = smb_getstatus(&status); + smb_unlocksmbhdr(); + msg->msgno = (res == 0) ? status.last_msg+1 : 0; +} + + +// ------------------------------------------------------------------ + +char* SMBArea::user_lookup(char* lookfor) +{ + NW(lookfor); + return NULL; +} + + +// ------------------------------------------------------------------ + +int SMBArea::renumber() +{ + return false; +} + + +// ------------------------------------------------------------------ + +void SMBArea::update_timesread(gmsg* msg) +{ + NW(msg); + return; +} + + +// ------------------------------------------------------------------ + +static char *binstr(char *buf, ushort length) +{ + static char str[128]; + char tmp[128]; + int i; + + str[0] = 0; + for(i = 0; i < length; i++) + if(buf[i] and not isprint(buf[i])) + break; + if(i == length) /* not binary */ + return buf; + + if(length > 42) + length = 42; + + for(i = 0; i < length; i++) { + sprintf(tmp, "%02X ", buf[i]); + strcat(str, tmp); + } + return str; +} + + +// ------------------------------------------------------------------ + +static char *faddrtoa(fidoaddr_t addr) +{ + static char str[25]; + char point[25]; + + sprintf(str, "%u:%u/%u", addr.zone, addr.net, addr.node); + if (addr.point) { + sprintf(point, ".%u", addr.point); + strcat(str, point); + } + return str; +} + + +// ------------------------------------------------------------------ + +Line* SMBArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) +{ + + GFTRK("SMBMakeDump"); + + Line* line = lin = + AddLine (NULL, "Hexdump of Synchronet-style message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + + smbmsg_t smsg; + char buf[512]; + int i; + + GFTRK("SMBLoadMsg"); + + if(not load_hdr(msg, &smsg)) { + line = AddLine(line, "Error loading header"); + GFTRK(NULL); + return line; + } + + line = AddLineF(line, "Subject : %s", smsg.subj); + line = AddLineF(line, "From : %s", smsg.from); + line = AddLineF(line, "To : %s", smsg.to); + line = AddLineF(line, "Type : %04Xh", smsg.hdr.type); + line = AddLineF(line, "Version : %04Xh", smsg.hdr.version); + line = AddLineF(line, "Length : %u", smsg.hdr.length); + line = AddLineF(line, "Attr : %04Xh", smsg.hdr.attr); + line = AddLineF(line, "AUXAttr : %04lXh", smsg.hdr.auxattr); + line = AddLineF(line, "NetAttr : %04lXh", smsg.hdr.netattr); + stpcpy(buf, ctime((time_t *)&smsg.hdr.when_written.time))[-1] = NUL; + line = AddLineF(line, "Written : %s", buf); + stpcpy(buf, ctime((time_t *)&smsg.hdr.when_imported.time))[-1] = NUL; + line = AddLineF(line, "Imported : %s", buf); + line = AddLineF(line, "Number : %ld (%ld)", smsg.hdr.number, ftell(data->sid_fp) / sizeof(idxrec_t)); + line = AddLineF(line, "Thread orig : %ld", smsg.hdr.thread_orig); + line = AddLineF(line, "Thread next : %ld", smsg.hdr.thread_next); + line = AddLineF(line, "Thread first : %ld", smsg.hdr.thread_first); + line = AddLineF(line, "Reserved : %s", HexDump16(buf, (const char*)smsg.hdr.reserved, 16, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X")); + line = AddLineF(line, "Offset : %06lXh", smsg.hdr.offset); + line = AddLineF(line, "Total dfields : %u", smsg.hdr.total_dfields); + + if(smsg.from_net.type) { + line = AddLineF(line, "From net type : %02Xh", smsg.from_net.type); + line = AddLineF(line, "From net addr : %s", (char *)(smsg.from_net.type == NET_FIDO ? faddrtoa(*(fidoaddr_t *)smsg.from_net.addr) : smsg.from_net.addr)); + } + + if(smsg.to_net.type) { + line = AddLineF(line, "To net type : %02Xh", smsg.to_net.type); + line = AddLineF(line, "To net addr : %s", (char *)(smsg.to_net.type == NET_FIDO ? faddrtoa(*(fidoaddr_t *)smsg.to_net.addr) : smsg.to_net.addr)); + } + + if(smsg.replyto_net.type) { + line = AddLineF(line, "Replyto net type : %02Xh", smsg.replyto_net.type); + line = AddLineF(line, "Replyto net addr : %s", (char *)(smsg.replyto_net.type == NET_FIDO ? faddrtoa(*(fidoaddr_t *)smsg.replyto_net.addr) : smsg.replyto_net.addr)); + } + + line = AddLineF(line, "From agent : %02Xh", smsg.from_agent); + line = AddLineF(line, "To agent : %02Xh", smsg.to_agent); + line = AddLineF(line, "Replyto agent : %02Xh", smsg.replyto_agent); + + line = AddLine(line, ""); + AddLineF(line, "dfields:"); + line = AddLine(line, ""); + + for (i = 0; i < smsg.hdr.total_dfields; i++) { + line = AddLineF(line, "dfield[%02u].type : %02X", i, smsg.dfield[i].type); + line = AddLineF(line, "dfield[%02u].offset : %lu", i, smsg.dfield[i].offset); + line = AddLineF(line, "dfield[%02u].length : %lu", i, smsg.dfield[i].length); + } + + line = AddLine(line, ""); + AddLineF(line, "hfields:"); + line = AddLine(line, ""); + + for (i = 0; i < smsg.total_hfields; i++) { + line = AddLineF(line, "hfield[%02u].type : %02X", i, smsg.hfield[i].type); + line = AddLineF(line, "hfield[%02u].length : %d", i, smsg.hfield[i].length); + line = AddLineF(line, "hfield_dat[%02u] : %s", i, binstr((char *)smsg.hfield_dat[i], smsg.hfield[i].length)); + } + + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + int _count = 0; + char* _ptr = (char*)&smsg.hdr; + while(_count < sizeof(msghdr_t)) { + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, 16, HEX_DUMP2); + line = AddLine(line, buf); + _count += 16; + _ptr += 16; + } + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, sizeof(msghdr_t)%16, HEX_DUMP2); + line = AddLine(line, buf); + + ushort xlat; + char *inbuf; + long outlen; + bool lzh; + bool tail = true; + ulong l; + ulong txt_len = 1; + + msg->txt = throw_strdup(""); + + for(i = 0; i < smsg.hdr.total_dfields; i++) + switch(smsg.dfield[i].type) { + case TEXT_BODY: + if(tail) + tail = false; + goto common; + case TEXT_TAIL: + if(not tail) { + tail = true; + msg->txt[txt_len-1] = '\r'; + txt_len++; + } +common: + fseek(data->sdt_fp, smsg.hdr.offset + smsg.dfield[i].offset, SEEK_SET); + fread(&xlat, 2, 1, data->sdt_fp); + l = 2; + lzh = false; + while(xlat != XLAT_NONE) { + if(xlat == XLAT_LZH) + lzh = true; + fread(&xlat, 2, 1, data->sdt_fp); + l += 2; + } + if(lzh) { + inbuf = (char *)throw_xmalloc(smsg.dfield[i].length); + fread(inbuf, smsg.dfield[i].length - l, 1, data->sdt_fp); + outlen = *(long *)inbuf; + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + glzh_decode(inbuf, smsg.dfield[i].length - l, msg->txt+txt_len-1); + throw_xfree(inbuf); + } else { + outlen = smsg.dfield[i].length - l; + msg->txt = (char *)throw_realloc(msg->txt, txt_len+outlen); + fread(msg->txt+txt_len-1, smsg.dfield[i].length - l, 1, data->sdt_fp); + } + txt_len+=outlen; + msg->txt[txt_len-1] = NUL; + break; + } + + smb_freemsgmem(smsg); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmosmb2.cpp b/goldlib/gmb3/gmosmb2.cpp new file mode 100644 index 0000000..10de2fd --- /dev/null +++ b/goldlib/gmb3/gmosmb2.cpp @@ -0,0 +1,140 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Synchronet message base +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void SMBArea::raw_scan(bool keep_index, bool scanpm) +{ + GFTRK("SMBArea::raw_scan"); + + SMBData* _was_data = data; + if(_was_data == NULL) + data_open(); + ulong firstmsgno = 0; + ulong lastmsgno = 0; + Msgn->Reset(); + PMrk->Reset(); + if(isopen or smb_open(10) == 0) { + if(smb_locksmbhdr(10) == 0) { + smbstatus_t status; + int res = smb_getstatus(&status); + smb_unlocksmbhdr(); + ulong total_msgs = 0; + if(res == 0) { + total_msgs = status.total_msgs; + lastmsgno = status.last_msg; + if(keep_index or scanpm) { + smbmsg_t msg; + int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; + ulong l = 1; + rewind(data->sid_fp); + while(l <= total_msgs) { + if(not fread(&msg.idx, 1, sizeof(idxrec_t), data->sid_fp)) + break; + if(smb_lockmsghdr(msg, 10) == 0) { + int rc = smb_getmsghdr(&msg); + smb_unlockmsghdr(msg); + if(rc == 0) { + if(firstmsgno == 0) + firstmsgno = msg.hdr.number; + if(keep_index) + Msgn->Append(msg.hdr.number); + if(scanpm) { + bool gotpm = false; + for(int u=0; uAppend(msg.hdr.number); + gotpm = false; + } + } + smb_freemsgmem(msg); + } + } + l++; + } + total_msgs = l-1; + } + } + if(not isopen) + smb_close(); + Msgn->SetCount(total_msgs); + } + } + if(WideDebug) { + WideLog->printf("- %s: t:%u, l:%u, fm:%lu, hm:%lu, lr:%u, u:%u, pm: %i", + echoid(), + Msgn->Count(), + 0, + firstmsgno, + lastmsgno, + 0, + 0, + scanpm ? (int)PMrk->Count() : -1 + ); + } + if(_was_data == NULL) + data_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SMBArea::scan() +{ + raw_scan(true); +} + + +// ------------------------------------------------------------------ + +void SMBArea::scan_area() +{ + raw_scan(); +} + + +// ------------------------------------------------------------------ + +void SMBArea::scan_area_pm() +{ + raw_scan(true, true); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmosmb3.cpp b/goldlib/gmb3/gmosmb3.cpp new file mode 100644 index 0000000..890edac --- /dev/null +++ b/goldlib/gmb3/gmosmb3.cpp @@ -0,0 +1,1042 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Based on freeware sources from Digital Dynamics +// ------------------------------------------------------------------ +// Synchronet message base +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ +// Open a message base +// If retry_time is 0, fast open method (no compatibility/validity check) +// Opens files for READing messages or updating message indices only + +int SMBArea::smb_open(int retry_time) +{ + int file; + smbhdr_t hdr; + + data->shd_fp = data->sdt_fp = data->sid_fp = NULL; + if ((data->shd_fp = fsopen(AddPath(path(), ".shd"), "rb+", WideSharemode)) == NULL) + return (2); + file = fileno(data->shd_fp); + if (retry_time && filelength(file) >= sizeof(smbhdr_t)) { + setvbuf(data->shd_fp, data->shd_buf, _IONBF, SHD_BLOCK_LEN); + if (smb_locksmbhdr(retry_time)) { + smb_close(); + return (-1); + } + memset(&hdr, 0, sizeof(smbhdr_t)); + fread(&hdr, sizeof(smbhdr_t), 1, data->shd_fp); + if (memcmp(hdr.id, "SMB\x1a", 4)) { + smb_close(); + return (-2); + } + if (hdr.version < 0x110) { // Compatibility check + smb_close(); + return (-3); + } + smb_unlocksmbhdr(); + rewind(data->shd_fp); + } + if ((data->sdt_fp = fsopen(AddPath(path(), ".sdt"), "rb+", WideSharemode)) == NULL) { + smb_close(); + return (1); + } + if ((data->sid_fp = fsopen(AddPath(path(), ".sid"), "rb+", WideSharemode)) == NULL) { + smb_close(); + return (3); + } + return (0); +} + + +// ------------------------------------------------------------------ +// Closes the currently open message base + +void SMBArea::smb_close(void) +{ + if (data->shd_fp != NULL) { + // In case it's been locked + smb_unlocksmbhdr(); + fclose(data->shd_fp); + } + if (data->sid_fp != NULL) + fclose(data->sid_fp); + if (data->sdt_fp != NULL) + fclose(data->sdt_fp); + data->sid_fp = data->shd_fp = data->sdt_fp = NULL; +} + + +// ------------------------------------------------------------------ +// Opens the data block allocation table message base 'smb_file' +// Retrys for retry_time number of seconds +// Return 0 on success, non-zero otherwise + +int SMBArea::smb_open_da(int retry_time) +{ + data->sda_fp = smb_openexlusively(AddPath(path(), ".sda"), retry_time); + return data->sda_fp == NULL ? 1 : 0; +} + + +// ------------------------------------------------------------------ +// Opens the header block allocation table for message base 'smb_file' +// Retrys for retry_time number of seconds +// Return 0 on success, non-zero otherwise + +int SMBArea::smb_open_ha(int retry_time) +{ + data->sha_fp = smb_openexlusively(AddPath(path(), ".sha"), retry_time); + return data->sha_fp == NULL ? 1 : 0; +} + + +// ------------------------------------------------------------------ +// Truncates header file +// Retrys for retry_time number of seconds +// Return 0 on success, non-zero otherwise + +int SMBArea::smb_trunchdr(int retry_time) +{ + long start; + + start = time(NULL); + rewind(data->shd_fp); + while (1) { + if (not chsize(fileno(data->shd_fp), 0L)) + break; + if (errno != EACCES) + return (-1); + if (time(NULL) - start >= retry_time) // Time-out + return (-2); + } + return (0); +} + + +// ------------------------------------------------------------------ +// Message Base Header Functions + +// ------------------------------------------------------------------ +// Attempts for retry_time number of seconds to lock the message base hdr + +int SMBArea::smb_locksmbhdr(int retry_time) +{ + dword start; + + if(WideCanLock) { + start = time(NULL); + while (1) { + if (not ::lock(fileno(data->shd_fp), 0L, sizeof(smbhdr_t) + sizeof(smbstatus_t))) + return (0); + if (time(NULL) - start >= retry_time) + break; // Incase we've already locked it + ::unlock(fileno(data->shd_fp), 0L, sizeof(smbhdr_t) + sizeof(smbstatus_t)); + } + return (-1); + } + return (0); +} + + +// ------------------------------------------------------------------ +// Read the SMB header from the header file and place into "status" + +int SMBArea::smb_getstatus(smbstatus_t *status) +{ + int i; + + clearerr(data->shd_fp); + fseek(data->shd_fp, sizeof(smbhdr_t), SEEK_SET); + i = fread(status, 1, sizeof(smbstatus_t), data->shd_fp); + if (i == sizeof(smbstatus_t)) + return (0); + return (1); +} + + +// ------------------------------------------------------------------ +// Writes message base header + +int SMBArea::smb_putstatus(smbstatus_t status) +{ + int i; + + clearerr(data->shd_fp); + fseek(data->shd_fp, sizeof(smbhdr_t), SEEK_SET); + i = fwrite(&status, 1, sizeof(smbstatus_t), data->shd_fp); + fflush(data->shd_fp); + if (i == sizeof(smbstatus_t)) + return (0); + return (1); +} + + +// ------------------------------------------------------------------ +// Unlocks previously locks message base header + +int SMBArea::smb_unlocksmbhdr() +{ + if(not WideCanLock) return 0; + return (::unlock(fileno(data->shd_fp), 0L, sizeof(smbhdr_t) + sizeof(smbstatus_t))); +} + + +// ------------------------------------------------------------------ +// Individual Message Functions + +// ------------------------------------------------------------------ +// Attempts for retry_time number of seconds to lock the header for 'msg' + +int SMBArea::smb_lockmsghdr(smbmsg_t msg, int retry_time) +{ + dword start; + + if(WideCanLock) { + start = time(NULL); + while (1) { + if (not ::lock(fileno(data->shd_fp), msg.idx.offset, sizeof(msghdr_t))) + return (0); + if (time(NULL) - start >= retry_time) + break; + ::unlock(fileno(data->shd_fp), msg.idx.offset, sizeof(msghdr_t)); + } + return (-1); + } + return 0; +} + + +// ------------------------------------------------------------------ +// Fills msg->idx with message index based on msg->hdr.number +// OR if msg->hdr.number is 0, based on msg->offset (record offset). +// if msg.hdr.number does not equal 0, then msg->offset is filled too. +// Either msg->hdr.number or msg->offset must be initialized before +// calling this function +// Returns 1 if message number wasn't found, 0 if it was + +int SMBArea::smb_getmsgidx(smbmsg_t *msg) +{ + idxrec_t idx; + dword l, length, total, bot, top; + + clearerr(data->sid_fp); + if (not msg->hdr.number) { + fseek(data->sid_fp, msg->offset * sizeof(idxrec_t), SEEK_SET); + if (not fread(&msg->idx, sizeof(idxrec_t), 1, data->sid_fp)) + return (1); + return (0); + } + length = filelength(fileno(data->sid_fp)); + if (not length) + return (1); + total = length / sizeof(idxrec_t); + if (not total) + return (1); + + bot = 0; + top = total; + l = total / 2; // Start at middle index + while (1) { + fseek(data->sid_fp, l * sizeof(idxrec_t), SEEK_SET); + if (not fread(&idx, sizeof(idxrec_t), 1, data->sid_fp)) + return (1); + if (bot == top - 1 and idx.number != msg->hdr.number) + return (1); + if (idx.number > msg->hdr.number) { + top = l; + l = bot + ((top - bot) / 2); + continue; + } + if (idx.number < msg->hdr.number) { + bot = l; + l = top - ((top - bot) / 2); + continue; + } + break; + } + msg->idx = idx; + msg->offset = l; + return (0); +} + + +// ------------------------------------------------------------------ +// Reads the last index record in the open message base + +int SMBArea::smb_getlastidx(idxrec_t *idx) +{ + long length; + + clearerr(data->sid_fp); + length = filelength(fileno(data->sid_fp)); + if (length < sizeof(idxrec_t)) + return (-1); + fseek(data->sid_fp, length - sizeof(idxrec_t), SEEK_SET); + if (not fread(idx, sizeof(idxrec_t), 1, data->sid_fp)) + return (-2); + return (0); +} + + +// ------------------------------------------------------------------ +// Figures out the total length of the header record for 'msg' +// Returns length + +uint SMBArea::smb_getmsghdrlen(smbmsg_t msg) +{ + int i; + + // fixed portion + msg.hdr.length = sizeof(msghdr_t); + // data fields + msg.hdr.length += msg.hdr.total_dfields * sizeof(dfield_t); + // header fields + for (i = 0; i < msg.total_hfields; i++) { + msg.hdr.length += sizeof(hfield_t); + msg.hdr.length += msg.hfield[i].length; + } + return (msg.hdr.length); +} + + +// ------------------------------------------------------------------ +// Figures out the total length of the data buffer for 'msg' +// Returns length + +dword SMBArea::smb_getmsgdatlen(smbmsg_t msg) +{ + int i; + dword length = 0L; + + for (i = 0; i < msg.hdr.total_dfields; i++) + length += msg.dfield[i].length; + return (length); +} + + +// ------------------------------------------------------------------ +// Read header information into 'msg' structure +// msg->idx.offset must be set before calling this function +// Must call smb_freemsgmem() to free memory allocated for var len strs +// Returns 0 on success, non-zero if error + +int SMBArea::smb_getmsghdr(smbmsg_t *msg) +{ + word i; + dword l, offset; + idxrec_t idx; + + rewind(data->shd_fp); + fseek(data->shd_fp, msg->idx.offset, SEEK_SET); + idx = msg->idx; + offset = msg->offset; + memset(msg, 0, sizeof(smbmsg_t)); + msg->idx = idx; + msg->offset = offset; + if (not fread(&msg->hdr, sizeof(msghdr_t), 1, data->shd_fp)) + return (-1); + if (memcmp(msg->hdr.id, "SHD\x1a", 4)) + return (-2); + if (msg->hdr.version < 0x110) + return (-9); + l = sizeof(msghdr_t); + msg->dfield = (dfield_t *)throw_xmalloc(msg->hdr.total_dfields*sizeof(dfield_t)); + i = 0; + while (i < msg->hdr.total_dfields and l < msg->hdr.length) { + if (not fread(&msg->dfield[i], sizeof(dfield_t), 1, data->shd_fp)) { + smb_freemsgmem(*msg); + return (-4); + } + i++; + l += sizeof(dfield_t); + } + if (i < msg->hdr.total_dfields) { + smb_freemsgmem(*msg); + return (-8); + } + while (l < msg->hdr.length) { + i = msg->total_hfields++; + msg->hfield_dat = (void **)throw_xrealloc(msg->hfield_dat, msg->total_hfields*sizeof(void *)); + msg->hfield = (hfield_t *)throw_xrealloc(msg->hfield, msg->total_hfields*sizeof(hfield_t)); + if (not fread(&msg->hfield[i], sizeof(hfield_t), 1, data->shd_fp)) { + smb_freemsgmem(*msg); + return (-5); + } + l += sizeof(hfield_t); + msg->hfield_dat[i] = (char *)throw_xmalloc(msg->hfield[i].length + 1); + memset(msg->hfield_dat[i], 0, msg->hfield[i].length + 1); // init to NULL + if (msg->hfield[i].length and not fread(msg->hfield_dat[i], msg->hfield[i].length, 1, data->shd_fp)) { + smb_freemsgmem(*msg); + return (-6); + } + switch (msg->hfield[i].type) { // convenience variables + case SENDER: + if (not msg->from) { + msg->from = (uchar *)msg->hfield_dat[i]; + break; + } + case FORWARDED: // fall through + msg->forwarded = 1; + break; + case SENDERAGENT: + if (not msg->forwarded) + msg->from_agent = *(word *)msg->hfield_dat[i]; + break; + case SENDEREXT: + if (not msg->forwarded) + msg->from_ext = (uchar *)msg->hfield_dat[i]; + break; + case SENDERNETTYPE: + if (not msg->forwarded) + msg->from_net.type = *(word *)msg->hfield_dat[i]; + break; + case SENDERNETADDR: + if (not msg->forwarded) + msg->from_net.addr = (char *)msg->hfield_dat[i]; + break; + case REPLYTO: + msg->replyto = (uchar *)msg->hfield_dat[i]; + break; + case REPLYTOEXT: + msg->replyto_ext = (uchar *)msg->hfield_dat[i]; + break; + case REPLYTOAGENT: + msg->replyto_agent = *(word *)msg->hfield_dat[i]; + break; + case REPLYTONETTYPE: + msg->replyto_net.type = *(word *)msg->hfield_dat[i]; + break; + case REPLYTONETADDR: + msg->replyto_net.addr = (char *)msg->hfield_dat[i]; + break; + case RECIPIENT: + msg->to = (uchar *)msg->hfield_dat[i]; + break; + case RECIPIENTEXT: + msg->to_ext = (uchar *)msg->hfield_dat[i]; + break; + case RECIPIENTAGENT: + msg->to_agent = *(word *)msg->hfield_dat[i]; + break; + case RECIPIENTNETTYPE: + msg->to_net.type = *(word *)msg->hfield_dat[i]; + break; + case RECIPIENTNETADDR: + msg->to_net.addr = (char *)msg->hfield_dat[i]; + break; + case SUBJECT: + msg->subj = (uchar *)msg->hfield_dat[i]; + break; + } + l += msg->hfield[i].length; + } + + if (not msg->from or not msg->to or not msg->subj) { + smb_freemsgmem(*msg); + return (-7); + } + return (0); +} + + +// ------------------------------------------------------------------ +// Frees memory allocated for 'msg' + +void SMBArea::smb_freemsgmem(smbmsg_t msg) +{ + word i; + + throw_xfree(msg.dfield); + for (i = 0; i < msg.total_hfields; i++) + throw_xfree(msg.hfield_dat[i]); + throw_xfree(msg.hfield); + throw_xfree(msg.hfield_dat); +} + + +// ------------------------------------------------------------------ +// Unlocks header for 'msg' + +int SMBArea::smb_unlockmsghdr(smbmsg_t msg) +{ + if(not WideCanLock) return 0; + return (::unlock(fileno(data->shd_fp), msg.idx.offset, sizeof(msghdr_t))); +} + + +// ------------------------------------------------------------------ +// Adds a header field to the 'msg' structure (in memory only) + +int SMBArea::smb_hfield(smbmsg_t * msg, word type, word length, void *data) +{ + int i; + + i = msg->total_hfields; + msg->hfield = (hfield_t *)throw_xrealloc(msg->hfield, (i+1)*sizeof(hfield_t)); + msg->hfield_dat = (void **)throw_xrealloc(msg->hfield_dat, (i+1)*sizeof(void *)); + msg->total_hfields++; + msg->hfield[i].type = type; + msg->hfield[i].length = length; + if (length) { + msg->hfield_dat[i] = (void *)throw_xmalloc(length); + memcpy(msg->hfield_dat[i], data, length); + } else + msg->hfield_dat[i] = NULL; + return (0); +} + + +// ------------------------------------------------------------------ +// Adds a data field to the 'msg' structure (in memory only) +// Automatically figures out the offset into the data buffer from existing +// dfield lengths + +int SMBArea::smb_dfield(smbmsg_t * msg, word type, dword length) +{ + int i, j; + + i = msg->hdr.total_dfields; + msg->dfield = (dfield_t *)throw_xrealloc(msg->dfield, (i+1)*sizeof(dfield_t)); + msg->hdr.total_dfields++; + msg->dfield[i].type = type; + msg->dfield[i].length = length; + for (j = msg->dfield[i].offset = 0; j < i; j++) + msg->dfield[i].offset += msg->dfield[j].length; + return (0); +} + + +// ------------------------------------------------------------------ +// Checks CRC history file for duplicate crc. If found, returns 1. +// If no dupe, adds to CRC history and returns 0, or negative if error. + +int SMBArea::smb_addcrc(dword max_crcs, dword crc, int retry_time) +{ + int file; + long length; + dword l, *buf; + + if (not max_crcs) + return (0); + file = smb_openexlusively2(AddPath(path(), ".sch"), retry_time); + length = filelength(file); + if (length < 0L) { + ::close(file); + return (-4); + } + buf = (dword *)throw_xmalloc(max_crcs * sizeof(dword)); + if (length >= max_crcs * 4) { // Reached or exceeds max crcs + read(file, buf, max_crcs * 4); + for (l = 0; l < max_crcs; l++) + if (crc == buf[l]) + break; + if (l < max_crcs) { // Dupe CRC found + ::close(file); + throw_xfree(buf); + return (1); + } + chsize(file, 0L); // truncate it + lseek(file, 0L, SEEK_SET); + write(file, buf + 4, (max_crcs - 1) * 4); + } else if (length / 4) { // Less than max crcs + read(file, buf, length); + for (l = 0; l < length / 4; l++) + if (crc == buf[l]) + break; + if (l < length / 4) { // Dupe CRC found + ::close(file); + throw_xfree(buf); + return (1); + } + } + lseek(file, 0L, SEEK_END); + write(file, &crc, 4); // Write to the end + throw_xfree(buf); + ::close(file); + return (0); +} + + +// ------------------------------------------------------------------ +// Creates a new message header record in the header file. +// If storage is SMB_SELFPACK, self-packing conservative allocation is used +// If storage is SMB_FASTALLOC, fast allocation is used +// If storage is SMB_HYPERALLOC, no allocation tables are used (fastest) + +int SMBArea::smb_addmsghdr(smbmsg_t * msg, smbstatus_t * status, int storage, int retry_time) +{ + int i; + long l; + + if (smb_locksmbhdr(retry_time)) + return (1); + if (smb_getstatus(status)) + return (2); + + if (storage != SMB_HYPERALLOC and (i = smb_open_ha(retry_time)) != 0) + return (i); + + msg->hdr.length = smb_getmsghdrlen(*msg); + if (storage == SMB_HYPERALLOC) + l = smb_hallochdr(status->header_offset); + else if (storage == SMB_FASTALLOC) + l = smb_fallochdr(msg->hdr.length); + else + l = smb_allochdr(msg->hdr.length); + if (l == -1L) { + smb_unlocksmbhdr(); + fclose(data->sha_fp); + return (-1); + } + status->last_msg++; + msg->idx.number = msg->hdr.number = status->last_msg; + msg->idx.offset = status->header_offset + l; + msg->idx.time = msg->hdr.when_imported.time; + msg->idx.attr = msg->hdr.attr; + msg->offset = status->total_msgs; + status->total_msgs++; + smb_putstatus(*status); + + if (storage != SMB_HYPERALLOC) + fclose(data->sha_fp); + i = smb_putmsg(*msg); + smb_unlocksmbhdr(); + return (i); +} + + +// ------------------------------------------------------------------ +// Writes both header and index information for msg 'msg' + +int SMBArea::smb_putmsg(smbmsg_t msg) +{ + int i; + + i = smb_putmsghdr(msg); + if (i) + return (i); + return (smb_putmsgidx(msg)); +} + + +// ------------------------------------------------------------------ +// Writes index information for 'msg' +// msg.idx and msg.offset must be set prior to calling to this function +// Returns 0 if everything ok + +int SMBArea::smb_putmsgidx(smbmsg_t msg) +{ + clearerr(data->sid_fp); + fseek(data->sid_fp, msg.offset * sizeof(idxrec_t), SEEK_SET); + if (not fwrite(&msg.idx, sizeof(idxrec_t), 1, data->sid_fp)) + return (1); + fflush(data->sid_fp); + return (0); +} + + +// ------------------------------------------------------------------ +// Writes header information for 'msg' +// msg.hdr.length +// msg.idx.offset +// and msg.offset must be set prior to calling to this function +// Returns 0 if everything ok + +int SMBArea::smb_putmsghdr(smbmsg_t msg) +{ + word i; + dword l; + + clearerr(data->shd_fp); + if (fseek(data->shd_fp, msg.idx.offset, SEEK_SET)) + return (-1); + + // Write the fixed portion of the header record + if (not fwrite(&msg.hdr, sizeof(msghdr_t), 1, data->shd_fp)) + return (-2); + + // Write the data fields (each is fixed length) + for (i = 0; i < msg.hdr.total_dfields; i++) + if (not fwrite(&msg.dfield[i], sizeof(dfield_t), 1, data->shd_fp)) + return (-3); + + // Write the variable length header fields + for (i = 0; i < msg.total_hfields; i++) { + if (not fwrite(&msg.hfield[i], sizeof(hfield_t), 1, data->shd_fp)) + return (-4); + if (msg.hfield[i].length and not fwrite(msg.hfield_dat[i], msg.hfield[i].length, 1, data->shd_fp)) + return (-5); + } + + l = smb_getmsghdrlen(msg); + while (l % SHD_BLOCK_LEN) { + if (fputc(0, data->shd_fp) == EOF) // pad block with NULL + return (-6); + l++; + } + fflush(data->shd_fp); + return (0); +} + + +// ------------------------------------------------------------------ +// Creates a sub-board's initial header file +// Truncates and deletes other associated SMB files + +int SMBArea::smb_create(dword max_crcs, dword max_msgs, word max_age, word attr, int retry_time) +{ + smbhdr_t hdr; + smbstatus_t status; + + if (filelength(fileno(data->shd_fp)) >= sizeof(smbhdr_t) + sizeof(smbstatus_t) + and smb_locksmbhdr(retry_time)) // header exists, so lock it + return (1); + memset(&hdr, 0, sizeof(smbhdr_t)); + memset(&status, 0, sizeof(smbstatus_t)); + memcpy(hdr.id, "SMB\x1a", 4); + hdr.version = SMB_VERSION; + hdr.length = sizeof(smbhdr_t) + sizeof(smbstatus_t); + status.last_msg = status.total_msgs = 0; + status.header_offset = sizeof(smbhdr_t) + sizeof(smbstatus_t); + status.max_crcs = max_crcs; + status.max_msgs = max_msgs; + status.max_age = max_age; + status.attr = attr; + rewind(data->shd_fp); + fwrite(&hdr, 1, sizeof(smbhdr_t), data->shd_fp); + fwrite(&status, 1, sizeof(smbstatus_t), data->shd_fp); + rewind(data->shd_fp); + chsize(fileno(data->shd_fp), sizeof(smbhdr_t) + sizeof(smbstatus_t)); + fflush(data->shd_fp); + + rewind(data->sdt_fp); + chsize(fileno(data->sdt_fp), 0L); + rewind(data->sid_fp); + chsize(fileno(data->sid_fp), 0L); + + remove(AddPath(path(), ".sda")); // if it exists, delete it + remove(AddPath(path(), ".sha")); // if it exists, delete it + remove(AddPath(path(), ".sch")); + smb_unlocksmbhdr(); + return (0); +} + + +// ------------------------------------------------------------------ +// Returns number of data blocks required to store "length" amount of data + +dword SMBArea::smb_datblocks(dword length) +{ + dword blocks; + + blocks = length / SDT_BLOCK_LEN; + if (length % SDT_BLOCK_LEN) + blocks++; + return (blocks); +} + + +// ------------------------------------------------------------------ +// Returns number of header blocks required to store "length" size header + +dword SMBArea::smb_hdrblocks(dword length) +{ + dword blocks; + + blocks = length / SHD_BLOCK_LEN; + if (length % SHD_BLOCK_LEN) + blocks++; + return (blocks); +} + + +// ------------------------------------------------------------------ +// Finds unused space in data file based on block allocation table and +// marks space as used in allocation table. +// File must be opened read/write DENY ALL +// Returns offset to beginning of data (in bytes, not blocks) +// Assumes smb_open_da() has been called +// fclose(data->sda_fp) should be called after +// Returns negative on error + +long SMBArea::smb_allocdat(dword length, word headers) +{ + word i, j; + dword l, blocks, offset = 0L; + + blocks = smb_datblocks(length); + j = 0; // j is consecutive unused block counter + fflush(data->sda_fp); + rewind(data->sda_fp); + while (not feof(data->sda_fp)) { + if (not fread(&i, 2, 1, data->sda_fp)) + break; + offset += SDT_BLOCK_LEN; + if (not i) + j++; + else + j = 0; + if (j == blocks) { + offset -= (blocks * SDT_BLOCK_LEN); + break; + } + } + clearerr(data->sda_fp); + fseek(data->sda_fp, (offset / SDT_BLOCK_LEN) * 2L, SEEK_SET); + for (l = 0; l < blocks; l++) + if (not fwrite(&headers, 2, 1, data->sda_fp)) + return (-1); + fflush(data->sda_fp); + return (offset); +} + + +// ------------------------------------------------------------------ +// Allocates space for data, but doesn't search for unused blocks +// Returns negative on error + +long SMBArea::smb_fallocdat(dword length, word headers) +{ + dword l, blocks, offset; + + fflush(data->sda_fp); + clearerr(data->sda_fp); + blocks = smb_datblocks(length); + fseek(data->sda_fp, 0L, SEEK_END); + offset = (ftell(data->sda_fp) / 2L) * SDT_BLOCK_LEN; + for (l = 0; l < blocks; l++) + if (not fwrite(&headers, 2, 1, data->sda_fp)) + break; + fflush(data->sda_fp); + if (l < blocks) + return (-1L); + return (offset); +} + + +// ------------------------------------------------------------------ +// De-allocates space for data +// Returns non-zero on error + +int SMBArea::smb_freemsgdat(dword offset, dword length, word headers) +{ + word i; + dword l, blocks; + + blocks = smb_datblocks(length); + + clearerr(data->sda_fp); + for (l = 0; l < blocks; l++) { + if (fseek(data->sda_fp, ((offset / SDT_BLOCK_LEN) + l) * 2L, SEEK_SET)) + return (1); + if (not fread(&i, 2, 1, data->sda_fp)) + return (2); + if (headers > i) + i = 0; // don't want to go negative + else + i -= headers; + if (fseek(data->sda_fp, -2L, SEEK_CUR)) + return (3); + if (not fwrite(&i, 2, 1, data->sda_fp)) + return (4); + } + fflush(data->sda_fp); + return (0); +} + + +// ------------------------------------------------------------------ +// Adds to data allocation records for blocks starting at 'offset' +// Returns non-zero on error + +int SMBArea::smb_incdat(dword offset, dword length, word headers) +{ + word i; + dword l, blocks; + + clearerr(data->sda_fp); + blocks = smb_datblocks(length); + for (l = 0; l < blocks; l++) { + fseek(data->sda_fp, ((offset / SDT_BLOCK_LEN) + l) * 2L, SEEK_SET); + if (not fread(&i, 2, 1, data->sda_fp)) + return (1); + i += headers; + fseek(data->sda_fp, -2L, SEEK_CUR); + if (not fwrite(&i, 2, 1, data->sda_fp)) + return (2); + } + fflush(data->sda_fp); + return (0); +} + + +// ------------------------------------------------------------------ +// De-allocates blocks for header record +// Returns non-zero on error + +int SMBArea::smb_freemsghdr(dword offset, dword length) +{ + uchar c = 0; + dword l, blocks; + + clearerr(data->sha_fp); + blocks = smb_hdrblocks(length); + fseek(data->sha_fp, offset / SHD_BLOCK_LEN, SEEK_SET); + for (l = 0; l < blocks; l++) + if (not fwrite(&c, 1, 1, data->sha_fp)) + return (1); + fflush(data->sha_fp); + return (0); +} + + +// ------------------------------------------------------------------ +// Frees all allocated header and data blocks for 'msg' + +int SMBArea::smb_freemsg(smbmsg_t msg, smbstatus_t status) +{ + int i; + word x; + + if (status.attr & SMB_HYPERALLOC) + return (0); // Nothing to do + + for (x = 0; x < msg.hdr.total_dfields; x++) { + if ((i = smb_freemsgdat(msg.hdr.offset + msg.dfield[x].offset, msg.dfield[x].length, 1)) != 0) + return (i); + } + return (smb_freemsghdr(msg.idx.offset - status.header_offset, msg.hdr.length)); +} + + +// ------------------------------------------------------------------ +// Finds unused space in header file based on block allocation table and +// marks space as used in allocation table. +// File must be opened read/write DENY ALL +// Returns offset to beginning of header (in bytes, not blocks) +// Assumes smb_open_ha() has been called +// fclose(data->sha_fp) should be called after +// Returns -1L on error + +long SMBArea::smb_allochdr(dword length) +{ + uchar c; + word i; + dword l, blocks, offset = 0; + + blocks = smb_hdrblocks(length); + i = 0; // i is consecutive unused block counter + fflush(data->sha_fp); + rewind(data->sha_fp); + while (not feof(data->sha_fp)) { + if (not fread(&c, 1, 1, data->sha_fp)) + break; + offset += SHD_BLOCK_LEN; + if (not c) + i++; + else + i = 0; + if (i == blocks) { + offset -= (blocks * SHD_BLOCK_LEN); + break; + } + } + clearerr(data->sha_fp); + fseek(data->sha_fp, offset / SHD_BLOCK_LEN, SEEK_SET); + c = 1; + for (l = 0; l < blocks; l++) + if (not fwrite(&c, 1, 1, data->sha_fp)) + return (-1L); + fflush(data->sha_fp); + return (offset); +} + + +// ------------------------------------------------------------------ +// Allocates space for index, but doesn't search for unused blocks +// Returns -1L on error + +long SMBArea::smb_fallochdr(dword length) +{ + uchar c = 1; + dword l, blocks, offset; + + blocks = smb_hdrblocks(length); + fflush(data->sha_fp); + clearerr(data->sha_fp); + fseek(data->sha_fp, 0L, SEEK_END); + offset = ftell(data->sha_fp) * SHD_BLOCK_LEN; + for (l = 0; l < blocks; l++) + if (not fwrite(&c, 1, 1, data->sha_fp)) + return (-1L); + fflush(data->sha_fp); + return (offset); +} + + +// ------------------------------------------------------------------ +// Allocate header blocks using Hyper Allocation +// this function should be most likely not be called from anywhere but +// smb_addmsghdr() + +long SMBArea::smb_hallochdr(dword header_offset) +{ + long l; + + fflush(data->shd_fp); + fseek(data->shd_fp, 0L, SEEK_END); + l = ftell(data->shd_fp); + if (l < header_offset) // Header file truncated?!? + return (header_offset); + while ((l - header_offset) % SHD_BLOCK_LEN) // Make sure even block boundry + l++; + return (l - header_offset); +} + + +// ------------------------------------------------------------------ +// Allocate data blocks using Hyper Allocation +// smb_locksmbhdr() should be called before this function and not +// unlocked until all data fields for this message have been written +// to the SDT file + +long SMBArea::smb_hallocdat() +{ + long l; + + fflush(data->sdt_fp); + fseek(data->sdt_fp, 0L, SEEK_END); + l = ftell(data->sdt_fp); + if (l <= 0) + return (l); + while (l % SDT_BLOCK_LEN) // Make sure even block boundry + l++; + return (l); +} diff --git a/goldlib/gmb3/gmosqsh.h b/goldlib/gmb3/gmosqsh.h new file mode 100644 index 0000000..5b892dd --- /dev/null +++ b/goldlib/gmb3/gmosqsh.h @@ -0,0 +1,354 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Squish msgbase. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GMSQSH_H +#define __GMSQSH_H + + +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ + +#ifdef GOLD_16BIT +const long MAX_IDXBUFSIZE = 65300L; +#else +const long MAX_IDXBUFSIZE = LONG_MAX; +#endif + + +// ------------------------------------------------------------------ + +#define MSGAREA_NORMAL 0x00 +#define MSGAREA_CREATE 0x01 +#define MSGAREA_CRIFNEC 0x02 + + +// ------------------------------------------------------------------ + +#define MSGTYPE_SDM 0x01 +#define MSGTYPE_SQUISH 0x02 +#define MSGTYPE_ECHO 0x80 + + +// ------------------------------------------------------------------ + +#define MSGNUM_CUR ((dword)-1L) +#define MSGNUM_PREV ((dword)-2L) +#define MSGNUM_NEXT ((dword)-3L) + + +// ------------------------------------------------------------------ + +#define MOPEN_CREATE 0 +#define MOPEN_READ 1 +#define MOPEN_WRITE 2 +#define MOPEN_RW 3 + + +// ------------------------------------------------------------------ + +#define SQEXTRA_BUF 16 + + +// ------------------------------------------------------------------ +// Constants for 'type' argument of SquishUidToMsgn() + +const int UID_EXACT = 0; +const int UID_NEXT = 1; +const int UID_PREV = 2; + + +// ------------------------------------------------------------------ +// Values for msgapierr + +#define MERR_NONE 0 // No error +#define MERR_BADH 1 // Invalid handle passed to function +#define MERR_BADF 2 // Invalid or corrupted file +#define MERR_NOMEM 3 // Not enough memory for specified operation +#define MERR_NODS 4 // Maybe not enough disk space for operation +#define MERR_NOENT 5 // File/message does not exist +#define MERR_BADA 6 // Bad argument passed to msgapi function +#define MERR_EOPEN 7 // Couldn't close - messages still open +#define MERR_ACCESS 10 // Access denied - msgbase locked? + + +// ------------------------------------------------------------------ +// Bitmasks for 'attr' + +#define MSGPRIVATE 0x0001 +#define MSGCRASH 0x0002 +#define MSGREAD 0x0004 +#define MSGSENT 0x0008 +#define MSGFILE 0x0010 +#define MSGFWD 0x0020 +#define MSGORPHAN 0x0040 +#define MSGKILL 0x0080 +#define MSGLOCAL 0x0100 +#define MSGHOLD 0x0200 +#define MSGXX2 0x0400 +#define MSGFRQ 0x0800 +#define MSGRRQ 0x1000 +#define MSGCPT 0x2000 +#define MSGARQ 0x4000 +#define MSGURQ 0x8000 +#define MSGSCANNED 0x00010000L +#define MSGUID 0x00020000L +#define MSGPRINTED 0x00040000L +#define MSGSEEN 0x00080000L +#define MSGLOK 0x40000000L + + +// ------------------------------------------------------------------ +// Max number of stored replies to one msg + +#define MAX_REPLY 9 + + +// ------------------------------------------------------------------ +// Structure of message headers in .SQD + +struct SqshHdr { + dword attr; + char from[36]; + char to[36]; + char subj[72]; + Addr orig; + Addr dest; + FTime date_written; // When user wrote the msg (UTC) + FTime date_arrived; // When msg arrived on-line (UTC) + short utc_offset; // Offset from UTC of message writer, in minutes. + dword replyto; + dword replies[MAX_REPLY]; + dword umsgid; + char ftsc_date[20]; +}; + + +// ------------------------------------------------------------------ +// Squish frames + +const dword SQFRAMEID = 0xAFAE4453L; +const dword SQFRAME_NULL = 0; +const word SQFRAME_NORMAL = 0; +const word SQFRAME_FREE = 1; + + +// ------------------------------------------------------------------ +// Structure of message frames in .SQD + +struct SqshFrm { + dword id; // Must always equal SQFRAMEID + long next; // Offset of next frame + long prev; // Offset of previous frame + dword length; // Length of this frame + dword totsize; // Length of data in frame (hdr+ctl+txt) + dword ctlsize; // Length of control info + word type; // Frm type (normal or free) + word reserved; // Reserved +}; + + +// ------------------------------------------------------------------ +// Structure of index file .SQI + +struct SqshIdx { + long offset; // Offset of frame in .SQD + dword msgno; // Message number + dword hash; // Hash value of TO: name +}; + + +// ------------------------------------------------------------------ +// Structure of base record in .SQD + +struct SqshBase { + word size; // sizeof(SqshBaseT) + word reserved1; // reserved + dword totalmsgs; // Number of messages in area + dword highestmsg; // Highest msg in area. Same as totalmsgs + dword protmsgs; // Skip killing first x msgs in area + dword highwatermark; // Relno (not Tagno) of HWM + dword nextmsgno; // Next message number to use + char name[80]; // Base name of SquishFile + dword firstframe; // Offset of first frame in file + dword lastframe; // Offset to last frame in file + dword firstfreeframe; // Offset of first FREE frame in file + dword lastfreeframe; // Offset of last free frame in file + dword endframe; // Pointer to end of file + dword maxmsgs; // Max # of msgs to keep in area + word daystokeep; // Max age of msgs in area (for packing util) + word framesize; // sizeof(SqshFrmT) + byte reserved2[124]; // Reserved by Squish for future use +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct SqshData { + int fhsqd; + int fhsqi; + SqshBase base; + SqshIdx* idx; + int softlock; + int islocked; +}; + + +// ------------------------------------------------------------------ + +struct SqshWide { + int userno; + MaximusUser* user; + const char* userpath; + int direct; + int recycle; + int squishscan; +}; + + +// ------------------------------------------------------------------ + +class SquishArea : public gmo_area { + +protected: + + SqshWide* wide; + SqshData* data; + + void data_open(); + void data_close(); + + int test_open(const char* __file); + void save_lastread(); + void raw_scan(int __keep_index, int __scanpm=false); + void raw_open(); + void raw_close(); + void refresh(); + int load_message(int __mode, gmsg* __msg, SqshHdr& __hdr); + + void read_frm(dword __offset, SqshFrm* __frm); + void write_frm(dword __offset, SqshFrm* __frm); + void upd_frm_next(dword __offset, SqshFrm* __frm, dword __next); + void upd_frm_prev(dword __offset, SqshFrm* __frm, dword __prev); + void add_to_free_chain(dword __delframe, SqshFrm* __delfrm); + void delete_msg(uint __reln); + void init_frm(SqshFrm* __frm); + void excess_frm(dword __lastframe, dword __newframe, SqshFrm* __newfrm, dword __totsize); + uint find_msgn(ulong __tagn); + void save_message(int __mode, gmsg* __msg); + +public: + + SquishArea() { wide = NULL; data = NULL; } + virtual ~SquishArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern SqshData* squishdata; +extern SqshWide* squishwide; +extern int squishdatano; + + +// ------------------------------------------------------------------ +// Squish scanning types + +const int SQS_API = 1; +const int SQS_QUICK = 2; + + +// ------------------------------------------------------------------ +// Squish recycling types + +const int SQUISHRECYCLE_NO = false; +const int SQUISHRECYCLE_YES = true; +const int SQUISHRECYCLE_MSGAPI1 = SQUISHRECYCLE_YES + 1; +const int SQUISHRECYCLE_MSGAPI2 = SQUISHRECYCLE_YES + 2; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmosqsh1.cpp b/goldlib/gmb3/gmosqsh1.cpp new file mode 100644 index 0000000..a645633 --- /dev/null +++ b/goldlib/gmb3/gmosqsh1.cpp @@ -0,0 +1,272 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Squish msgbase handling and Maximus user functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +SqshData* squishdata = NULL; +SqshWide* squishwide = NULL; +int squishdatano = 0; + + +// ------------------------------------------------------------------ + +void SquishArea::data_open() { + + wide = squishwide; + data = squishdata + (squishdatano++); + data->islocked = false; + data->softlock = false; + data->fhsqd = data->fhsqi = -1; + data->idx = NULL; +} + + +// ------------------------------------------------------------------ + +void SquishArea::data_close() { + + squishdatano--; +} + + +// ------------------------------------------------------------------ + +void SquishExit() { + + if(squishwide) + delete squishwide->user; + throw_release(squishwide); + throw_release(squishdata); +} + + +// ------------------------------------------------------------------ + +void SquishInit(const char* userpath, int userno, int direct, int recycle, int squishscan) { + + squishdata = (SqshData*)throw_calloc(2, sizeof(SqshData)); + squishwide = (SqshWide*)throw_calloc(1, sizeof(SqshWide)); + + squishwide->userpath = userpath; + squishwide->userno = userno; + squishwide->direct = direct; + squishwide->recycle = recycle; + squishwide->squishscan = squishscan; + + squishwide->user = new MaximusUser; + throw_new(squishwide->user); + + Path userfile; + strxcpy(userfile, userpath, sizeof(Path)); + AddPath(userfile, "USER.BBS"); + const char* _username = WideUsername[0]; + if(squishwide->userno == -1) { + squishwide->user->fh = ::sopen(userfile, O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(squishwide->user->fh != -1) { + squishwide->user->find(_username); + if(NOT squishwide->user->found) { + WideLog->printf("* User \"%s\" not found in %s.", _username, userfile); + squishwide->user->add(_username); + WideLog->printf("* Now added with user number %u.", squishwide->user->index); + } + close(squishwide->user->fh); + } + squishwide->userno = squishwide->user->index; + } +} + + +// ------------------------------------------------------------------ + +void SquishArea::raw_close() { + + GFTRK("SquishRawClose"); + + if(data->fhsqi != -1) ::close(data->fhsqi); data->fhsqi = -1; + if(data->fhsqd != -1) ::close(data->fhsqd); data->fhsqd = -1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +int SquishArea::test_open(const char* __file) { + + GFTRK("SquishTestOpen"); + + int _fh; + long _tries = 0; + + do { + + _fh = ::sopen(__file, O_RDWR|O_BINARY|O_CREAT, WideSharemode, S_STDRW); + if(_fh == -1) { + + // Tell the world + if(PopupLocked(++_tries, false, __file) == false) { + + // User requested to exit + WideLog->ErrOpen(); + raw_close(); + WideLog->printf("! A Squish msgbase file could not be opened."); + WideLog->printf(": %s.", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void SquishArea::raw_open() { + + GFTRK("SquishRawOpen"); + + data->fhsqd = test_open(AddPath(path(), ".sqd")); + data->fhsqi = test_open(AddPath(path(), ".sqi")); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ +// Open the Squish message base + +void SquishArea::open() { + + GFTRK("SquishOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a Squish msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + raw_open(); + refresh(); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::save_lastread() { + + GFTRK("SquishSaveLastread"); + + int _fh = ::sopen(AddPath(path(), ".sql"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(_fh != -1) { + lseekset(_fh, wide->userno, sizeof(dword)); + dword _lastread = Msgn->CvtReln(lastread); + write(_fh, &_lastread, sizeof(dword)); + ::close(_fh); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::close() { + + GFTRK("SquishClose"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + raw_close(); + Msgn->Reset(); + throw_xrelease(data->idx); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed Squish msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::suspend() { + + GFTRK("SquishSuspend"); + + save_lastread(); + raw_close(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::resume() { + + GFTRK("SquishResume"); + + raw_open(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmosqsh2.cpp b/goldlib/gmb3/gmosqsh2.cpp new file mode 100644 index 0000000..7fe6563 --- /dev/null +++ b/goldlib/gmb3/gmosqsh2.cpp @@ -0,0 +1,286 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Squish msgbase handling and Maximus user functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void SquishArea::refresh() { + + GFTRK("SquishRefresh"); + + // Create new base record or read the existing one + if(data->fhsqd != -1) { + if(filelength(data->fhsqd) < sizeof(SqshBase)) { + SqshBase& _base = data->base; + memset(&_base, 0, sizeof(SqshBase)); + _base.size = sizeof(SqshBase); + strxcpy(_base.name, path(), sizeof(_base.name)); + _base.endframe = _base.size; + _base.framesize = sizeof(SqshFrm); + _base.nextmsgno = 2; + lseekset(data->fhsqd, 0); + write(data->fhsqd, &data->base, sizeof(SqshBase)); + } + else { + lseekset(data->fhsqd, 0); + read(data->fhsqd, &data->base, sizeof(SqshBase)); + } + } + + // Are there any msgs? + if(data->base.totalmsgs) { + + // Read the index file + data->idx = (SqshIdx*)throw_realloc(data->idx, (uint)(data->base.totalmsgs*sizeof(SqshIdx))); + lseekset(data->fhsqi, 0); + read(data->fhsqi, data->idx, (uint)(data->base.totalmsgs*sizeof(SqshIdx))); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::raw_scan(int __keep_index, int __scanpm) { + + GFTRK("SquishRawScan"); + + SqshData* _was_data = data; + if(_was_data == NULL) { + data = squishdata; + wide = squishwide; + } + + // Load the lastread + dword _lastread = 0; + int _fh = ::sopen(AddPath(path(), ".sql"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(_fh != -1) { + lseekset(_fh, wide->userno, sizeof(dword)); + read(_fh, &_lastread, sizeof(dword)); + ::close(_fh); + } + + // Open Squish files for scanning unless they are already open + if(NOT isopen) { + + data->idx = NULL; + data->base.totalmsgs = 0; + + // Open index file + data->fhsqi = ::sopen(AddPath(path(), ".sqi"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(data->fhsqi != -1) { + + // Get the number of index records + data->base.totalmsgs = filelength(data->fhsqi) / sizeof(SqshIdx); + + // If there appear to be only one record, experience shows that + // there may in fact be zero! So check the *.SQD base record for + // the exact number of msgs in this case or if requested. + if((data->base.totalmsgs == 1) OR (wide->squishscan == SQS_API)) { + + // Open, read and close data file + data->fhsqd = ::sopen(AddPath(path(), ".sqd"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(data->fhsqd != -1) { + read(data->fhsqd, &data->base, sizeof(SqshBase)); + ::close(data->fhsqd); + data->fhsqd = -1; + } + } + else { + data->fhsqd = -1; + } + + // Allocate index buffer and read from file + refresh(); + + // Close index file + ::close(data->fhsqi); + data->fhsqi = -1; + } + } + + register ulong _msgno; + register SqshIdx* _sqiptr = data->idx; + register dword _totalmsgs = data->base.totalmsgs; + register ulong _firstmsgno = _totalmsgs ? _sqiptr->msgno : 0; + register ulong _lastmsgno = 0; + register uint _active = 0; + register uint _lastread_reln = 0; + register ulong _lastreadfound = 0; + + if(data->base.totalmsgs) { + + // (Re)allocate message index + if(__keep_index) + Msgn->Resize((uint)data->base.totalmsgs); + + register ulong* _msgndxptr = Msgn->tag; + + // Fill message index + while(_active < _totalmsgs) { + + _active++; + _msgno = (_sqiptr++)->msgno; + if(__keep_index) + *_msgndxptr++ = _msgno; + + // Check for premature end of index (free frames) + if((_msgno <= _lastmsgno) OR (_msgno == 0xFFFFFFFFL)) { + _active--; + if((_msgno == _lastmsgno) AND _active == 1) { + _lastread_reln = 0; + _active = 0; + } + break; + } + + // Get the lastread + if((_msgno >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = _msgno; + _lastread_reln = _active - (_msgno != _lastread ? 1 : 0); + } + + // Store last message number + _lastmsgno = _msgno; + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + } + + // Update area data + Msgn->SetCount(_active); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + // Scan for personal mail + if(__scanpm) { + int umax = (WidePersonalmail & PM_ALLNAMES) ? WideUsernames : 1; + vector uhash; + for(int uh=0; uhReset(); + register uint n = lastread + 1; + register uint cnt = Msgn->Count(); + register int gotpm = false; + while(n <= cnt) { + SqshIdx* idx = data->idx + (n-1); + for(int u=0; uhash & 0x80000000LU) == 0) { + if(idx->hash == uhash[u]) { + gotpm = true; + break; + } + } + } + if(gotpm) { + PMrk->Append(Msgn->at(n-1)); + gotpm = false; + } + n++; + } + } + + if(WideDebug) { + WideLog->printf("- %s: t:%u, l:%u, fm:%lu, hm:%lu, lr:%lu, u:%u, pm:%i", + echoid(), + Msgn->Count(), + lastread, + _firstmsgno, + _lastmsgno, + _lastread, + wide->userno, + __scanpm ? (int)PMrk->Count() : -1 + ); + } + + // Free index buffer if just counting + if(not __keep_index or __scanpm) + throw_xrelease(data->idx); + + if(_was_data == NULL) { + data = NULL; + wide = NULL; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::scan() { + + GFTRK("SquishScan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::scan_area() { + + GFTRK("SquishScanArea"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::scan_area_pm() { + + GFTRK("SquishScanAreaPM"); + + raw_scan(true, true); + Msgn->Reset(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmosqsh3.cpp b/goldlib/gmb3/gmosqsh3.cpp new file mode 100644 index 0000000..b19f830 --- /dev/null +++ b/goldlib/gmb3/gmosqsh3.cpp @@ -0,0 +1,201 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Squish msgbase handling and Maximus user functions. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +int SquishArea::load_message(int __mode, gmsg* __msg, SqshHdr& __hdr) { + + // Setup some local variables for speed + int _fhsqd = data->fhsqd; + SqshIdx* _idx = data->idx; + uint _reln = Msgn->ToReln(__msg->msgno); + + if(_reln == 0) { + GFTRK(NULL); + return false; + } + + // Load the message frame + SqshFrm _frm; + memset(&_frm, 0, sizeof(SqshFrm)); + lseekset(_fhsqd, _idx[_reln-1].offset); + read(_fhsqd, &_frm, sizeof(SqshFrm)); + + // Load the message header + memset(&__hdr, 0, sizeof(SqshHdr)); + read(_fhsqd, &__hdr, sizeof(SqshHdr)); + + // Read control info and message text + if(__mode & GMSG_TXT) { + + if(_frm.length) { + + // Allocate memory for kludges and message text, then read control info + char* _dest = __msg->txt = (char*)throw_calloc(1, (uint)(1+_frm.ctlsize+_frm.totsize-sizeof(SqshHdr))); + char* _src = _dest + (uint)_frm.ctlsize; + *_src = NUL; + read(_fhsqd, _src, (uint)_frm.ctlsize); + + // Convert Squish control info to true kludges + while(*_src AND (*_src == CTRL_A) AND _src[1]) { + + // Copy the kludge char unless it's the AREA: line + if(NOT ((*(dword*)(_src+1) == CHR4_AREA) AND strneql(_src+1, "AREA:", 5))) + *_dest++ = *_src; + _src++; + + // Copy the rest of the kludge and add a CR termination + while((*_src != CTRL_A) AND *_src) + *_dest++ = *_src++; + *_dest++ = CR; + } + + // Make sure the kludge block is NUL terminated + *_dest = NUL; + + // Read the message text right after the kludges + uint _txtlen = (uint)(_frm.totsize - _frm.ctlsize - sizeof(SqshHdr)); + read(_fhsqd, _dest, _txtlen); + + // Make sure the text is NUL terminated + _dest[_txtlen] = NUL; + } + else { + __msg->txt = (char*)throw_calloc(1, 1); + } + } + + // Convert header + + __msg->link.to_set(__hdr.replyto); + __msg->link.first_set(__hdr.replies[0]); + + // Convert link.list + int q = 0; + int r = __hdr.replies[0] == __hdr.replies[1] ? 2 : 1; + while(r<=8) { + if(__hdr.replies[r] and __hdr.replies[r-1] != __hdr.replies[r]) + __msg->link.list_set(q++, __hdr.replies[r]); + r++; + } + + strxcpy(__msg->by, __hdr.from, sizeof(__msg->by)); + strxcpy(__msg->to, __hdr.to, sizeof(__msg->to)); + strxcpy(__msg->re, __hdr.subj, sizeof(__msg->re)); + + __msg->orig.zone = __msg->oorig.zone = __hdr.orig.zone; + __msg->orig.net = __msg->oorig.net = __hdr.orig.net; + __msg->orig.node = __msg->oorig.node = __hdr.orig.node; + __msg->orig.point = __msg->oorig.point = __hdr.orig.point; + + __msg->dest.zone = __msg->odest.zone = __hdr.dest.zone; + __msg->dest.net = __msg->odest.net = __hdr.dest.net; + __msg->dest.node = __msg->odest.node = __hdr.dest.node; + __msg->dest.point = __msg->odest.point = __hdr.dest.point; + + // Convert date and time + time_t _written = FTimeToTime(&__hdr.date_written); + __msg->written = _written ? _written : FidoTimeToUnix(__hdr.ftsc_date); + __msg->arrived = FTimeToTime(&__hdr.date_arrived); + + __msg->timesread = (__hdr.attr & MSGSEEN) ? 1 : 0; + + // Convert attributes + __msg->attr.pvt(__hdr.attr & MSGPRIVATE); + __msg->attr.cra(__hdr.attr & MSGCRASH); + __msg->attr.rcv(__hdr.attr & MSGREAD); + __msg->attr.snt(__hdr.attr & MSGSENT); + __msg->attr.att(__hdr.attr & MSGFILE); + __msg->attr.trs(__hdr.attr & MSGFWD); + __msg->attr.orp(__hdr.attr & MSGORPHAN); + __msg->attr.k_s(__hdr.attr & MSGKILL); + __msg->attr.loc(__hdr.attr & MSGLOCAL); + __msg->attr.hld(__hdr.attr & MSGHOLD); + __msg->attr.rsv(__hdr.attr & MSGXX2); + __msg->attr.frq(__hdr.attr & MSGFRQ); + __msg->attr.rrq(__hdr.attr & MSGRRQ); + __msg->attr.rrc(__hdr.attr & MSGCPT); + __msg->attr.arq(__hdr.attr & MSGARQ); + __msg->attr.urq(__hdr.attr & MSGURQ); + __msg->attr.scn(__hdr.attr & MSGSCANNED); + __msg->attr.prn(__hdr.attr & MSGPRINTED); + __msg->attr.lok(__hdr.attr & MSGLOK); + + if(isnet()) { + __msg->attr.uns(__msg->attr.loc() AND NOT __msg->attr.snt()); + if(wide->direct and __msg->attr.hld() and __msg->attr.cra()) { + // Translate hld+cra to dir attribute + __msg->attr.dir1(); + __msg->attr.cra0(); + __msg->attr.hld0(); + } + } + else if(isecho()) + __msg->attr.uns(__msg->attr.loc() AND ((__hdr.attr & MSGSCANNED) ? 0 : 1)); + else + __msg->attr.uns0(); + + GFTRK(NULL); + + return true; +} + + +// ------------------------------------------------------------------ + +int SquishArea::load_hdr(gmsg* __msg) { + + GFTRK("SquishLoadHdr"); + + SqshHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int SquishArea::load_msg(gmsg* __msg) { + + GFTRK("SquishLoadMsg"); + + SqshHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmosqsh4.cpp b/goldlib/gmb3/gmosqsh4.cpp new file mode 100644 index 0000000..4700fbc --- /dev/null +++ b/goldlib/gmb3/gmosqsh4.cpp @@ -0,0 +1,717 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Squish msgbase handling and Maximus user functions. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +void SquishArea::lock() { + + GFTRK("SquishLock"); + + if(NOT data->islocked) { + if(WideCanLock) { + long _tries = 0; + while(::lock(data->fhsqd, 0, 1) == -1) { + if(PopupLocked(++_tries, true, path()) == false) { + WideLog->ErrLock(); + raw_close(); + WideLog->printf("! A Squish msgbase file could not be locked."); + WideLog->printf(": %s.SQD.", path()); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + } + if(_tries) + PopupLocked(0, 0, NULL); + } + refresh(); + data->islocked = true; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::unlock() { + + GFTRK("SquishUnlock"); + + if(WideCanLock AND data->islocked) + ::unlock(data->fhsqd, 0, 1); + lseekset(data->fhsqd, 0); + write(data->fhsqd, &data->base, sizeof(SqshBase)); + lseekset(data->fhsqi, 0); + write(data->fhsqi, data->idx, (uint)(data->base.totalmsgs*sizeof(SqshIdx))); + chsize(data->fhsqi, data->base.totalmsgs*sizeof(SqshIdx)); + data->islocked = false; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::read_frm(dword __offset, SqshFrm* __frm) { + + lseekset(data->fhsqd, __offset); + read(data->fhsqd, __frm, sizeof(SqshFrm)); +} + + +// ------------------------------------------------------------------ + +void SquishArea::write_frm(dword __offset, SqshFrm* __frm) { + + lseekset(data->fhsqd, __offset); + write(data->fhsqd, __frm, sizeof(SqshFrm)); +} + + +// ------------------------------------------------------------------ + +void SquishArea::upd_frm_next(dword __offset, SqshFrm* __frm, dword __next) { + + if(__offset != SQFRAME_NULL) { + read_frm(__offset, __frm); + __frm->next = __next; + write_frm(__offset, __frm); + } +} + + +// ------------------------------------------------------------------ + +void SquishArea::upd_frm_prev(dword __offset, SqshFrm* __frm, dword __prev) { + + if(__offset != SQFRAME_NULL) { + read_frm(__offset, __frm); + __frm->prev = __prev; + write_frm(__offset, __frm); + } +} + + +// ------------------------------------------------------------------ + +void SquishArea::add_to_free_chain(dword __delframe, SqshFrm* __delfrm) { + + SqshBase& _base = data->base; + + // Update free frame chain + if((_base.firstfreeframe == SQFRAME_NULL) or (_base.lastfreeframe == SQFRAME_NULL)) { + + // No other free frames, so create new chain + _base.firstfreeframe = _base.lastfreeframe = __delframe; + __delfrm->prev = __delfrm->next = SQFRAME_NULL; + } + else { + + // Insert this frame into the chain + __delfrm->next = SQFRAME_NULL; + __delfrm->prev = _base.lastfreeframe; + SqshFrm _lastfrm; + upd_frm_next(_base.lastfreeframe, &_lastfrm, __delframe); + _base.lastfreeframe = __delframe; + } + + // Write the deleted frame + __delfrm->type = SQFRAME_FREE; + //WideLog->printf("- Deleted frame 0x%08lX of length %lu.", __delframe, __delfrm->length); + write_frm(__delframe, __delfrm); +} + + +// ------------------------------------------------------------------ + +void SquishArea::delete_msg(uint __reln) { + + GFTRK("SquishDeleteMsg"); + + int _was_locked = data->islocked; + if(NOT _was_locked) + lock(); + + // Setup some local variables for speed + SqshIdx* _idx = data->idx; + SqshBase& _base = data->base; + + // Load the frame to be deleted + SqshFrm _delfrm; + dword _delframe = _idx[__reln].offset; + read_frm(_delframe, &_delfrm); + + // Chain the previous and next frames together + SqshFrm _tmpfrm; + upd_frm_next(_delfrm.prev, &_tmpfrm, _delfrm.next); + upd_frm_prev(_delfrm.next, &_tmpfrm, _delfrm.prev); + + // Update base data if the first or last frame was deleted + if(_delframe == _base.firstframe) + _base.firstframe = _delfrm.next; + if(_delframe == _base.lastframe) + _base.lastframe = _delfrm.prev; + + // Add the deleted msg to the free frame chain + add_to_free_chain(_delframe, &_delfrm); + + // Remove deleted message number from the indexes + Msgn->DelReln(__reln+1); + dword _tomove = _base.totalmsgs - __reln - 1; + memmove(_idx+__reln, _idx+__reln+1, (uint)(_tomove*sizeof(SqshIdx))); + + // Update base data + _base.highestmsg--; + _base.totalmsgs--; + + // Update area data + if(lastread) + lastread--; + + if(NOT _was_locked) + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::init_frm(SqshFrm* __frm) { + + memset(__frm, 0, sizeof(SqshFrm)); + __frm->type = SQFRAME_NORMAL; + __frm->id = SQFRAMEID; +} + + +// ------------------------------------------------------------------ +// Copy the text itself to a buffer, or count its length if out==NULL + +uint CopyToBuf(char* p, char* out, char** end) { + + if(out) + *out++ = CTRL_A; + + uint len = 1; + + while((*p==CR) or (*p==LF) or (not WideDispsoftcr and *p==SOFTCR)) + p++; + + while((*p==CTRL_A) or (strncmp(p, "AREA:", 5)==0)) { + + // Skip over the first ^A + if(*p == CTRL_A) + p++; + + while(*p and (*p != CR) and (*p != LF) and (WideDispsoftcr or *p!=SOFTCR)) { + if(out) + *out++ = *p; + len++; + p++; + } + + if(out) + *out++ = CTRL_A; + + len++; + + while((*p==LF) or (not WideDispsoftcr and *p==SOFTCR)) + p++; + if(*p == CR) + p++; + while((*p==LF) or (not WideDispsoftcr and *p==SOFTCR)) + p++; + } + + // Nul-term the string + if(out) + *out = NUL; + + len++; + + // Make sure to leave no trailing CTRL_A's. + if(out and (out[-1]==CTRL_A)) + out[-1] = NUL; + + + // Now store the new end location of the kludge lines + if(end) + *end = p; + + return len; +} + + +// ------------------------------------------------------------------ + +char* CopyToControlBuf(char* txt, char** newtext, uint* length) { + + // Figure out how long the control info is + uint ctlsize = CopyToBuf(txt, NULL, NULL); + + // Allocate memory for it + char* cbuf = (char*)throw_calloc(1, ctlsize+20); + + // Now copy the text itself + char* end; + CopyToBuf(txt, cbuf, &end); + + if(length) + *length -= (uint)(end-txt); + if(newtext) + *newtext = end; + + return cbuf; +} + + +// ------------------------------------------------------------------ + +void SquishArea::excess_frm(dword __lastframe, dword __newframe, SqshFrm* __newfrm, dword __totsize) { + + // Is the excess length large enough for a frame and message header? + dword _excesslength = __newfrm->length - __totsize; + if(_excesslength >= sizeof(SqshFrm)) { + + // Calculate frame offset of the excess frame + dword _exframe = __newframe + __totsize + sizeof(SqshFrm); + + // Adjust base data if this becomes the last free frame + if(__lastframe == data->base.lastfreeframe) + data->base.lastfreeframe = _exframe; + + // Setup the excess frame and write it + SqshFrm _exfrm; + init_frm(&_exfrm); + _exfrm.type = SQFRAME_FREE; + _exfrm.next = __newfrm->next; + _exfrm.prev = __newframe; + __newfrm->next = _exframe; + __newfrm->length = __totsize; + _exfrm.length = _excesslength - sizeof(SqshFrm); + write_frm(_exframe, &_exfrm); + SqshFrm _tmpfrm; + upd_frm_prev(_exfrm.next, &_tmpfrm, _exframe); + //WideLog->printf("- Created excess free frame 0x%08lX of length %lu.", _exframe, _exfrm.length); + } +} + + +// ------------------------------------------------------------------ + +uint SquishArea::find_msgn(ulong __tagn) { + + if(data->idx) { + + register SqshIdx* tag = data->idx; + register uint tags = (uint)data->base.totalmsgs; + + if(__tagn AND tags AND (__tagn > tag[tags-1].msgno)) + return 0; + + if(tags AND __tagn) { + + register long _mid; + register long _left = 0; + register long _right = tags; + + do { + _mid = (_left+_right)/2; + if(__tagn < tag[(uint)_mid].msgno) + _right = _mid - 1; + else if(__tagn > tag[(uint)_mid].msgno) + _left = _mid + 1; + else + return (uint)(_mid + 1); + } while(_left < _right); + + if(__tagn == tag[(uint)_left].msgno) + return (uint)(_left + 1); + } + } + + return 0; +} + + +// ------------------------------------------------------------------ + +void SquishArea::save_message(int __mode, gmsg* __msg) { + + SqshHdr __hdr; + int _was_locked = data->islocked; + if(not _was_locked) + lock(); + + // If not new, does the message still exist? + if((__mode & GMSG_NEW) or find_msgn(__msg->msgno)) { + + uint _reln = (__mode & GMSG_NEW) ? 0 : (Msgn->ToReln(__msg->msgno) - 1); + + // Reset header + memset(&__hdr, 0, sizeof(SqshHdr)); + + // Convert attributes + __hdr.attr |= MSGUID; + __hdr.attr |= __msg->attr.pvt() ? MSGPRIVATE : 0; + __hdr.attr |= __msg->attr.cra() ? MSGCRASH : 0; + __hdr.attr |= __msg->attr.rcv() ? MSGREAD : 0; + __hdr.attr |= __msg->attr.snt() ? MSGSENT : 0; + __hdr.attr |= __msg->attr.att() ? MSGFILE : 0; + __hdr.attr |= __msg->attr.trs() ? MSGFWD : 0; + __hdr.attr |= __msg->attr.orp() ? MSGORPHAN : 0; + __hdr.attr |= __msg->attr.k_s() ? MSGKILL : 0; + __hdr.attr |= __msg->attr.loc() ? MSGLOCAL : 0; + __hdr.attr |= __msg->attr.hld() ? MSGHOLD : 0; + __hdr.attr |= __msg->attr.rsv() ? MSGXX2 : 0; + __hdr.attr |= __msg->attr.frq() ? MSGFRQ : 0; + __hdr.attr |= __msg->attr.rrq() ? MSGRRQ : 0; + __hdr.attr |= __msg->attr.rrc() ? MSGCPT : 0; + __hdr.attr |= __msg->attr.arq() ? MSGARQ : 0; + __hdr.attr |= __msg->attr.urq() ? MSGURQ : 0; + __hdr.attr |= __msg->attr.prn() ? MSGPRINTED : 0; + __hdr.attr |= __msg->attr.lok() ? MSGLOK : 0; + __hdr.attr |= __msg->timesread ? MSGSEEN : 0; + + if(__msg->attr.scn() and not __msg->attr.uns()) + __hdr.attr |= MSGSCANNED; + + if(__msg->attr.dir() and wide->direct) + __hdr.attr |= MSGCRASH | MSGHOLD; + + memcpy(__hdr.from, __msg->by, 36); + memcpy(__hdr.to, __msg->to, 36); + memcpy(__hdr.subj, __msg->re, 72); + + __hdr.orig.zone = __msg->oorig.zone; + __hdr.orig.net = __msg->oorig.net; + __hdr.orig.node = __msg->oorig.node; + __hdr.orig.point = __msg->oorig.point; + + __hdr.dest.zone = __msg->odest.zone; + __hdr.dest.net = __msg->odest.net; + __hdr.dest.node = __msg->odest.node; + __hdr.dest.point = __msg->odest.point; + + __hdr.replyto = __msg->link.to(); + __hdr.replies[0] = __msg->link.first(); + for(int r=1; r<=8; r++) + __hdr.replies[r] = __msg->link.list(r-1); + __hdr.umsgid = (__mode & GMSG_NEW) ? data->base.nextmsgno : __msg->msgno; + + __hdr.date_written = TimeToFTime(__msg->written); + __hdr.date_arrived = TimeToFTime(__msg->arrived); + struct tm* _tm = gmtime(&__msg->written); + sprintf(__hdr.ftsc_date, "%02d %3s %02d %02d:%02d:%02d", + _tm->tm_mday, gmonths[_tm->tm_mon+1], _tm->tm_year % 100, + _tm->tm_hour, _tm->tm_min, _tm->tm_sec + ); + + // Setup some local variables for speed + int _fhsqd = data->fhsqd; + SqshIdx* _idx = data->idx; + SqshBase& _base = data->base; + dword _hash = strHash32(__hdr.to) | ((__hdr.attr & MSGREAD) ? 0x80000000LU : 0); + + // Writing msg text? + if(__mode & GMSG_TXT) { + + char* _txt = __msg->txt; + uint _usize = strlen(_txt) + 1; + char* _ctl = CopyToControlBuf(_txt, &_txt, &_usize); + dword _txtsize = strlen(_txt) + 1; + dword _ctlsize = strlen(_ctl) + 1; + dword _totsize = sizeof(SqshHdr) + _ctlsize + _txtsize; + + SqshFrm _oldfrm, _newfrm; + dword _newframe = SQFRAME_NULL; + dword _oldframe = _idx ? _idx[_reln].offset : _base.endframe; + if(NOT(__mode & GMSG_NEW)) { + + // Get the original frame and see if there is still room for the msg + read_frm(_oldframe, &_oldfrm); + if(_oldfrm.length >= _totsize) { + _newframe = _oldframe; + _newfrm = _oldfrm; + } + } + + // It's a new message or the changed message doesn't fit + if(_newframe == SQFRAME_NULL) { + + // If there is a max msgs limit and are we writing a new + // msg, delete msgs to (hopefully) make room for this msg + if(_base.maxmsgs AND (__mode & GMSG_NEW)) + while(_base.maxmsgs <= _base.totalmsgs) + delete_msg((uint)_base.protmsgs); + + // Locate a free frame, if possible + _newframe = _base.firstfreeframe; + //WideLog->printf("- Looking for a frame of at least length %lu.", _totsize); + while(1) { + + // At end of free frames? + if(_newframe == SQFRAME_NULL) { + _newframe = _base.endframe; + init_frm(&_newfrm); + //WideLog->printf("- Allocated new frame 0x%08lX of length %lu.", _newframe, _totsize); + break; + } + + // Is this frame large enough in itself? + read_frm(_newframe, &_newfrm); + //WideLog->printf("- Found free frame 0x%08lX of length %lu.", _newframe, _newfrm.length); + if(_newfrm.length >= _totsize) { + + // Create excess frame if possible + if(wide->recycle == SQUISHRECYCLE_YES) { + excess_frm(_newframe, _newframe, &_newfrm, _totsize); + //WideLog->printf("- Frame was large enough (%lu bytes wasted).", _newfrm.length - _totsize); + } + break; + } + + // If two frames are adjacent, try to merge them to make more room + if(wide->recycle and (wide->recycle != SQUISHRECYCLE_MSGAPI2)) { + dword _lastframe = SQFRAME_NULL; + while((_newfrm.next == (_newframe+_newfrm.length+sizeof(SqshFrm))) and (_newfrm.length < _totsize)) { + SqshFrm _lastfrm; + read_frm(_newfrm.next, &_lastfrm); + _newfrm.length += _lastfrm.length + sizeof(SqshFrm); + //WideLog->printf("- Merged frames 0x%08lX and 0x%08lX. New length: %lu.", _newframe, _newfrm.next, _newfrm.length); + _lastframe = _newfrm.next; + _newfrm.next = _lastfrm.next; + } + + // Did we get a large enough frame? + if(_newfrm.length >= _totsize) { + + // Create excess frame if possible + if(wide->recycle == SQUISHRECYCLE_YES) { + excess_frm(_lastframe, _newframe, &_newfrm, _totsize); + //WideLog->printf("- Merged frame was large enough (%lu bytes wasted).", _newfrm.length - _totsize); + } + + // If one of the frames in our chain was the last free frame, + // set the last free frame to the one we've merged it into, + // for later a clean up effort. + if(_lastframe == _base.lastfreeframe) + _base.lastfreeframe = _newframe; + + // Got a free frame + break; + } + } + + // Go to next free frame and try again + _newframe = _newfrm.next; + } + + // If this was the first frame (ie. the first one pointed to by + // firstfreeframe, which means that the first frame found was long + // enough to hold the message), then set the free pointer to the + // start of the new free chain. + if(_newframe == _base.firstfreeframe) + _base.firstfreeframe = _newfrm.next; + if(_newframe == _base.lastfreeframe) + _base.lastfreeframe = _newfrm.prev; + + // Now update the linked list of free frames, to remove the current + // frame from the free-frame list, if necessary. We only need to do + // this if the current frame wasn't just being appended to the .SQD + // file, since there would be no links to update in that case. + if(_newframe != _base.endframe) { + SqshFrm _tmpfrm; + upd_frm_next(_newfrm.prev, &_tmpfrm, _newfrm.next); + upd_frm_prev(_newfrm.next, &_tmpfrm, _newfrm.prev); + } + + if(__mode & GMSG_NEW) { + + // Link the frame to the last frame + _newfrm.prev = _base.lastframe; + _newfrm.next = SQFRAME_NULL; + SqshFrm _tmpfrm; + upd_frm_next(_newfrm.prev, &_tmpfrm, _newframe); + if(_base.firstframe == SQFRAME_NULL) + _base.firstframe = _newframe; + _base.lastframe = _newframe; + } + else { + + // Rewriting old message + _newfrm.next = _oldfrm.next; + _newfrm.prev = _oldfrm.prev; + add_to_free_chain(_oldframe, &_oldfrm); + SqshFrm _tmpfrm; + upd_frm_next(_newfrm.prev, &_tmpfrm, _newframe); + upd_frm_prev(_newfrm.next, &_tmpfrm, _newframe); + if(_base.firstframe == _oldframe) + _base.firstframe = _newframe; + if(_base.lastframe == _oldframe) + _base.lastframe = _newframe; + } + + // Set the frame length only if this is a brand new frame + if(_newframe == _base.endframe) { + _newfrm.length = _totsize; + _base.endframe += sizeof(SqshFrm) + _totsize; + } + } + + // Set sizes in the frame + _newfrm.totsize = _totsize; + _newfrm.ctlsize = _ctlsize; + _newfrm.type = SQFRAME_NORMAL; + + // Write frame, header, control info and message text + write_frm(_newframe, &_newfrm); + write(_fhsqd, &__hdr, sizeof(SqshHdr)); + write(_fhsqd, _ctl, (uint)_ctlsize); + write(_fhsqd, _txt, (uint)_txtsize); + throw_free(_ctl); + + // Update internal arrays if new + if(__mode & GMSG_NEW) { + _base.highestmsg++; + _reln = (uint)(_base.totalmsgs++); + __msg->msgno = _base.nextmsgno++; + Msgn->Append(__msg->msgno); + data->idx = _idx = (SqshIdx*)throw_realloc(data->idx, (uint)(_base.totalmsgs*sizeof(SqshIdx))); + } + + // Update index + SqshIdx* _idxp = _idx + _reln; + _idxp->offset = _newframe; + _idxp->msgno = __msg->msgno; + _idxp->hash = _hash; + } + else { + + // Just update the header + _idx[_reln].hash = _hash; + lseekset(_fhsqd, _idx[_reln].offset+sizeof(SqshFrm)); + write(_fhsqd, &__hdr, sizeof(SqshHdr)); + } + + // Adjust the highwatermark if required + if(__msg->attr.uns()) + if(_base.highwatermark >= __msg->msgno) + _base.highwatermark = __msg->msgno - 1; + } + else { + scan(); + } + + if(not _was_locked) + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("SquishSaveHdr"); + + save_message(__mode|GMSG_HDR, __msg); +} + + +// ------------------------------------------------------------------ + +void SquishArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("SquishSaveMsg"); + + save_message(__mode|GMSG_HDRTXT, __msg); +} + + +// ------------------------------------------------------------------ + +void SquishArea::del_msg(gmsg* __msg) { + + GFTRK("SquishDelMsg"); + + delete_msg(Msgn->ToReln(__msg->msgno)-1); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void SquishArea::new_msgno(gmsg* __msg) { + + __msg->msgno = data->base.nextmsgno; +} + + +// ------------------------------------------------------------------ + +void SquishArea::update_timesread(gmsg* msg) { + + GFTRK("SquishArea::update_timesread"); + + lock(); + + uint reln = Msgn->ToReln(msg->msgno) - 1; + + dword frame = data->idx[reln].offset; + + SqshHdr hdr; + ::lseekset(data->fhsqd, frame+sizeof(SqshFrm)); + ::read(data->fhsqd, &hdr, sizeof(SqshHdr)); + + hdr.attr |= msg->timesread ? MSGSEEN : 0; + + ::lseekset(data->fhsqd, frame+sizeof(SqshFrm)); + ::write(data->fhsqd, &hdr, sizeof(SqshHdr)); + + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmosqsh5.cpp b/goldlib/gmb3/gmosqsh5.cpp new file mode 100644 index 0000000..9ed6b08 --- /dev/null +++ b/goldlib/gmb3/gmosqsh5.cpp @@ -0,0 +1,163 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// Squish msgbase handling and Maximus user functions. +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +char* SquishArea::user_lookup(char* __lookfor) { + + Path userfile; + strxcpy(userfile, wide->userpath, sizeof(Path)); + AddPath(userfile, "USER.BBS"); + wide->user->fh = ::sopen(userfile, O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + wide->user->findwild(__lookfor, __lookfor); + ::close(wide->user->fh); + + if(wide->user->found) + return __lookfor; + else + return NULL; +} + + +// ------------------------------------------------------------------ + +int SquishArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ + +Line* SquishArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) { + + GFTRK("SquishMakeDump"); + + // Load the base record + SqshBase _base; + lseekset(data->fhsqd, 0); + read(data->fhsqd, &_base, sizeof(SqshBase)); + + // Load the index record + SqshIdx _idx; + uint _reln = Msgn->ToReln(msg->msgno); + lseekset(data->fhsqi, _reln-1, sizeof(SqshIdx)); + read(data->fhsqi, &_idx, sizeof(SqshIdx)); + + // Load the message frame + SqshFrm _frm; + dword _frame = _idx.offset; + lseekset(data->fhsqd, _frame); + read(data->fhsqd, &_frm, sizeof(SqshFrm)); + + // Load the header and message text + SqshHdr _hdr; + load_message(GMSG_HDRTXT, msg, _hdr); + + char buf[100]; + Line* line = lin = + AddLine (NULL, "Hexdump of Squish-style message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Msgbase : %s", path()); + AddLineF(line, "From : %-36.36s", _hdr.from); + AddLineF(line, "To : %-36.36s", _hdr.to); + AddLineF(line, "Subject : %-72.72s", _hdr.subj); + AddLineF(line, "DateTime : %-20.20s", _hdr.ftsc_date); + AddLineF(line, "OrigAddr : %u:%u/%u.%u", _hdr.orig.zone, _hdr.orig.net, _hdr.orig.node, _hdr.orig.point); + AddLineF(line, "DestAddr : %u:%u/%u.%u", _hdr.dest.zone, _hdr.dest.net, _hdr.dest.node, _hdr.dest.point); + AddLineF(line, "Umsgid : %lu", _hdr.umsgid); + AddLineF(line, "Reply : %lu", _hdr.replyto); + AddLineF(line, "See : %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu", + _hdr.replies[0], _hdr.replies[1], _hdr.replies[2], + _hdr.replies[3], _hdr.replies[4], _hdr.replies[5], + _hdr.replies[6], _hdr.replies[7], _hdr.replies[8] + ); + AddLineF(line, "Attr : %08lXh (%sb)", _hdr.attr, ltob(buf,_hdr.attr,0)); + AddLineF(line, "DateWritten : %s (%08lXh)", FTimeToStr(buf, _hdr.date_written), *(dword*)&_hdr.date_written); + AddLineF(line, "DateArrived : %s (%08lXh)", FTimeToStr(buf, _hdr.date_arrived), *(dword*)&_hdr.date_arrived); + AddLineF(line, "UTC-Offset : %u", _hdr.utc_offset); + AddLineF(line, "UserRecno : %u (%s)", wide->userno, WideUsername[0]); + line = AddLine(line, ""); + AddLineF(line, "Message Base Record:"); + line = AddLine(line, ""); + AddLineF(line, "TotalMsgs : %lu", _base.totalmsgs); + AddLineF(line, "HighestMsg : %lu", _base.highestmsg); + AddLineF(line, "NextMsgno : %lu", _base.nextmsgno); + AddLineF(line, "HighWaterMark : %lu", _base.highwatermark); + AddLineF(line, "FirstFrame : %08lXh (%lu)", _base.firstframe, _base.firstframe); + AddLineF(line, "LastFrame : %08lXh (%lu)", _base.lastframe, _base.lastframe); + AddLineF(line, "FirstFreeFrame : %08lXh (%lu)", _base.firstfreeframe, _base.firstfreeframe); + AddLineF(line, "LastFreeFrame : %08lXh (%lu)", _base.lastfreeframe, _base.lastfreeframe); + AddLineF(line, "EndFrame : %08lXh (%lu)", _base.endframe, _base.endframe); + AddLineF(line, "Max/Skip/Days : %lu %lu %u", _base.maxmsgs, _base.protmsgs, _base.daystokeep); + line = AddLine(line, ""); + AddLineF(line, "Message Index Record:"); + line = AddLine(line, ""); + AddLineF(line, "FrameOffset : %08lXh (%lu)", _idx.offset, _idx.offset); + AddLineF(line, "MessageNumber : %08lXh (%lu)", _idx.msgno, _idx.msgno); + AddLineF(line, "HashValue : %08lXh (%lu)", _idx.hash, _idx.hash); + line = AddLine(line, ""); + AddLineF(line, "Message Frame Record:"); + line = AddLine(line, ""); + AddLineF(line, "Frame-ID : %08lXh%s", _frm.id, (_frm.id != SQFRAMEID) ? " (error, should be AFAE4453h!)" : ""); + AddLineF(line, "ThisFrame : %08lXh (%lu)", _frame, _frame); + AddLineF(line, "PrevFrame : %08lXh (%lu)", _frm.prev, _frm.prev); + AddLineF(line, "NextFrame : %08lXh (%lu)", _frm.next, _frm.next); + AddLineF(line, "FrameLength : %lu", _frm.length); + AddLineF(line, "TotalLength : %lu", _frm.totsize); + AddLineF(line, "CtrlLength : %lu", _frm.ctlsize); + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + int _count = 0; + char* _ptr = (char*)&_hdr; + while(_count < sizeof(SqshHdr)) { + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, 16, HEX_DUMP2); + line = AddLine(line, buf); + _count += 16; + _ptr += 16; + } + sprintf(buf, "%04X ", _count); + HexDump16(buf+7, _ptr, sizeof(SqshHdr)%16, HEX_DUMP2); + line = AddLine(line, buf); + + GFTRK(NULL); + + return line; +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmowcat.h b/goldlib/gmb3/gmowcat.h new file mode 100644 index 0000000..e026f07 --- /dev/null +++ b/goldlib/gmb3/gmowcat.h @@ -0,0 +1,244 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! 4.0 Structures. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ +// Only include once! + +#ifndef __GMWCAT_H +#define __GMWCAT_H + + +// ------------------------------------------------------------------ + +#include +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// WildCat! 4.0 Magic Numbers + +const long MagicHeaderActive = 0x001A1A1BL; +const long MagicHeaderInactive = 0x011A1A1BL; + + +// ------------------------------------------------------------------ +// WildCat! 4.0 Message Attributes (mflags) + +const word mfPrivate = 0x0001; +const word mfReceiveable = 0x0002; +const word mfReceived = 0x0004; +const word mfReceipt = 0x0008; +const word mfCarboned = 0x0010; +const word mfForwarded = 0x0020; +const word mfEchoFlag = 0x0040; +const word mfHasReplies = 0x0100; +const word mfDeleted = 0x0200; +const word mfTagged = 0x0400; +const word mfSent = 0x0800; + + +// ------------------------------------------------------------------ +// Fido message attributes + +#define FIDO_PVT 0x0001 +#define FIDO_CRASH 0x0002 +#define FIDO_RECEIVED 0x0004 +#define FIDO_SENT 0x0008 +#define FIDO_ATTACH 0x0010 +#define FIDO_TRANSIT 0x0020 +#define FIDO_ORPHAN 0x0040 +#define FIDO_KILLSENT 0x0080 +#define FIDO_LOCAL 0x0100 +#define FIDO_HOLD 0x0200 +#define FIDO_RESERVED 0x0400 +#define FIDO_FREQ 0x0800 +#define FIDO_RETRECREQ 0x1000 +#define FIDO_RETREC 0x2000 +#define FIDO_AUDITREQ 0x4000 +#define FIDO_UPDREQ 0x8000 + + +// ------------------------------------------------------------------ +// WildCat! 4.0 Message Header + +struct WCatHdr { + long magicnumber; + word msgno; + char from[71]; + char fromtitle[11]; + long fromuserid; + char to[71]; + char totitle[11]; + long touserid; + char subject[71]; + char network[9]; + word msgdate; + long msgtime; + word readdate; + long readtime; + word mflags; + word reference; + Addr origaddr; + Addr destaddr; + word msgbytes; + char internalattach[13]; + char externalattach[13]; + word prevunread; + word nextunread; + word fidoflags; + long cost; + byte reserved[20]; +}; + + +// ------------------------------------------------------------------ +// WildCat! 4.0 Message Index Base Record + +struct WCatBase { + word recsize; + word active; + word nextmsgno; +}; + + +// ------------------------------------------------------------------ +// WildCat! 4.0 Message Index Record + +struct WCatIdx { + word msgno; + long offset; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct WCatData { + int fhix; + int fhdat; + WCatBase base; + WCatIdx* idx; + int islocked; +}; + + +// ------------------------------------------------------------------ + +struct WCatWide { + int userno; +// WildCatUser* user; +}; + + +// ------------------------------------------------------------------ + +class WCatArea : public gmo_area { + +protected: + + WCatWide* wide; + WCatData* data; + + void data_open(); + void data_close(); + + int test_open(const char* __file); + void raw_open(); + void save_lastread(); + void raw_scan(int __keep_index, int __scanpm=false); + void save_message(int __mode, gmsg* __msg, WCatHdr& __hdr); + + void raw_close(); + void refresh(); + int load_message(int __mode, gmsg* __msg, WCatHdr& __hdr); + +public: + + WCatArea() { wide = NULL; data = NULL; } + virtual ~WCatArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern WCatWide* wcatwide; +extern WCatData* wcatdata; +extern int wcatdatano; + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmowcat1.cpp b/goldlib/gmb3/gmowcat1.cpp new file mode 100644 index 0000000..d6eb5dc --- /dev/null +++ b/goldlib/gmb3/gmowcat1.cpp @@ -0,0 +1,238 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! 4.x messagebase engine. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +WCatWide* wcatwide = NULL; +WCatData* wcatdata = NULL; +int wcatdatano = 0; + + +// ------------------------------------------------------------------ + +void WCatArea::data_open() { + + wide = wcatwide; + data = wcatdata + (wcatdatano++); +} + + +// ------------------------------------------------------------------ + +void WCatArea::data_close() { + + wcatdatano--; +} + + +// ------------------------------------------------------------------ + +void WCatArea::raw_close() { + + GFTRK("WCatRawClose"); + + if(data->fhix != -1) ::close(data->fhix); data->fhix = -1; + if(data->fhdat != -1) ::close(data->fhdat); data->fhdat = -1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +int WCatArea::test_open(const char* __file) { + + GFTRK("WCatTestOpen"); + + int _fh; + long _tries = 0; + + do { + + _fh = ::sopen(__file, O_RDWR|O_BINARY|O_CREAT, WideSharemode, S_STDRW); + if(_fh == -1) { + + // Tell the world + if(PopupLocked(++_tries, false, __file) == false) { + + // User requested to exit + WideLog->ErrOpen(); + raw_close(); + WideLog->printf("! A WildCat! msgbase file could not be opened."); + WideLog->printf(": %s.", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void WCatArea::raw_open() { + + GFTRK("WCatRawOpen"); + + data->fhix = test_open(AddPath(path(), ".ix")); + data->fhdat = test_open(AddPath(path(), ".dat")); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatExit() { + + throw_xrelease(wcatwide); + throw_xrelease(wcatdata); +} + + +// ------------------------------------------------------------------ + +void WCatInit(int userno) { + + wcatdata = (WCatData*)throw_calloc(2, sizeof(WCatData)); + wcatwide = (WCatWide*)throw_calloc(1, sizeof(WCatWide)); + + wcatwide->userno = userno; +} + + +// ------------------------------------------------------------------ + +void WCatArea::open() { + + GFTRK("WCatOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open a WildCat! msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + raw_open(); + refresh(); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::save_lastread() { + + GFTRK("WCatSaveLastread"); + + int _fh = ::sopen(AddPath(path(), ".lrd"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(_fh != -1) { + word _lastread = (word)Msgn->CvtReln(lastread); + lseekset(_fh, wcatwide->userno, sizeof(word)); + write(_fh, &_lastread, sizeof(word)); + ::close(_fh); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::close() { + + GFTRK("WCatClose"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + raw_close(); + Msgn->Reset(); + throw_release(data->idx); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed WildCat! msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::suspend() { + + GFTRK("WCatSuspend"); + + save_lastread(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::resume() { + + GFTRK("WCatResume"); + + + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmowcat2.cpp b/goldlib/gmb3/gmowcat2.cpp new file mode 100644 index 0000000..3f9d85d --- /dev/null +++ b/goldlib/gmb3/gmowcat2.cpp @@ -0,0 +1,220 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! 4.x messagebase engine. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +void WCatArea::refresh() { + + GFTRK("WCatRefresh"); + + // Create new base record or read the existing one + if(data->fhix != -1) { + if(filelength(data->fhix) < sizeof(WCatBase)) { + data->base.recsize = sizeof(WCatIdx); + data->base.active = 0; + data->base.nextmsgno = 1; + lseekset(data->fhix, 0); + write(data->fhix, &data->base, sizeof(WCatBase)); + } + else { + lseekset(data->fhix, 0); + read(data->fhix, &data->base, sizeof(WCatBase)); + } + } + + long ixnum = (filelength(data->fhix)-(long)sizeof(WCatBase)) / (long)sizeof(WCatIdx); + + // Are there any msgs? + if(ixnum) { + + // Read the index file + data->idx = (WCatIdx*)throw_realloc(data->idx, (uint)(ixnum*sizeof(WCatIdx))); + lseekset(data->fhix, sizeof(WCatBase)); + read(data->fhix, data->idx, (uint)(ixnum*sizeof(WCatIdx))); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::raw_scan(int __keep_index, int __scanpm) { + + GFTRK("WCatRawScan"); + + WCatData* _was_data = data; + if(_was_data == NULL) { + data = wcatdata; + wide = wcatwide; + } + + // Load the lastread + dword _lastread = 0; + int _fh = ::sopen(AddPath(path(), ".lrd"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(_fh != -1) { + lseekset(_fh, wide->userno, sizeof(dword)); + read(_fh, &_lastread, sizeof(dword)); + ::close(_fh); + } + + // Open WildCat! files for scanning unless they are already open + if(NOT isopen) { + + data->idx = NULL; + data->base.recsize = 0; + data->base.active = 0; + data->base.nextmsgno = 0; + + // Open index file + data->fhix = ::sopen(AddPath(path(), ".ix"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD); + if(data->fhix != -1) { + + // Allocate index buffer and read from file + refresh(); + + // Close index file + ::close(data->fhix); + data->fhix = -1; + } + } + + register uint _active = 0; + register uint _lastread_reln = 0; + register ulong _lastreadfound = 0; + + if(data->base.active) { + + // (Re)allocate message index + if(__keep_index) + Msgn->Resize((uint)data->base.active); + + // Variables for the loop + register ulong _msgno; + register ulong* _msgndxptr = Msgn->tag; + register WCatIdx* _ixptr = data->idx; + register dword _totalmsgs = data->base.active; + register ulong _firstmsgno = _totalmsgs ? _ixptr->msgno : 0; + register ulong _lastmsgno = 0; + + // Fill message index + while(_active < _totalmsgs) { + + _active++; + _msgno = (_ixptr++)->msgno; + if(NOT _firstmsgno) + _firstmsgno = _msgno; + if(__keep_index) + *_msgndxptr++ = _msgno; + + // Get the lastread + if((_msgno >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = _msgno; + _lastread_reln = (uint)(_active - (_msgno != _lastread ? 1 : 0)); + } + + // Store last message number + _lastmsgno = _msgno; + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + } + + // Update area data + Msgn->SetCount(_active); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + // Scan for personal mail + if(__scanpm) { + // Not implemented yet + } + + // Free index buffer if just counting + if(NOT __keep_index OR __scanpm) + throw_release(data->idx); + + if(_was_data == NULL) { + data = NULL; + wide = NULL; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::scan() { + + GFTRK("WCatScan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::scan_area() { + + GFTRK("WCatScanArea"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::scan_area_pm() { + + GFTRK("WCatScanArea*M"); + + raw_scan(true, true); + Msgn->Reset(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmowcat3.cpp b/goldlib/gmb3/gmowcat3.cpp new file mode 100644 index 0000000..2e1a40b --- /dev/null +++ b/goldlib/gmb3/gmowcat3.cpp @@ -0,0 +1,219 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! 4.x messagebase engine. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +int WCatArea::load_message(int __mode, gmsg* __msg, WCatHdr& __hdr) { + + // Setup some local variables for speed + int _fhdat = data->fhdat; + WCatIdx* _idx = data->idx; + uint _reln = Msgn->ToReln(__msg->msgno); + + // Load the message header + memset(&__hdr, 0, sizeof(WCatHdr)); + lseekset(_fhdat, _idx[_reln-1].offset); + read(_fhdat, &__hdr, sizeof(WCatHdr)); + + // Convert header + + __msg->timesread = 1; + + __msg->link.to_set(__hdr.reference); + + struplow(strnp2cc(__msg->by, __hdr.from, 70)); + struplow(strnp2cc(__msg->to, __hdr.to, 70)); + strnp2cc(__msg->re, __hdr.subject, 70); + + strnp2cc(__msg->wildcat.from_title, __hdr.fromtitle, 10); + strnp2cc(__msg->wildcat.to_title, __hdr.totitle, 10); + strnp2cc(__msg->wildcat.network, __hdr.network, 8); + strnp2cc(__msg->wildcat.internal_attach, __hdr.internalattach, 12); + strnp2cc(__msg->wildcat.external_attach, __hdr.externalattach, 12); + + memcpy(__msg->wildcat.reserved, __hdr.reserved, 20); + + __msg->wildcat.from_userid = __hdr.fromuserid; + __msg->wildcat.to_userid = __hdr.touserid; + __msg->wildcat.next_unread = __hdr.nextunread; + __msg->wildcat.prev_unread = __hdr.prevunread; + + __msg->cost = (uint)__hdr.cost; + + __msg->orig.zone = __msg->oorig.zone = __hdr.origaddr.zone; + __msg->orig.net = __msg->oorig.net = __hdr.origaddr.net; + __msg->orig.node = __msg->oorig.node = __hdr.origaddr.node; + __msg->orig.point = __msg->oorig.point = __hdr.origaddr.point; + + __msg->dest.zone = __msg->odest.zone = __hdr.destaddr.zone; + __msg->dest.net = __msg->odest.net = __hdr.destaddr.net; + __msg->dest.node = __msg->odest.node = __hdr.destaddr.node; + __msg->dest.point = __msg->odest.point = __hdr.destaddr.point; + + // Convert date and time + struct tm _tm; + long _time; + unsigned _year, _month, _day, _hour, _minute, _second; + + __msg->written = __msg->arrived = __msg->received = 0; + + if(__hdr.msgdate AND __hdr.msgtime) { + JDN2YMD(__hdr.msgdate+1, &_year, &_month, &_day); + _time = __hdr.msgtime-1; + _hour = (unsigned)(_time / 3600L); + _minute = (unsigned)((_time % 3600L) / 60L); + _second = (unsigned)(_time - (((long)_hour*3600L)+(long)_minute*60L)); + _tm.tm_year = _year; + _tm.tm_mon = _month - 1; + _tm.tm_mday = _day; + _tm.tm_hour = _hour; + _tm.tm_min = _minute; + _tm.tm_sec = _second; + _tm.tm_isdst = -1; + time_t a = mktime(&_tm); + time_t b = mktime(gmtime(&a)); + __msg->written = a + a - b; + } + + if(__hdr.readdate AND __hdr.readtime) { + JDN2YMD(__hdr.readdate+1, &_year, &_month, &_day); + _time = __hdr.readtime-1; + _hour = (unsigned)(_time / 3600L); + _minute = (unsigned)((_time % 3600L) / 60L); + _second = (unsigned)(_time - (((long)_hour*3600L)+(long)_minute*60L)); + _tm.tm_year = _year; + _tm.tm_mon = _month - 1; + _tm.tm_mday = _day; + _tm.tm_hour = _hour; + _tm.tm_min = _minute; + _tm.tm_sec = _second; + _tm.tm_isdst = -1; + time_t a = mktime(&_tm); + time_t b = mktime(gmtime(&a)); + __msg->received = a + a - b; + } + + + // Convert fidoflag attributes + __msg->attr.pvt(__hdr.fidoflags & FIDO_PVT); + __msg->attr.cra(__hdr.fidoflags & FIDO_CRASH); + __msg->attr.rcv(__hdr.fidoflags & FIDO_RECEIVED); + __msg->attr.snt(__hdr.fidoflags & FIDO_SENT); + __msg->attr.att(__hdr.fidoflags & FIDO_ATTACH); + __msg->attr.trs(__hdr.fidoflags & FIDO_TRANSIT); + __msg->attr.orp(__hdr.fidoflags & FIDO_ORPHAN); + __msg->attr.k_s(__hdr.fidoflags & FIDO_KILLSENT); + __msg->attr.loc(__hdr.fidoflags & FIDO_LOCAL); + __msg->attr.hld(__hdr.fidoflags & FIDO_HOLD); + __msg->attr.rsv(__hdr.fidoflags & FIDO_RESERVED); + __msg->attr.frq(__hdr.fidoflags & FIDO_FREQ); + __msg->attr.rrq(__hdr.fidoflags & FIDO_RETRECREQ); + __msg->attr.rrc(__hdr.fidoflags & FIDO_RETREC); + __msg->attr.arq(__hdr.fidoflags & FIDO_AUDITREQ); + __msg->attr.urq(__hdr.fidoflags & FIDO_UPDREQ); + + // Convert mflag attributes + __msg->attr.pvt(__hdr.mflags & mfPrivate); + __msg->attr.rab(__hdr.mflags & mfReceiveable); + __msg->attr.rcv(__hdr.mflags & mfReceived); + __msg->attr.rrc(__hdr.mflags & mfReceipt); + __msg->attr.car(__hdr.mflags & mfCarboned); + __msg->attr.fwd(__hdr.mflags & mfForwarded); + __msg->attr.efl(__hdr.mflags & mfEchoFlag); + __msg->attr.hrp(__hdr.mflags & mfHasReplies); + __msg->attr.del(__hdr.mflags & mfDeleted); + __msg->attr.tag(__hdr.mflags & mfTagged); + __msg->attr.snt(__hdr.mflags & mfSent); + + // Set the unsent attribute + __msg->attr.uns(__msg->attr.loc() and not __msg->attr.snt()); + + __msg->txtlength = __hdr.msgbytes; + + // If message text is requested + if(__mode & GMSG_TXT) { + + uint _txtlen = __hdr.msgbytes; + if((_txtlen+256) > WideMsgSize) + _txtlen = (uint)WideMsgSize; + uint _alloclen = (uint)(_txtlen+256); + + // Get length of message text and adjust if necessary + // Allocate space for the message text + __msg->txt = (char*)throw_calloc(1, _alloclen); + + // Read the message text + read(_fhdat, __msg->txt, _txtlen); + + // Convert kludge char from NUL to CTRL-A + char* p = __msg->txt; + for(int n=0; n<_txtlen; n++,p++) { + if(!*p) + *p = CTRL_A; + } + } + + GFTRK(NULL); + + // Success + return true; +} + + +// ------------------------------------------------------------------ + +int WCatArea::load_hdr(gmsg* __msg) { + + GFTRK("WCatLoadHdr"); + + WCatHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int WCatArea::load_msg(gmsg* __msg) { + + GFTRK("WCatLoadMsg"); + + WCatHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmowcat4.cpp b/goldlib/gmb3/gmowcat4.cpp new file mode 100644 index 0000000..93423f5 --- /dev/null +++ b/goldlib/gmb3/gmowcat4.cpp @@ -0,0 +1,283 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! 4.x messagebase engine. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +void WCatArea::lock() { + + GFTRK("WCatLock"); + + if(NOT data->islocked) { + if(WideCanLock) { + long _tries = 0; + while(::lock(data->fhix, 0, 1) == -1) { + if(PopupLocked(++_tries, true, path()) == false) { + WideLog->ErrLock(); + raw_close(); + WideLog->printf("! A WildCat! msgbase file could not be locked."); + WideLog->printf(": %s.IX.", path()); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + } + if(_tries) + PopupLocked(0, 0, NULL); + } + refresh(); + data->islocked = true; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::unlock() { + + GFTRK("WCatUnlock"); + if(WideCanLock AND data->islocked) + ::unlock(data->fhix, 0, 1); + data->islocked = false; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::save_message(int __mode, gmsg* __msg, WCatHdr& __hdr) { + + int _was_locked = data->islocked; + if(NOT _was_locked) + lock(); + + memset(&__hdr, 0, sizeof(WCatHdr)); + + if(__mode & GMSG_NEW) { + data->base.active++; + __msg->msgno = data->base.nextmsgno++; + Msgn->Append(__msg->msgno); + data->idx = (WCatIdx*)throw_realloc(data->idx, data->base.active*sizeof(WCatIdx)); + __hdr.mflags |= mfReceiveable; + lseekset(data->fhix, 0); + write(data->fhix, &data->base, sizeof(WCatBase)); + } + else if(__mode & GMSG_DELETE) { + __hdr.mflags |= mfDeleted; + } + + __hdr.magicnumber = MagicHeaderActive; + __hdr.msgno = (word)__msg->msgno; + + strc2p(strupr(strxcpy(__hdr.from, __msg->by, sizeof(__hdr.from)))); + strc2p(strcpy(__hdr.fromtitle, __msg->wildcat.from_title)); + __hdr.fromuserid = __msg->wildcat.from_userid; + + strc2p(strupr(strxcpy(__hdr.to, __msg->to, sizeof(__hdr.to)))); + strc2p(strcpy(__hdr.totitle, __msg->wildcat.to_title)); + __hdr.touserid = __msg->wildcat.to_userid; + + strc2p(strxcpy(__hdr.subject, __msg->re, sizeof(__hdr.subject))); + + if(!*__msg->wildcat.network AND (isnet() OR isecho())) + strcpy(__msg->wildcat.network, "FTSC"); + strc2p(strcpy(__hdr.network, __msg->wildcat.network)); + + if(__msg->written) { + struct tm* _tm = gmtime(&__msg->written); + int _year = _tm->tm_year % 100; + __hdr.msgdate = (word)(YMD2JDN(1900+_year, _tm->tm_mon+1, _tm->tm_mday)-1); + __hdr.msgtime = (((long)_tm->tm_hour*3600L)+((long)_tm->tm_min*60L)+_tm->tm_sec)+1; + } + + if(__msg->received) { + struct tm* _tm = gmtime(&__msg->received); + int _year = _tm->tm_year % 100; + __hdr.readdate = (word)YMD2JDN(1900+_year, _tm->tm_mon+1, _tm->tm_mday); + __hdr.readtime = (((long)_tm->tm_hour*3600L)+((long)_tm->tm_min*60L)+_tm->tm_sec)+1; + } + + __hdr.mflags |= (word)(__msg->attr.pvt() ? mfPrivate : 0); + __hdr.mflags |= (word)(__msg->attr.rab() ? mfReceiveable : 0); + __hdr.mflags |= (word)(__msg->attr.rcv() ? mfReceived : 0); + __hdr.mflags |= (word)(__msg->attr.rrc() ? mfReceipt : 0); + __hdr.mflags |= (word)(__msg->attr.car() ? mfCarboned : 0); + __hdr.mflags |= (word)(__msg->attr.fwd() ? mfForwarded : 0); + __hdr.mflags |= (word)(__msg->attr.efl() ? mfEchoFlag : 0); + __hdr.mflags |= (word)(__msg->attr.hrp() ? mfHasReplies : 0); + __hdr.mflags |= (word)(__msg->attr.del() ? mfDeleted : 0); + __hdr.mflags |= (word)(__msg->attr.tag() ? mfTagged : 0); + __hdr.mflags |= (word)(__msg->attr.snt() ? mfSent : 0); + if(__msg->link.first()) + __hdr.mflags |= mfHasReplies; + + __hdr.reference = (word)__msg->link.to(); + + __hdr.origaddr = __msg->orig; + __hdr.destaddr = __msg->dest; + + __hdr.msgbytes = (word)__msg->txtlength; + + strc2p(strcpy(__hdr.internalattach, __msg->wildcat.internal_attach)); + strc2p(strcpy(__hdr.externalattach, __msg->wildcat.external_attach)); + + __hdr.prevunread = (word)__msg->wildcat.prev_unread; + __hdr.nextunread = (word)__msg->wildcat.next_unread; + + __hdr.fidoflags |= (word)(__msg->attr.pvt() ? FIDO_PVT : 0); + __hdr.fidoflags |= (word)(__msg->attr.cra() ? FIDO_CRASH : 0); + __hdr.fidoflags |= (word)(__msg->attr.rcv() ? FIDO_RECEIVED : 0); + __hdr.fidoflags |= (word)(__msg->attr.snt() ? FIDO_SENT : 0); + __hdr.fidoflags |= (word)(__msg->attr.att() ? FIDO_ATTACH : 0); + __hdr.fidoflags |= (word)(__msg->attr.trs() ? FIDO_TRANSIT : 0); + __hdr.fidoflags |= (word)(__msg->attr.orp() ? FIDO_ORPHAN : 0); + __hdr.fidoflags |= (word)(__msg->attr.k_s() ? FIDO_KILLSENT : 0); + __hdr.fidoflags |= (word)(__msg->attr.loc() ? FIDO_LOCAL : 0); + __hdr.fidoflags |= (word)(__msg->attr.hld() ? FIDO_HOLD : 0); + __hdr.fidoflags |= (word)(__msg->attr.rsv() ? FIDO_RESERVED : 0); + __hdr.fidoflags |= (word)(__msg->attr.frq() ? FIDO_FREQ : 0); + __hdr.fidoflags |= (word)(__msg->attr.rrq() ? FIDO_RETRECREQ : 0); + __hdr.fidoflags |= (word)(__msg->attr.rrc() ? FIDO_RETREC : 0); + __hdr.fidoflags |= (word)(__msg->attr.arq() ? FIDO_AUDITREQ : 0); + __hdr.fidoflags |= (word)(__msg->attr.urq() ? FIDO_UPDREQ : 0); + + __hdr.cost = __msg->cost; + + memcpy(__hdr.reserved, __msg->wildcat.reserved, 20); + + char* _txt = NULL; + uint _reln = Msgn->ToReln(__msg->msgno)-1; + long _datstart = data->idx[_reln].offset; + + if(__mode & GMSG_TXT) { + + _txt = throw_strdup(__msg->txt); + word _size = (word)strlen(_txt); + __hdr.msgbytes = _size; + word n = 0; + char* ptr = _txt; + while(n < _size) { + if(*ptr == CTRL_A) + *ptr = NUL; + ptr++; + n++; + } + + if((__mode & GMSG_NEW) OR (_size > __hdr.msgbytes)) { + if(_size > __hdr.msgbytes) { + ulong _magic = MagicHeaderInactive; + lseekset(data->fhdat, data->idx[_reln].offset); + write(data->fhdat, &_magic, 4); + } + _datstart = filelength(data->fhdat); + data->idx[_reln].msgno = __hdr.msgno; + data->idx[_reln].offset = _datstart; + lseekset(data->fhix, sizeof(WCatBase)+((long)_reln*sizeof(WCatIdx))); + write(data->fhix, &data->idx[_reln], sizeof(WCatIdx)); + } + __hdr.msgbytes = _size; + } + + lseekset(data->fhdat, _datstart); + write(data->fhdat, &__hdr, sizeof(WCatHdr)); + if(_txt) { + write(data->fhdat, _txt, __hdr.msgbytes); + throw_free(_txt); + } + + if(NOT _was_locked) + unlock(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("WCatSaveHdr"); + + WCatHdr _hdr; + save_message(__mode|GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void WCatArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("WCatSaveMsg"); + + WCatHdr _hdr; + save_message(__mode|GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void WCatArea::del_msg(gmsg* __msg) { + + GFTRK("WCatDelMsg"); + + WCatHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void WCatArea::new_msgno(gmsg* __msg) { + + GFTRK("WCatNewMsgno"); + + __msg->msgno = data->base.nextmsgno; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void WCatArea::update_timesread(gmsg*) { + +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmowcat5.cpp b/goldlib/gmb3/gmowcat5.cpp new file mode 100644 index 0000000..0f074d5 --- /dev/null +++ b/goldlib/gmb3/gmowcat5.cpp @@ -0,0 +1,126 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// WildCat! 4.x messagebase engine. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +char* WCatArea::user_lookup(char* __lookfor) { + + NW(__lookfor); + return NULL; +} + + +// ------------------------------------------------------------------ + +int WCatArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ +// Hexdump the current message header + +Line* WCatArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) { + + GFTRK("WCatMakeDump"); + + WCatHdr _hdr; + load_message(GMSG_HDRTXT, msg, _hdr); + + char buf[100]; + Line* line = lin = + AddLine (NULL, "Hexdump of WildCat! message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Path : %s", path()); + AddLineF(line, "MagicNumber: %08lXh", _hdr.magicnumber); + AddLineF(line, "MsgNumber : %u", _hdr.msgno); + AddLineF(line, "Orig : %s", STRNP2C(_hdr.from)); + AddLineF(line, "OrigTitle : %s", STRNP2C(_hdr.fromtitle)); + AddLineF(line, "OrigUserID : %li", _hdr.fromuserid); + AddLineF(line, "Dest : %s", STRNP2C(_hdr.to)); + AddLineF(line, "DestTitle : %s", STRNP2C(_hdr.totitle)); + AddLineF(line, "DestUserID : %li", _hdr.touserid); + AddLineF(line, "Subject : %s", STRNP2C(_hdr.subject)); + AddLineF(line, "Network : %s", STRNP2C(_hdr.network)); + AddLineF(line, "MsgTime : %s (%u, %li)", strftimei(buf, 100, "%d %b %y %H:%M:%S", gmtime(&msg->written)), _hdr.msgdate, _hdr.msgtime); + AddLineF(line, "ReadTime : %s (%u, %li)", strftimei(buf, 100, "%d %b %y %H:%M:%S", gmtime(&msg->received)), _hdr.readdate, _hdr.readtime); + AddLineF(line, "mFlags : %u (%04Xh)", _hdr.mflags, _hdr.mflags); + AddLineF(line, "Reference : %u", _hdr.reference); + AddLineF(line, "FidoFrom : %u:%u/%u.%u", _hdr.origaddr.zone, _hdr.origaddr.net, _hdr.origaddr.node, _hdr.origaddr.point); + AddLineF(line, "FidoTo : %u:%u/%u.%u", _hdr.origaddr.zone, _hdr.destaddr.net, _hdr.destaddr.node, _hdr.destaddr.point); + AddLineF(line, "MsgBytes : %u", _hdr.msgbytes); + AddLineF(line, "Int.Attach : %s", STRNP2C(_hdr.internalattach)); + AddLineF(line, "Ext.Attach : %s", STRNP2C(_hdr.externalattach)); + AddLineF(line, "PrevUnread : %u", _hdr.prevunread); + AddLineF(line, "NextUnread : %u", _hdr.nextunread); + AddLineF(line, "FidoFlags : %u (%04Xh)", _hdr.fidoflags, _hdr.fidoflags); + AddLineF(line, "Cost : %li", _hdr.cost); + AddLineF(line, "Reserved : %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", + _hdr.reserved[0], _hdr.reserved[1], _hdr.reserved[2], + _hdr.reserved[3], _hdr.reserved[4], _hdr.reserved[5], + _hdr.reserved[6], _hdr.reserved[7], _hdr.reserved[8], + _hdr.reserved[9], _hdr.reserved[10], _hdr.reserved[11], + _hdr.reserved[12], _hdr.reserved[13], _hdr.reserved[14], + _hdr.reserved[15], _hdr.reserved[16], _hdr.reserved[17], + _hdr.reserved[18], _hdr.reserved[19] + ); + line = AddLine(line, ""); + AddLineF(line, "UserRecno : %u (%s)", wide->userno, WideUsername[0]); + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + int _count; + char* _ptr = (char*)&_hdr; + for(_count=0; _count +#include + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack(1) +#endif + + +// ------------------------------------------------------------------ +// Bitmaps for the header.fflags + +#define FFLAGS_MSGPRIVATE 0x0001 // private message, +#define FFLAGS_MSGCRASH 0x0002 // accept for forwarding +#define FFLAGS_MSGREAD 0x0004 // read by addressee +#define FFLAGS_MSGSENT 0x0008 // sent OK (remote) +#define FFLAGS_MSGFILE 0x0010 // file attached to msg +#define FFLAGS_MSGFWD 0x0020 // being forwarded +#define FFLAGS_MSGORPHAN 0x0040 // unknown dest node +#define FFLAGS_MSGKILL 0x0080 // kill after mailing +#define FFLAGS_MSGLOCAL 0x0100 // FidoNet vs. local +#define FFLAGS_MSGXX1 0x0200 // +#define FFLAGS_MSGXX2 0x0400 // STRIPPED by FidoNet +#define FFLAGS_MSGFRQ 0x0800 // file request +#define FFLAGS_MSGRRQ 0x1000 // receipt requested +#define FFLAGS_MSGCPT 0x2000 // is a return receipt +#define FFLAGS_MSGARQ 0x4000 // audit trail requested +#define FFLAGS_MSGURQ 0x8000 // update request + + +// ------------------------------------------------------------------ +// Bitmaps for the header.xflags + +#define XFLAGS_MSGDELETED 0x0001 // deleted message, +#define XFLAGS_MSGANON 0x0002 // anonymous message +#define XFLAGS_MSGECHO 0x0004 // unmoved echo message +#define XFLAGS_MSGNET 0x0008 // unmoved net message + +#define XFLAGS_MSGHOLD 0x0010 // file attached to msg +#define XFLAGS_MSGHOST 0x0020 // being forwarded +#define XFLAGS_MSGSCANNED 0x0040 // Fidonet scanned +#define XFLAGS_MSGKEEP 0x0080 // don't delete + +#define XFLAGS_MSGTREATED 0x0100 // soft cr's & lf's removed +#define XFLAGS_MSGPACKED 0x0200 // message LZSS compressed +#define XFLAGS_MSGGSCAN 0x0400 // GroupMail scanned +#define XFLAGS_MSGRSCAN 0x0800 // rfc0822 scanned + +#define XFLAGS_MSGARCHIVED 0x4000 // Message stored +#define XFLAGS_MSGTAGGED 0x8000 // used by offline readers + + +// ------------------------------------------------------------------ +// AdeptXBBS Message Header (*.Data) + +struct XbbsHdr { + char majorversion; // Minor revision number of this message style + char minorversion; // Minor revision number of this message style + ushort structlen; // The length of this data structure + char from[60]; // Who the message is from + char to[60]; // Who the message is to + char subj[70]; // The subject of the message + char date[35]; // Date the message was written + char indate[4]; // Import date + ulong msgnum; // Current message number + ulong timesread; // Number of times the message has been read + time_t timerecv; // Time user received this message + ulong length; // Length of message stored in .Text Data file + long start; // Pointer to starting byte in .Text Data file + ulong extra1; // Extra space // Was going to be for reply + ulong extra2; // Extra space // linking instead came up with + ulong extra3; // Extra space // a better method + Addr origaddr; // Messages origin + Addr destaddr; // Messages destination + ushort cost; // Cost to send this message + ushort fflags; // Fidonet related flags + ushort xflags; // XBBS related flags + ulong iflags; // Internet related flags + ulong oflags; // Other network related flags +}; + + +// ------------------------------------------------------------------ +// AdeptXBBS Message Index (*.Index) + +struct XbbsIdx { + ushort to; // Checksum of the to field + ushort from; // Checksum of the from field + ushort subj; // Checksum of the subject field + ulong msgidcrc; // MSGID 32-bit CRC of address field (starting value 0xFFFFFFFF) + ulong msgidserialno; // MSGID Serial number field + ulong replycrc; // REPLY 32-bit CRC of address field (starting value 0xFFFFFFFF) + ulong replyserialno; // REPLY Serial number field +}; + + +// ------------------------------------------------------------------ +// AdeptXBBS Personal Mail Index + +struct XbbsPmi { + long areanumber; + long msgnumber; + char from[60]; + char subject[70]; + char date[20]; +}; + + +// ------------------------------------------------------------------ + +#if defined(GOLD_CANPACK) +#pragma pack() +#endif + + +// ------------------------------------------------------------------ + +struct XbbsData { + int fhdata; + int fhindex; + int fhlmr; + int fhtext; + int islocked; + XbbsIdx* idx; + uint idx_size; +}; + + +// ------------------------------------------------------------------ + +struct XbbsWide { + int fhpmi; + int userno; + XbbsUser* user; + XbbsPmi* pmi; + int isopen; + const char* path; +}; + + +// ------------------------------------------------------------------ + +class XbbsArea : public gmo_area { + +protected: + + XbbsWide* wide; + XbbsData* data; + + void data_open(); + void data_close(); + + void raw_open(); + void raw_close(); + void refresh(); + int load_message(int __mode, gmsg* __msg, XbbsHdr& __hdr); + + void lock_file(int handle, long position, long length); + void unlock_file(int handle, long position, long length); + + int test_open(const char* __file, int sharemode=-1); + void save_lastread(); + void raw_scan(int __keep_index, int __scanpm=false); + void save_message(int __mode, gmsg* __msg, XbbsHdr& __hdr); + + void update_personal_mail(gmsg* __msg, XbbsHdr& __hdr, int __status); + +public: + + XbbsArea() { wide = NULL; data = NULL; } + virtual ~XbbsArea() {} + + // ---------------------------------------------------------------- + // Messagebase member functions + + void open(); + void close(); + + void suspend(); + void resume(); + + void lock(); + void unlock(); + + void scan(); + void scan_area(); + void scan_area_pm(); + + int load_hdr(gmsg* msg); + int load_msg(gmsg* msg); + + void save_hdr(int mode, gmsg* msg); + void save_msg(int mode, gmsg* msg); + + void del_msg(gmsg* msg); + + void new_msgno(gmsg* msg); + char* user_lookup(char* lookfor); + int renumber(); + + void update_timesread(gmsg* msg); + + Line* make_dump_msg(Line*& lin, gmsg* msg, char* lng_head); +}; + + +// ------------------------------------------------------------------ + +extern XbbsWide* xbbswide; +extern XbbsData* xbbsdata; +extern int xbbsdatano; + + +// ------------------------------------------------------------------ + +#if not defined(__OS2__) +inline void XbbsArea::open() { } +inline void XbbsArea::save_lastread() { } +inline void XbbsArea::close() { } +inline void XbbsArea::suspend() { } +inline void XbbsArea::resume() { } +inline void XbbsArea::scan() { } +inline void XbbsArea::scan_area() { } +inline void XbbsArea::scan_area_pm() { } +inline int XbbsArea::load_message(int, gmsg*, XbbsHdr&) { return false; } +inline int XbbsArea::load_hdr(gmsg*) { return false; } +inline int XbbsArea::load_msg(gmsg*) { return false; } +inline void XbbsArea::lock() { } +inline void XbbsArea::unlock() { } +inline void XbbsArea::save_message(int, gmsg*, XbbsHdr&) { } +inline void XbbsArea::save_hdr(int, gmsg*) { } +inline void XbbsArea::save_msg(int, gmsg*) { } +inline void XbbsArea::del_msg(gmsg*) { } +inline void XbbsArea::new_msgno(gmsg*) { } +inline char* XbbsArea::user_lookup(char*) { return NULL; } +inline int XbbsArea::renumber() { return false; } +inline void XbbsArea::update_timesread(gmsg*) { } +inline Line* XbbsArea::make_dump_msg(Line*&, gmsg*, char* lng_head) { return NULL; } +#endif + + +// ------------------------------------------------------------------ + +#endif + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmoxbbs1.cpp b/goldlib/gmb3/gmoxbbs1.cpp new file mode 100644 index 0000000..8915755 --- /dev/null +++ b/goldlib/gmb3/gmoxbbs1.cpp @@ -0,0 +1,280 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS messagebase engine. +// ------------------------------------------------------------------ + +#include +#include +#include +#include + + +// ------------------------------------------------------------------ + +XbbsWide* xbbswide = NULL; +XbbsData* xbbsdata = NULL; +int xbbsdatano = 0; + + +// ------------------------------------------------------------------ + +void XbbsArea::data_open() { + + wide = xbbswide; + data = xbbsdata + (xbbsdatano++); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::data_close() { + + xbbsdatano--; +} + + +// ------------------------------------------------------------------ + +void XbbsArea::raw_close() { + + GFTRK("XbbsRawClose"); + + if(data->fhdata != -1) ::close(data->fhdata); data->fhdata = -1; + if(data->fhindex != -1) ::close(data->fhindex); data->fhindex = -1; + if(data->fhtext != -1) ::close(data->fhtext); data->fhtext = -1; + + if(wide->isopen) { + if(wide->isopen == 1) { + if(wide->user->fh != -1) { + ::close(wide->user->fh); + wide->user->fh= -1; + } + } + wide->isopen--; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +int XbbsArea::test_open(const char* __file, int sharemode) { + + GFTRK("XbbsTestOpen"); + + int _fh; + long _tries = 0; + if(sharemode == -1) + sharemode = WideSharemode; + + do { + + _fh = ::sopen(__file, O_RDWR|O_BINARY|O_CREAT, sharemode, S_STDRW); + if(_fh == -1) { + + // Tell the world + if(PopupLocked(++_tries, false, __file) == false) { + + // User requested to exit + WideLog->ErrOpen(); + raw_close(); + WideLog->printf("! An AdeptXBBS msgbase file could not be opened."); + WideLog->printf(": %s.", __file); + WideLog->ErrOSInfo(); + OpenErrorExit(); + } + } + } while(_fh == -1); + + // Remove the popup window + if(_tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); + + return _fh; +} + + +// ------------------------------------------------------------------ + +void XbbsArea::raw_open() { + + GFTRK("XbbsRawOpen"); + + data->fhdata = test_open(AddPath(path(), ".Data")); + data->fhindex = test_open(AddPath(path(), ".Index")); + data->fhtext = test_open(AddPath(path(), ".Text")); + wide->isopen++; + if(wide->isopen == 1) + wide->user->fh = ::sopen(AddPath(wide->path, "Users"), O_RDONLY|O_BINARY, WideSharemode); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsExit() { + + if(xbbswide) + delete xbbswide->user; + throw_release(xbbswide); + throw_release(xbbsdata); +} + + +// ------------------------------------------------------------------ + +void XbbsInit(const char* path, int userno) { + + xbbsdata = (XbbsData*)throw_calloc(2, sizeof(XbbsData)); + xbbswide = (XbbsWide*)throw_calloc(1, sizeof(XbbsWide)); + + xbbswide->path = path; + xbbswide->userno = userno; + + xbbswide->user = new XbbsUser; + throw_new(xbbswide->user); + + xbbswide->user->fh = -1; + xbbswide->fhpmi = -1; + xbbswide->pmi = NULL; + xbbswide->isopen = 0; + + const char* _username = WideUsername[0]; + if(xbbswide->userno == -1) { + xbbswide->user->fh = ::sopen(AddPath(xbbswide->path, "Users"), O_RDONLY|O_BINARY, WideSharemode); + if(xbbswide->user->fh != -1) { + xbbswide->user->find(_username); + if(NOT xbbswide->user->found) { + xbbswide->userno = 0; + //WideLog->printf("* User \"%s\" not found in %sUsers.", _username, xbbswide->path); + //xbbswide->user->add(_username); + //WideLog->printf("* Now added with user number %u.", xbbswide->user->index); + } + close(xbbswide->user->fh); + } + xbbswide->userno = xbbswide->user->index; + } +} + + +// ------------------------------------------------------------------ + +void XbbsArea::open() { + + GFTRK("XbbsOpen"); + + isopen++; + if(isopen > 2) { + WideLog->ErrTest(); + WideLog->printf("! Trying to open an AdeptXBBS msgbase more than twice."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + if(isopen == 1) { + data_open(); + raw_open(); + refresh(); + scan(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::save_lastread() { + + GFTRK("XbbsSaveLastread"); + + int _fh = ::sopen(AddPath(path(), ".lmr"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW); + if(_fh != -1) { + ulong _lastread = Msgn->CvtReln(lastread); + lseekset(_fh, wide->userno+1, sizeof(ulong)); + write(_fh, &_lastread, sizeof(ulong)); + ::close(_fh); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::close() { + + GFTRK("XbbsClose"); + + if(isopen) { + if(isopen == 1) { + save_lastread(); + raw_close(); + Msgn->Reset(); + throw_release(data->idx); + data_close(); + } + isopen--; + } + else { + WideLog->ErrTest(); + WideLog->printf("! Trying to close an already closed AdeptXBBS msgbase."); + WideLog->printf(": %s, %s.", echoid(), path()); + WideLog->printf("+ Info: This indicates a potentially serious bug."); + WideLog->printf("+ Advice: Report to the Author immediately."); + TestErrorExit(); + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::suspend() { + + GFTRK("XbbsSuspend"); + + save_lastread(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::resume() { + + GFTRK("XbbsResume"); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmoxbbs2.cpp b/goldlib/gmb3/gmoxbbs2.cpp new file mode 100644 index 0000000..92eb02b --- /dev/null +++ b/goldlib/gmb3/gmoxbbs2.cpp @@ -0,0 +1,227 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS messagebase engine. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +void XbbsArea::refresh() { + + GFTRK("XbbsRefresh"); + + long indexnum = filelength(data->fhindex) / (long)sizeof(XbbsIdx); + + // Are there any msgs? + if(indexnum) { + + // Read the index file + data->idx = (XbbsIdx*)throw_realloc(data->idx, (uint)(indexnum*sizeof(XbbsIdx))); + lseekset(data->fhindex, 0); + read(data->fhindex, data->idx, (uint)(indexnum*sizeof(XbbsIdx))); + } + + data->idx_size = (uint)indexnum; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsWideOpen() { + + GFTRK("XbbsWideOpen"); + + // Open the personal mail index + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsWideClose() { + + GFTRK("XbbsWideClose"); + + // Close the personal mail index + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::raw_scan(int __keep_index, int __scanpm) { + + GFTRK("XbbsRawScan"); + + XbbsData* _was_data = data; + if(_was_data == NULL) { + data = xbbsdata; + wide = xbbswide; + } + + // Load the lastread + ulong _lastread = 0; + int _fh = ::sopen(AddPath(path(), ".lmr"), O_RDONLY|O_BINARY, WideSharemode); + if(_fh != -1) { + lseekset(_fh, wide->userno+1, sizeof(ulong)); + read(_fh, &_lastread, sizeof(ulong)); + ::close(_fh); + } + + // Open AdeptXBBS files for scanning unless they are already open + if(NOT isopen) { + + data->idx = NULL; + data->idx_size = 0; + + // Open index file + data->fhindex = ::sopen(AddPath(path(), ".Index"), O_RDONLY|O_BINARY, WideSharemode); + if(data->fhindex != -1) { + + // Allocate index buffer and read from file + refresh(); + + // Close index file + ::close(data->fhindex); + data->fhindex = -1; + } + } + + register uint _active = 0; + register uint _lastread_reln = 0; + register ulong _lastreadfound = 0; + + if(data->idx_size) { + + // (Re)allocate message index + if(__keep_index) + Msgn->Resize(data->idx_size); + + // Variables for the loop + register ulong _msgno; + register ulong* _msgndxptr = Msgn->tag; + register dword _totalmsgs = data->idx_size; + register ulong _firstmsgno = _totalmsgs ? 1 : 0; + register ulong _lastmsgno = 0; + + // Fill message index + while(_active < _totalmsgs) { + + _active++; + _msgno = _active; + if(NOT _firstmsgno) + _firstmsgno = _msgno; + if(__keep_index) + *_msgndxptr++ = _msgno; + + // Get the lastread + if((_msgno >= _lastread) AND (_lastread_reln == 0)) { + _lastreadfound = _msgno; + _lastread_reln = (uint)(_active - (_msgno != _lastread ? 1 : 0)); + } + + // Store last message number + _lastmsgno = _msgno; + } + + // If the exact lastread was not found + if(_active AND (_lastreadfound != _lastread)) { + + // Higher than highest or lower than lowest? + if(_lastread > _lastmsgno) + _lastread_reln = _active; + else if(_lastread < _firstmsgno) + _lastread_reln = 0; + } + } + + // Update area data + Msgn->SetCount(_active); + lastread = _lastread_reln; + lastreadentry = _lastreadfound; + + // Scan for personal mail + if(__scanpm) { + // Not implemented yet + } + + // Free index buffer if just counting + if(NOT __keep_index OR __scanpm) + throw_release(data->idx); + + if(_was_data == NULL) { + data = NULL; + wide = NULL; + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::scan() { + + GFTRK("XbbsScan"); + + raw_scan(true); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::scan_area() { + + GFTRK("XbbsScanArea"); + + raw_scan(false); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::scan_area_pm() { + + GFTRK("XbbsScanArea*M"); + + raw_scan(true, true); + Msgn->Reset(); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ diff --git a/goldlib/gmb3/gmoxbbs3.cpp b/goldlib/gmb3/gmoxbbs3.cpp new file mode 100644 index 0000000..8cdf6b2 --- /dev/null +++ b/goldlib/gmb3/gmoxbbs3.cpp @@ -0,0 +1,177 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS messagebase engine. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +int XbbsArea::load_message(int __mode, gmsg* __msg, XbbsHdr& __hdr) { + + // Setup some local variables for speed + int _fhdata = data->fhdata; + uint _reln = Msgn->ToReln(__msg->msgno); + + // Load the message header + memset(&__hdr, 0, sizeof(XbbsHdr)); + lseekset(_fhdata, (long)(_reln-1)*(long)sizeof(XbbsHdr)); + read(_fhdata, &__hdr, sizeof(XbbsHdr)); + + // Convert header + + strcpy(__msg->by, __hdr.from); + strcpy(__msg->to, __hdr.to); + strcpy(__msg->re, __hdr.subj); + + __msg->orig.zone = __msg->oorig.zone = __hdr.origaddr.zone; + __msg->orig.net = __msg->oorig.net = __hdr.origaddr.net; + __msg->orig.node = __msg->oorig.node = __hdr.origaddr.node; + __msg->orig.point = __msg->oorig.point = __hdr.origaddr.point; + + __msg->dest.zone = __msg->odest.zone = __hdr.destaddr.zone; + __msg->dest.net = __msg->odest.net = __hdr.destaddr.net; + __msg->dest.node = __msg->odest.node = __hdr.destaddr.node; + __msg->dest.point = __msg->odest.point = __hdr.destaddr.point; + + __msg->written = FidoTimeToUnix(__hdr.date); + __msg->received = __hdr.timerecv; + if(__hdr.indate[2]) { + struct tm t; + t.tm_year = __hdr.indate[0]+89; + t.tm_mon = __hdr.indate[1]-1; + t.tm_mday = __hdr.indate[2]; + t.tm_hour = t.tm_min = t.tm_sec = 0; + t.tm_isdst = -1; + time_t a = mktime(&t); + time_t b = mktime(gmtime(&a)); + __msg->arrived = a + a - b; + } + + __msg->cost = __hdr.cost; + __msg->timesread = __hdr.timesread; + + __msg->txtstart = __hdr.start; + __msg->txtlength = __hdr.length; + + // Convert fflag attributes + __msg->attr.pvt(__hdr.fflags & FFLAGS_MSGPRIVATE); + __msg->attr.cra(__hdr.fflags & FFLAGS_MSGCRASH); + __msg->attr.rcv(__hdr.fflags & FFLAGS_MSGREAD); + __msg->attr.snt(__hdr.fflags & FFLAGS_MSGSENT); + __msg->attr.att(__hdr.fflags & FFLAGS_MSGFILE); + __msg->attr.trs(__hdr.fflags & FFLAGS_MSGFWD); + __msg->attr.orp(__hdr.fflags & FFLAGS_MSGORPHAN); + __msg->attr.k_s(__hdr.fflags & FFLAGS_MSGKILL); + __msg->attr.loc(__hdr.fflags & FFLAGS_MSGLOCAL); + __msg->attr.frq(__hdr.fflags & FFLAGS_MSGFRQ); + __msg->attr.rrq(__hdr.fflags & FFLAGS_MSGRRQ); + __msg->attr.rrc(__hdr.fflags & FFLAGS_MSGCPT); + __msg->attr.arq(__hdr.fflags & FFLAGS_MSGARQ); + __msg->attr.urq(__hdr.fflags & FFLAGS_MSGURQ); + + // Convert xflag attributes + __msg->attr.del(__hdr.xflags & XFLAGS_MSGDELETED); + __msg->attr.ano(__hdr.xflags & XFLAGS_MSGANON); + __msg->attr.ume(__hdr.xflags & XFLAGS_MSGECHO); + __msg->attr.umn(__hdr.xflags & XFLAGS_MSGNET); + __msg->attr.fsc(__hdr.xflags & XFLAGS_MSGSCANNED); + __msg->attr.lok(__hdr.xflags & XFLAGS_MSGKEEP); + __msg->attr.trt(__hdr.xflags & XFLAGS_MSGTREATED); + __msg->attr.lzs(__hdr.xflags & XFLAGS_MSGPACKED); + __msg->attr.gsc(__hdr.xflags & XFLAGS_MSGGSCAN); + __msg->attr.rsc(__hdr.xflags & XFLAGS_MSGRSCAN); + __msg->attr.arc(__hdr.xflags & XFLAGS_MSGARCHIVED); + __msg->attr.tag(__hdr.xflags & XFLAGS_MSGTAGGED); + + // Set the unsent attribute + #if 0 + if(isnet()) + __msg->attr.uns((__msg->attr.loc() AND NOT __msg->attr.snt()) OR (__hdr.xflags & XFLAGS_MSGNET)); + else + __msg->attr.uns(__hdr.xflags & XFLAGS_MSGECHO); + #endif + + if(isnet() OR isecho()) + __msg->attr.uns(NOT(__hdr.xflags & XFLAGS_MSGSCANNED)); + + __msg->adeptxbbs.iflags = __hdr.iflags; + __msg->adeptxbbs.oflags = __hdr.oflags; + + // If message text is requested + if(__mode & GMSG_TXT) { + + uint _txtlen = __hdr.length; + if((_txtlen+256) > WideMsgSize) + _txtlen = WideMsgSize; + uint _alloclen = (uint)(_txtlen+256); + + // Get length of message text and adjust if necessary + // Allocate space for the message text + __msg->txt = (char*)throw_calloc(1, _alloclen); + + // Read the message text + lseekset(data->fhtext, __hdr.start); + read(data->fhtext, __msg->txt, _txtlen); + } + + GFTRK(NULL); + + // Success + return true; +} + + +// ------------------------------------------------------------------ + +int XbbsArea::load_hdr(gmsg* __msg) { + + GFTRK("XbbsLoadHdr"); + + XbbsHdr _hdr; + return load_message(GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +int XbbsArea::load_msg(gmsg* __msg) { + + GFTRK("XbbsLoadMsg"); + + XbbsHdr _hdr; + return load_message(GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoxbbs4.cpp b/goldlib/gmb3/gmoxbbs4.cpp new file mode 100644 index 0000000..07361c6 --- /dev/null +++ b/goldlib/gmb3/gmoxbbs4.cpp @@ -0,0 +1,419 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS messagebase engine. +// ------------------------------------------------------------------ + + +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include + +#include + + +// ------------------------------------------------------------------ + +void XbbsArea::lock() { + + // Not applicable in AdeptXBBS +} + + +// ------------------------------------------------------------------ + +void XbbsArea::unlock() { + + // Not applicable in AdeptXBBS +} + + +// ------------------------------------------------------------------ + +void XbbsArea::lock_file(int handle, long position, long length) { + + GFTRK("XbbsLockFile"); + + long tries = 0; + while(::lock(handle, position, length) == -1) { + if(PopupLocked(++tries, true, path()) == false) { + WideLog->ErrLock(); + raw_close(); + Path file; + strcpy(file, path()); + if(handle == data->fhdata) + strcat(file, ".Data"); + else if(handle == data->fhtext) + strcat(file, ".Text"); + else if(handle == data->fhindex) + strcat(file, ".Index"); + else if(handle == wide->fhpmi) + sprintf(file, "%sPersonal_Mail\\%s", wide->path, WideUsername[0]); + WideLog->printf("! An AdeptXBBS msgbase file could not be locked."); + WideLog->printf(": %s.", file); + WideLog->ErrOSInfo(); + LockErrorExit(); + } + } + if(tries) + PopupLocked(0, 0, NULL); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::unlock_file(int handle, long position, long length) { + + GFTRK("XbbsUnlockFile"); + + ::unlock(handle, position, length); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +ushort XbbsCheckSum(char* str) { + + ushort checksum = 0; + + while(*str) { + checksum ^= (ushort)toupper(*str++); + if(checksum & 1) + checksum = (ushort)((checksum >> 1) ^ 0xA000); + else + checksum >>= 1; + } + + return checksum; +} + + +// ------------------------------------------------------------------ + +void XbbsArea::save_message(int __mode, gmsg* __msg, XbbsHdr& __hdr) { + + // Reset header + memset(&__hdr, 0, sizeof(XbbsHdr)); + + if(__mode & GMSG_NEW) { + data->idx_size++; + __msg->msgno = data->idx_size; + Msgn->Append(__msg->msgno); + data->idx = (XbbsIdx*)throw_realloc(data->idx, data->idx_size*sizeof(XbbsIdx)); + } + + strxcpy(__hdr.from, __msg->by, sizeof(__hdr.from)); + strxcpy(__hdr.to, __msg->to, sizeof(__hdr.to)); + strxcpy(__hdr.subj, __msg->re, sizeof(__hdr.subj)); + + struct tm* _tm = gmtime(&__msg->written); + sprintf(__hdr.date, "%02d %3s %02d %02d:%02d:%02d", + _tm->tm_mday, gmonths[_tm->tm_mon+1], _tm->tm_year % 100, + _tm->tm_hour, _tm->tm_min, _tm->tm_sec + ); + if(__msg->arrived) + _tm = gmtime(&__msg->arrived); + __hdr.indate[0] = (byte)(_tm->tm_year - 89); + __hdr.indate[1] = (byte)(_tm->tm_mon + 1); + __hdr.indate[2] = (byte)(_tm->tm_mday); + __hdr.indate[3] = 0; + + __hdr.msgnum = __msg->msgno; + __hdr.timesread = __msg->timesread; + __hdr.timerecv = __msg->received; + __hdr.origaddr = __msg->oorig; + __hdr.destaddr = __msg->odest; + __hdr.cost = (ushort)__msg->cost; + + // Transfer attributes + __hdr.fflags |= (ushort)(__msg->attr.pvt() ? FFLAGS_MSGPRIVATE : 0); + __hdr.fflags |= (ushort)(__msg->attr.cra() ? FFLAGS_MSGCRASH : 0); + __hdr.fflags |= (ushort)(__msg->attr.rcv() ? FFLAGS_MSGREAD : 0); + __hdr.fflags |= (ushort)(__msg->attr.snt() ? FFLAGS_MSGSENT : 0); + __hdr.fflags |= (ushort)(__msg->attr.att() ? FFLAGS_MSGFILE : 0); + __hdr.fflags |= (ushort)(__msg->attr.trs() ? FFLAGS_MSGFWD : 0); + __hdr.fflags |= (ushort)(__msg->attr.orp() ? FFLAGS_MSGORPHAN : 0); + __hdr.fflags |= (ushort)(__msg->attr.k_s() ? FFLAGS_MSGKILL : 0); + __hdr.fflags |= (ushort)(__msg->attr.loc() ? FFLAGS_MSGLOCAL : 0); + __hdr.fflags |= (ushort)(__msg->attr.rsv() ? FFLAGS_MSGXX2 : 0); + __hdr.fflags |= (ushort)(__msg->attr.frq() ? FFLAGS_MSGFRQ : 0); + __hdr.fflags |= (ushort)(__msg->attr.rrq() ? FFLAGS_MSGRRQ : 0); + __hdr.fflags |= (ushort)(__msg->attr.rrc() ? FFLAGS_MSGCPT : 0); + __hdr.fflags |= (ushort)(__msg->attr.arq() ? FFLAGS_MSGARQ : 0); + __hdr.fflags |= (ushort)(__msg->attr.urq() ? FFLAGS_MSGURQ : 0); + + __hdr.xflags |= (ushort)(__msg->attr.del() ? XFLAGS_MSGDELETED : 0); + __hdr.xflags |= (ushort)(__msg->attr.ano() ? XFLAGS_MSGANON : 0); + __hdr.xflags |= (ushort)(__msg->attr.fsc() ? XFLAGS_MSGSCANNED : 0); + __hdr.xflags |= (ushort)(__msg->attr.lok() ? XFLAGS_MSGKEEP : 0); + __hdr.xflags |= (ushort)(__msg->attr.trt() ? XFLAGS_MSGTREATED : 0); + __hdr.xflags |= (ushort)(__msg->attr.lzs() ? XFLAGS_MSGPACKED : 0); + __hdr.xflags |= (ushort)(__msg->attr.gsc() ? XFLAGS_MSGGSCAN : 0); + __hdr.xflags |= (ushort)(__msg->attr.rsc() ? XFLAGS_MSGRSCAN : 0); + __hdr.xflags |= (ushort)(__msg->attr.arc() ? XFLAGS_MSGARCHIVED : 0); + __hdr.xflags |= (ushort)(__msg->attr.tag() ? XFLAGS_MSGTAGGED : 0); + + if(NOT (__mode & GMSG_UPDATE)) { + if(__msg->attr.uns()) { + __hdr.xflags &= ~(XFLAGS_MSGSCANNED|XFLAGS_MSGGSCAN|XFLAGS_MSGRSCAN); + if(isnet()) + __hdr.xflags |= XFLAGS_MSGNET; + else if(isecho()) + __hdr.xflags |= XFLAGS_MSGECHO; + } + else { + if(isnet()) { + __hdr.fflags |= FFLAGS_MSGSENT; + __hdr.xflags |= XFLAGS_MSGNET | XFLAGS_MSGSCANNED; + } + else if(isecho()) { + __hdr.fflags |= FFLAGS_MSGSENT; + __hdr.xflags |= XFLAGS_MSGECHO | XFLAGS_MSGSCANNED; + } + } + } + + __hdr.iflags = __msg->adeptxbbs.iflags; + __hdr.oflags = __msg->adeptxbbs.oflags; + + __hdr.start = __msg->txtstart; + __hdr.length = __msg->txtlength; + + if(__mode & GMSG_TXT) { + + // Write the message text + uint _size = strlen(__msg->txt) + 1; + if((__mode & GMSG_NEW) OR (_size > __hdr.length)) + __hdr.start = filelength(data->fhtext); + lseekset(data->fhtext, __hdr.start); + lock_file(data->fhtext, __hdr.start, 640L*1024L); + write(data->fhtext, __msg->txt, _size); + unlock_file(data->fhtext, __hdr.start, 640L*1024L); + __hdr.length = _size; + } + + // Write header record + long position = (__msg->msgno-1L)*(long)sizeof(XbbsHdr); + lseekset(data->fhdata, position); + lock_file(data->fhdata, position, sizeof(XbbsHdr)); + write(data->fhdata, &__hdr, sizeof(XbbsHdr)); + unlock_file(data->fhdata, position, sizeof(XbbsHdr)); + + // Build and write index record unless we are just updating the header + if(__mode & GMSG_TXT) { + XbbsIdx idx; + char buf[201]; + idx.to = XbbsCheckSum(__hdr.to); + idx.from = XbbsCheckSum(__hdr.from); + idx.subj = XbbsCheckSum(__hdr.subj); + idx.msgidcrc = idx.msgidserialno = 0; + idx.replycrc = idx.replyserialno = 0; + if(*__msg->msgids) { + strcpy(buf, __msg->msgids); + char* ptr = strrchr(buf, ' '); + if(ptr) { + *ptr++ = NUL; + idx.msgidcrc = strCrc32(buf, true, CRC32_MASK_CCITT); + idx.msgidserialno = atoulx(ptr); + } + } + if(*__msg->replys) { + strcpy(buf, __msg->replys); + char* ptr = strrchr(buf, ' '); + if(ptr) { + *ptr++ = NUL; + idx.replycrc = strCrc32(buf, true, CRC32_MASK_CCITT); + idx.replyserialno = atoulx(ptr); + } + } + memcpy(data->idx+__msg->msgno-1, &idx, sizeof(XbbsIdx)); + position = (__msg->msgno-1L)*(long)sizeof(XbbsIdx); + lseekset(data->fhindex, position); + lock_file(data->fhindex, position, sizeof(XbbsIdx)); + write(data->fhindex, &idx, sizeof(XbbsIdx)); + unlock_file(data->fhindex, position, sizeof(XbbsIdx)); + } + + if(NOT(__mode & GMSG_DELETE)) { + // Add/update personal mail record + int _addpm = true; + // Remove it if the msg is being received + if((__mode & GMSG_UPDATE) AND __msg->attr.rcv()) + _addpm = false; + // Don't touch it if the msg was already received + if(NOT (_addpm AND __msg->attr.rcv())) { + // Only do it if the person is on this BBS + if(wide->user->find(__msg->to)) + update_personal_mail(__msg, __hdr, _addpm); + } + } + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::save_hdr(int __mode, gmsg* __msg) { + + GFTRK("XbbsSaveHdr"); + + XbbsHdr _hdr; + save_message(__mode|GMSG_HDR, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::save_msg(int __mode, gmsg* __msg) { + + GFTRK("XbbsSaveMsg"); + + XbbsHdr _hdr; + save_message(__mode|GMSG_HDRTXT, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::del_msg(gmsg* __msg) { + + GFTRK("XbbsDelMsg"); + + XbbsHdr _hdr; + save_message(GMSG_HDR | GMSG_DELETE, __msg, _hdr); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::new_msgno(gmsg* __msg) { + + GFTRK("XbbsNewMsgno"); + + __msg->msgno = data->idx_size + 1; + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::update_personal_mail(gmsg* __msg, XbbsHdr& __hdr, int __addpm) { + + XbbsPmi _pmi; + _pmi.areanumber = board(); + _pmi.msgnumber = __msg->msgno; + strxcpy(_pmi.from, __msg->by, sizeof(_pmi.from)); + strxcpy(_pmi.subject, __msg->re, sizeof(_pmi.subject)); + strxcpy(_pmi.date, __hdr.date, sizeof(_pmi.date)); + + int _pmino = 0; + XbbsPmi* _pmiptr = NULL; + + gfile fp; + Path _pmifile; + sprintf(_pmifile, "%sPersonal_Mail\\%s", wide->path, __hdr.to); + int fh = test_open(_pmifile, SH_DENYWR); + + int _pmirecs = (int)(filelength(fh) / sizeof(XbbsPmi)); + XbbsPmi* _pmilist = (XbbsPmi*)throw_calloc((_pmirecs+1), sizeof(XbbsPmi)); + ::read(fh, _pmilist, sizeof(XbbsPmi)*_pmirecs); + + if(_pmilist) { + _pmiptr = _pmilist; + for(_pmino=0; _pmino<_pmirecs; _pmino++, _pmiptr++) { + if(_pmiptr->areanumber == _pmi.areanumber) + if(_pmiptr->msgnumber == _pmi.msgnumber) + break; + } + if(_pmino == _pmirecs) + _pmiptr = NULL; + } + + if(__addpm) { + if(!_pmiptr) { + _pmirecs++; + _pmilist = (XbbsPmi*)throw_realloc(_pmilist, _pmirecs*sizeof(XbbsPmi)); + _pmiptr = _pmilist + _pmirecs - 1; + } + memcpy(_pmiptr, &_pmi, sizeof(XbbsPmi)); + } + else { + if(_pmiptr) { + memmove(_pmiptr, _pmiptr+1, (_pmirecs-_pmino-1)*sizeof(XbbsPmi)); + _pmirecs--; + } + } + + if(_pmirecs) { + lseekset(fh, 0); + ::write(fh, _pmilist, sizeof(XbbsPmi)*_pmirecs); + if(_pmiptr AND !__addpm) + chsize(fh, sizeof(XbbsPmi)*_pmirecs); + ::close(fh); + } + else { + ::close(fh); + remove(_pmifile); + } + + throw_free(_pmilist); +} + + +// ------------------------------------------------------------------ + +void XbbsArea::update_timesread(gmsg* msg) { + + GFTRK("XbbsArea::update_timesread"); + + XbbsHdr hdr; + + long position = (Msgn->ToReln(msg->msgno)-1)*(long)sizeof(XbbsHdr); + + ::lseekset(data->fhdata, position); + ::read(data->fhdata, &hdr, sizeof(XbbsHdr)); + + hdr.timesread = (word)msg->timesread; + + ::lseekset(data->fhdata, position); + lock_file(data->fhdata, position, sizeof(XbbsHdr)); + ::write(data->fhdata, &hdr, sizeof(XbbsHdr)); + unlock_file(data->fhdata, position, sizeof(XbbsHdr)); + + GFTRK(NULL); +} + + +// ------------------------------------------------------------------ + diff --git a/goldlib/gmb3/gmoxbbs5.cpp b/goldlib/gmb3/gmoxbbs5.cpp new file mode 100644 index 0000000..408ef35 --- /dev/null +++ b/goldlib/gmb3/gmoxbbs5.cpp @@ -0,0 +1,129 @@ +// This may look like C code, but it is really -*- C++ -*- + +// ------------------------------------------------------------------ +// The Goldware Library +// Copyright (C) 1990-1999 Odinn Sorensen +// ------------------------------------------------------------------ +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the Free +// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +// MA 02111-1307, USA +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ +// AdeptXBBS messagebase engine. +// ------------------------------------------------------------------ + +#include +#include +#include + + +// ------------------------------------------------------------------ + +char* XbbsArea::user_lookup(char* __lookfor) { + + wide->user->fh = ::sopen(AddPath(wide->path, "Users"), O_RDWR|O_BINARY, WideSharemode, S_STDRW); + if(wide->user->fh) { + wide->user->findwild(__lookfor, __lookfor); + ::close(wide->user->fh); + } + + if(wide->user->found) + return __lookfor; + else + return NULL; +} + + +// ------------------------------------------------------------------ + +int XbbsArea::renumber() { + + return false; +} + + +// ------------------------------------------------------------------ +// Hexdump the current message header + +Line* XbbsArea::make_dump_msg(Line*& lin, gmsg* msg, char* lng_head) { + + GFTRK("XbbsMakeDump"); + + XbbsHdr hdr; + load_message(GMSG_HDRTXT, msg, hdr); + XbbsIdx* idx = data->idx + (msg->msgno - 1); + + char buf[100]; + Line* line = lin = + AddLine (NULL, "Hexdump of AdeptXBBS message header and text"); + AddLineF(line, "------------------------------------------------------------------------------"); + line = AddLine(line, ""); + AddLineF(line, "Path : %s", path()); + AddLineF(line, "UserRecno : %u (%s)", wide->userno, WideUsername[0]); + line = AddLine(line, ""); + AddLineF(line, "Header Record:"); + line = AddLine(line, ""); + AddLineF(line, "Version : %u.%u", hdr.majorversion, hdr.minorversion); + AddLineF(line, "StructLen : %u", hdr.structlen); + AddLineF(line, "From : %s", hdr.from); + AddLineF(line, "To : %s", hdr.to); + AddLineF(line, "Subj : %s", hdr.subj); + AddLineF(line, "Date : %s", hdr.date); + AddLineF(line, "InDate : %u-%u-%u", hdr.indate[0]+1989, hdr.indate[1], hdr.indate[2]); + AddLineF(line, "MsgNum : %lu", hdr.msgnum); + AddLineF(line, "TimesRead : %lu", hdr.timesread); + AddLineF(line, "TimeRecv : %s (%08lXh)", TimeToStr(buf, hdr.timerecv), hdr.timerecv); + AddLineF(line, "Length : %lu", hdr.length); + AddLineF(line, "Start : %lu", hdr.start); + AddLineF(line, "Extra1,2,3 : %lu, %lu, %lu", hdr.extra1, hdr.extra2, hdr.extra3); + AddLineF(line, "OrigAddr : %u:%u/%u.%u", hdr.origaddr.zone, hdr.origaddr.net, hdr.origaddr.node, hdr.origaddr.point); + AddLineF(line, "DestAddr : %u:%u/%u.%u", hdr.origaddr.zone, hdr.destaddr.net, hdr.destaddr.node, hdr.destaddr.point); + AddLineF(line, "Cost : %u", hdr.cost); + AddLineF(line, "FFlags : %u (%04Xh)", hdr.fflags, hdr.fflags); + AddLineF(line, "XFlags : %u (%04Xh)", hdr.xflags, hdr.xflags); + AddLineF(line, "IFlags : %lu (%08lXh)", hdr.iflags, hdr.iflags); + AddLineF(line, "OFlags : %lu (%08lXh)", hdr.oflags, hdr.oflags); + line = AddLine(line, ""); + AddLineF(line, "Index Record:"); + line = AddLine(line, ""); + AddLineF(line, "CheckSumTo : %04Xh (%u)", idx->to, idx->to); + AddLineF(line, "CheckSumFrom : %04Xh (%u)", idx->from, idx->from); + AddLineF(line, "CheckSumSubj : %04Xh (%u)", idx->subj, idx->subj); + AddLineF(line, "MsgidCrc : %08lXh (%lu)", idx->msgidcrc, idx->msgidcrc); + AddLineF(line, "MsgidSerialNo : %08lXh (%lu)", idx->msgidserialno, idx->msgidserialno); + AddLineF(line, "ReplyidCrc : %08lXh (%lu)", idx->replycrc, idx->replycrc); + AddLineF(line, "ReplyidSerialNo : %08lXh (%lu)", idx->replyserialno, idx->replyserialno); + line = AddLine(line, ""); + AddLineF(line, lng_head); + line = AddLine(line, ""); + + int _count; + char* _ptr = (char*)&hdr; + for(_count=0; _count doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* + * If your system is kinda special + */ +/* #undef SYSTEM_DOS */ +/* #undef SYSTEM_QUICKWIN */ +/* #undef SYSTEM_WINDLL */ +/* #undef SYSTEM_OS2 */ + +/* + * If your system has stdin/stdout/stderr + */ +#define HAVE_STDIO 1 + +/* + * how to declare functions that are exported from the UU library + */ +#define UUEXPORT + +/* + * how to declare functions that are exported from the fptools library + */ +#define TOOLEXPORT + +/* + * define if your compiler supports function prototypes + */ +#define PROTOTYPES 1 + +/* + * Replacement functions. + * #define strerror _FP_strerror + * #define tempnam _FP_tempnam + * if you don't have these functions + */ + +/* Define if you have the gettimeofday function. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#undef HAVE_IO_H + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_STDARG_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_VARARGS_H */ diff --git a/goldlib/uulib/fptools.c b/goldlib/uulib/fptools.c new file mode 100644 index 0000000..c52744b --- /dev/null +++ b/goldlib/uulib/fptools.c @@ -0,0 +1,512 @@ +/* + * fptools.c, some helper functions for getcgi.c and uu(en|de)view + * + * Distributed by the GNU General Public License. Use and be happy. + * Read http://www.uni-frankfurt.de/~fp/Tools/Getcgi.html for more + * information. fp@informatik.uni-frankfurt.de + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SYSTEM_WINDLL +#include +#endif +#ifdef SYSTEM_OS2 +#include +#endif + +/* + * This file provides replacements for some handy functions that aren't + * available on all systems, like most of the functions. They + * should behave exactly as their counterparts. There are also extensions + * that aren't portable at all (like strirstr etc.). + * The proper behaviour in a configure script is as follows: + * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,_FP_strrchr)) + * This way, the (probably less efficient) replacements will only be used + * where it is not provided by the default libraries. Be aware that this + * does not work with replacements that just shadow wrong behaviour (like + * _FP_free) or provide extended functionality (_FP_gets). + * The above is not used in the uuenview/uudeview configuration script, + * since both only use the replacement functions in non-performance-cri- + * tical sections (except for _FP_tempnam and _FP_strerror, where some + * functionality of the original would be lost). + */ + +#include +#include + +#ifdef STDC_HEADERS +#include +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif + +#include + +#if 0 +#ifdef SYSTEM_WINDLL +BOOL _export WINAPI +DllEntryPoint (HINSTANCE hInstance, DWORD seginfo, + LPVOID lpCmdLine) +{ + /* Don't do anything, so just return true */ + return TRUE; +} +#endif +#endif + +char * fptools_id = "$Id$"; + +/* + * some versions of free can't handle a NULL pointer properly + * (ANSI says, free ignores a NULL pointer, but some machines + * prefer to SIGSEGV on it) + */ + +void TOOLEXPORT +_FP_free (void *ptr) +{ + if (ptr) free (ptr); +} + +/* + * This is non-standard, so I'm defining my own + */ + +char * TOOLEXPORT +_FP_strdup (char *string) +{ + char *result; + + if (string == NULL) + return NULL; + + if ((result = (char *) malloc (strlen (string) + 1)) == NULL) + return NULL; + + strcpy (result, string); + return result; +} + +/* + * limited-length string copy. this function behaves differently from + * the original in that the dest string is always terminated with a + * NULL character. + */ + +char * TOOLEXPORT +_FP_strncpy (char *dest, char *src, int length) +{ + char *odest=dest; + if (src == NULL || dest == NULL || length-- <= 0) + return dest; + + while (length-- && *src) + *dest++ = *src++; + + *dest++ = '\0'; + return odest; +} + +/* + * duplicate a memory area + */ + +void * TOOLEXPORT +_FP_memdup (void *ptr, int len) +{ + void *result; + + if (ptr == NULL) + return NULL; + + if ((result = malloc (len)) == NULL) + return NULL; + + memcpy (result, ptr, len); + return result; +} + +/* + * case-insensitive compare + */ + +int TOOLEXPORT +_FP_stricmp (char *str1, char *str2) +{ + if (str1==NULL || str2==NULL) + return -1; + + while (*str1) { + if (tolower(*str1) != tolower(*str2)) + break; + str1++; + str2++; + } + return (tolower (*str1) - tolower (*str2)); +} + +int TOOLEXPORT +_FP_strnicmp (char *str1, char *str2, int count) +{ + if (str1==NULL || str2==NULL) + return -1; + + while (*str1 && count) { + if (tolower(*str1) != tolower(*str2)) + break; + str1++; + str2++; + count--; + } + return count ? (tolower (*str1) - tolower (*str2)) : 0; +} + +/* + * autoconf says this function might be a compatibility problem + */ + +char * TOOLEXPORT +_FP_strstr (char *str1, char *str2) +{ + char *ptr1, *ptr2; + + if (str1==NULL) + return NULL; + if (str2==NULL) + return str1; + + while (*(ptr1=str1)) { + for (ptr2=str2; + *ptr1 && *ptr2 && *ptr1==*ptr2; + ptr1++, ptr2++) + /* empty loop */ ; + + if (*ptr2 == '\0') + return str1; + str1++; + } + return NULL; +} + +char * TOOLEXPORT +_FP_strpbrk (char *str, char *accept) +{ + char *ptr; + + if (str == NULL) + return NULL; + if (accept == NULL || *accept == '\0') + return str; + + for (; *str; str++) + for (ptr=accept; *ptr; ptr++) + if (*str == *ptr) + return str; + + return NULL; +} + +/* + * autoconf also complains about this one + */ + +char * TOOLEXPORT +_FP_strtok (char *str1, char *str2) +{ + static char *optr; + char *ptr; + + if (str2 == NULL) + return NULL; + + if (str1) { + optr = str1; + } + else { + if (*optr == '\0') + return NULL; + } + + while (*optr && strchr (str2, *optr)) /* look for beginning of token */ + optr++; + + if (*optr == '\0') /* no token found */ + return NULL; + + ptr = optr; + while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */ + optr++; + + if (*optr) { + *optr++ = '\0'; + } + return ptr; +} + +/* + * case insensitive strstr. + */ + +char * TOOLEXPORT +_FP_stristr (char *str1, char *str2) +{ + char *ptr1, *ptr2; + + if (str1==NULL) + return NULL; + if (str2==NULL) + return str1; + + while (*(ptr1=str1)) { + for (ptr2=str2; + *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2); + ptr1++, ptr2++) + /* empty loop */ ; + + if (*ptr2 == '\0') + return str1; + str1++; + } + return NULL; +} + +/* + * Nice fake of the real (non-standard) one + */ + +char * TOOLEXPORT +_FP_strrstr (char *ptr, char *str) +{ + char *found=NULL, *new, *iter=ptr; + + if (ptr==NULL || str==NULL) + return NULL; + + if (*str == '\0') + return ptr; + + while ((new = _FP_strstr (iter, str)) != NULL) { + found = new; + iter = new + 1; + } + return found; +} + +char * TOOLEXPORT +_FP_strirstr (char *ptr, char *str) +{ + char *found=NULL, *iter=ptr, *new; + + if (ptr==NULL || str==NULL) + return NULL; + if (*str == '\0') + return ptr; + + while ((new = _FP_stristr (iter, str)) != NULL) { + found = new; + iter = new + 1; + } + return found; +} + +/* + * convert whole string to case + */ + +char * TOOLEXPORT +_FP_stoupper (char *input) +{ + char *iter = input; + + if (input == NULL) + return NULL; + + while (*iter) { + *iter = toupper (*iter); + iter++; + } + return input; +} + +char * TOOLEXPORT +_FP_stolower (char *input) +{ + char *iter = input; + + if (input == NULL) + return NULL; + + while (*iter) { + *iter = tolower (*iter); + iter++; + } + return input; +} + +/* + * string matching with wildcards + */ + +int TOOLEXPORT +_FP_strmatch (char *string, char *pattern) +{ + char *p1 = string, *p2 = pattern; + + if (pattern==NULL || string==NULL) + return 0; + + while (*p1 && *p2) { + if (*p2 == '?') { + p1++; p2++; + } + else if (*p2 == '*') { + if (*++p2 == '\0') + return 1; + while (*p1 && *p1 != *p2) + p1++; + } + else if (*p1 == *p2) { + p1++; p2++; + } + else + return 0; + } + if (*p1 || *p2) + return 0; + + return 1; +} + +char * TOOLEXPORT +_FP_strrchr (char *string, int tc) +{ + char *ptr; + + if (string == NULL) + return NULL; + + ptr = string + strlen (string) - 1; + + while (ptr != string && *ptr != tc) + ptr--; + + if (*ptr == tc) + return ptr; + + return NULL; +} + +/* + * strip directory information from a filename. Works only on DOS and + * Unix systems so far ... + */ + +char * TOOLEXPORT +_FP_cutdir (char *filename) +{ + char *ptr; + + if (filename == NULL) + return NULL; + + if ((ptr = _FP_strrchr (filename, '/')) != NULL) + ptr++; + else if ((ptr = _FP_strrchr (filename, '\\')) != NULL) + ptr++; + else + ptr = filename; + + return ptr; +} + +/* + * My own fgets function. It handles all kinds of line terminators + * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the + * terminator is replaced by a single LF + */ + +char * TOOLEXPORT +_FP_fgets (char *buf, int n, FILE *stream) +{ + char *obp = buf; + int c; + + if (feof (stream)) + return NULL; + + while (--n) { + if ((c = fgetc (stream)) == EOF) { + if (ferror (stream)) + return NULL; + else { + if (obp == buf) + return NULL; + *buf = '\0'; + return obp; + } + } + if (c == '\015') { /* CR */ + /* + * Peek next character. If it's no LF, push it back. + * ungetc(EOF, stream) is handled correctly according + * to the manual page + */ + if ((c = fgetc (stream)) != '\012') + if (!feof (stream)) + ungetc (c, stream); + *buf++ = '\012'; + *buf = '\0'; + return obp; + } + else if (c == '\012') { /* LF */ + *buf++ = '\012'; + *buf = '\0'; + return obp; + } + /* + * just another standard character + */ + *buf++ = c; + } + /* + * n-1 characters already transferred + */ + *buf = '\0'; + + return obp; +} + +/* + * A replacement strerror function that just returns the error code + */ + +char * TOOLEXPORT +_FP_strerror (int errcode) +{ + static char number[8]; + + sprintf (number, "%03d", errcode); + + return number; +} + +/* + * tempnam is not ANSI, but tmpnam is. Ignore the prefix here. + */ + +char * TOOLEXPORT +_FP_tempnam (char *dir, char *pfx) +{ + return _FP_strdup (tmpnam (NULL)); +} diff --git a/goldlib/uulib/fptools.h b/goldlib/uulib/fptools.h new file mode 100644 index 0000000..c9cacf1 --- /dev/null +++ b/goldlib/uulib/fptools.h @@ -0,0 +1,60 @@ +/* + * fptools.c, some helper functions for getcgi.c and uu(en|de)view + * + * Distributed by the GNU General Public License. Use and be happy. + * Read http://www.uni-frankfurt.de/~fp/Tools/Getcgi.html for more + * information. fp@informatik.uni-frankfurt.de + */ + +/* + * Some handy, nonstandard functions. Note that the original may + * be both faster and better. ``better'', if your compiler allows + * cleaner use of such functions by proper use of ``const''. + * + * $Id$ + */ + +#ifndef __FPTOOLS_H__ +#define __FPTOOLS_H__ + +#ifndef _ANSI_ARGS_ +#ifdef PROTOTYPES +#define _ANSI_ARGS_(c) c +#else +#define _ANSI_ARGS_(c) () +#endif +#endif + +#ifndef TOOLEXPORT +#define TOOLEXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void TOOLEXPORT _FP_free _ANSI_ARGS_((void *)); +char * TOOLEXPORT _FP_strdup _ANSI_ARGS_((char *)); +char * TOOLEXPORT _FP_strncpy _ANSI_ARGS_((char *, char *, int)); +void * TOOLEXPORT _FP_memdup _ANSI_ARGS_((void *, int)); +int TOOLEXPORT _FP_stricmp _ANSI_ARGS_((char *, char *)); +int TOOLEXPORT _FP_strnicmp _ANSI_ARGS_((char *, char *, int)); +char * TOOLEXPORT _FP_strrstr _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_stoupper _ANSI_ARGS_((char *)); +char * TOOLEXPORT _FP_stolower _ANSI_ARGS_((char *)); +int TOOLEXPORT _FP_strmatch _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_strstr _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_stristr _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_strirstr _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_strrchr _ANSI_ARGS_((char *, int)); +char * TOOLEXPORT _FP_fgets _ANSI_ARGS_((char *, int, FILE *)); +char * TOOLEXPORT _FP_strpbrk _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_strtok _ANSI_ARGS_((char *, char *)); +char * TOOLEXPORT _FP_cutdir _ANSI_ARGS_((char *)); +char * TOOLEXPORT _FP_strerror _ANSI_ARGS_((int)); +char * TOOLEXPORT _FP_tempnam _ANSI_ARGS_((char *, char *)); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/goldlib/uulib/uucheck.c b/goldlib/uulib/uucheck.c new file mode 100644 index 0000000..f840909 --- /dev/null +++ b/goldlib/uulib/uucheck.c @@ -0,0 +1,1468 @@ +/* + * This file is part of uudeview, the simple and friendly multi-part multi- + * file uudecoder program (c) 1994 by Frank Pilhofer. The author may be + * contacted by his email address, fp@informatik.uni-frankfurt.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SYSTEM_WINDLL +#include +#endif +#ifdef SYSTEM_OS2 +#include +#endif + +/* + * uucheck.c + * + * Various checking and processing of one input part + **/ + +#include +#include + +#ifdef STDC_HEADERS +#include +#include +#endif +#ifdef HAVE_MALLOC_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_MEMORY_H +#include +#endif + +#include +#include +#include +#include + +char * uucheck_id = "$Id$"; + +/* + * Arbitrary number. This is the maximum number of part numbers we + * store for our have-parts and missing-parts lists + */ + +#define MAXPLIST 256 + + +/* + * forward declarations of local functions + */ + +static char * UUGetFileName _ANSI_ARGS_((char *, char *, char *)); +static int UUGetPartNo _ANSI_ARGS_((char *, char **, char **)); + +/* + * State of Scanner function and PreProcessPart + */ + +int lastvalid, lastenc, nofnum; +char *uucheck_lastname; +char *uucheck_tempname; +static int lastpart = 0; +static char *nofname = "UNKNOWN"; + +/* + * special characters we allow an unquoted filename to have + */ + +static char *fnchars = "._-~!"; + +/* + * Policy for extracting a part number from the subject line. + * usually, look for part numbers in () brackets first, then in [] + */ + +static char *brackchr[] = { + "()[]", "[]()" +}; + +/* + * Extract a filename from the subject line. We need anything to identify + * the name of the program for sorting. If a nice filename cannot be found, + * the subject line itself is used + * ptonum is, if not NULL, a pointer to the part number in the subject line, + * so that it won't be used as filename. + **/ + +static char * +UUGetFileName (char *subject, char *ptonum, char *ptonend) +{ + char *ptr = subject, *iter, *result, *part; + int count, length=0, alflag=0; + +/* + * If this file has no subject line, assume it is the next part of the + * previous file (this is done in UUPreProcessPart) + **/ + + if (subject == NULL) + return NULL; + +/* + * If the subject starts with 'Re', it is ignored + * REPosts or RETries are not ignored! + **/ + + if (uu_ignreply && + (subject[0] == 'R' || subject[0] == 'r') && + (subject[1] == 'E' || subject[1] == 'e') && + (subject[2] == ':' || subject[2] == ' ')) { + return NULL; + } + +/* + * Ignore a "Repost" prefix of the subject line. We don't want to get + * a file named "Repost" :-) + **/ + + if (_FP_strnicmp (subject, "repost", 6) == 0) + subject += 6; + if (_FP_strnicmp (subject, "re:", 3) == 0) + subject += 3; + + while (*subject == ' ' || *subject == ':') subject++; + + part = _FP_stristr (subject, "part"); + if (part == subject) { + subject += 4; + while (*subject == ' ') subject++; + } + + /* + * If the file was encoded by uuenview, then the filename is enclosed + * in [brackets]. But check what's inside these bracket's, try not to + * fall for something other than a filename + */ + + ptr = subject; + while ((iter = strchr (ptr, '[')) != NULL) { + if (strchr (iter, ']') == NULL) { + ptr = iter + 1; + continue; + } + iter++; + while (isspace (*iter)) + iter++; + count = length = alflag = 0; + while (iter[count] && + (isalnum (iter[count]) || strchr (fnchars, iter[count])!=NULL)) { + if (isalpha (iter[count])) + alflag++; + count++; + } + if (count<4 || alflag==0) { + ptr = iter + 1; + continue; + } + length = count; + while (isspace (iter[count])) + count++; + if (iter[count] == ']') { + ptr = iter; + break; + } + length = 0; + ptr = iter + 1; + } + + /* + * new filename detection routine, fists mostly for files by ftp-by-email + * servers that create subject lines with ftp.host.address:/full/path/file + * on them. We look for slashes and take the filename from after the last + * one ... or at least we try to. + */ + + if (length == 0) { + ptr = subject; + while ((iter = strchr (ptr, '/')) != NULL) { + if (iter >= ptonum && iter <= ptonend) { + ptr = iter + 1; + continue; + } + count = length = 0; + iter++; + while (iter[count] && + (isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL)) + count++; + if (iter[count] == ' ' && length > 4) { + length = count; + break; + } + ptr = iter + ((count)?count:1); + } + } + + /* + * Look for two alphanumeric strings separated by a '.' + * (That's most likely a filename) + **/ + + if (length == 0) { + ptr = subject; + while (*ptr && *ptr != 0x0a && *ptr != 0x0d && ptr != part) { + iter = ptr; + count = length = alflag = 0; + + if (_FP_strnicmp (ptr, "ftp", 3) == 0) { + /* hey, that's an ftp address */ + while (isalpha (*ptr) || isdigit (*ptr) || *ptr == '.') + ptr++; + continue; + } + + while ((isalnum(*iter)||strchr(fnchars, *iter)!=NULL|| + *iter=='/') && *iter && iter != ptonum && *iter != '.') { + if (isalpha (*iter)) + alflag = 1; + + count++; iter++; + } + if (*iter == '\0' || iter == ptonum) { + if (iter == ptonum) + ptr = ptonend; + else + ptr = iter; + + length = 0; + continue; + } + if (*iter++ != '.' || count > 32 || alflag == 0) { + ptr = iter; + length = 0; + continue; + } + if (_FP_strnicmp (iter, "edu", 3) == 0 || + _FP_strnicmp (iter, "gov", 3) == 0) { + /* hey, that's an ftp address */ + while (isalpha (*iter) || isdigit (*iter) || *iter == '.') + iter++; + ptr = iter; + length = 0; + continue; + } + + length += count + 1; + count = 0; + + while ((isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL|| + iter[count]=='/') && iter[count] && iter[count] != '.') + count++; + + if (iter[count]==':' && iter[count+1]=='/') { + /* looks like stuff from a mail server */ + ptr = iter + 1; + length = 0; + continue; + } + + if (count > 8 || iter == ptonum) { + ptr = iter; + length = 0; + continue; + } + + if (iter[count] != '.') { + length += count; + break; + } + + while (iter[count] && + (isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL|| + iter[count]=='/')) + count++; + + if (iter[count]==':' && iter[count+1]=='/') { + /* looks like stuff from a mail server */ + ptr = iter + 1; + length = 0; + continue; + } + + if (count < 12 && iter != ptonum) { + length += count; + break; + } + + ptr = iter; + length = 0; + } + } + + if (length == 0) { /* No filename found, use subject line for ident */ + ptr = subject; + + while (*ptr && !isalpha (*ptr)) + ptr++; + + while ((isalnum(ptr[length])||strchr(fnchars,ptr[length])!=NULL|| + ptr[length] == '/') && + ptr[length] && ptr+length!=part && ptr+length!=ptonum) + length++; + + if (length) { + if (ptr[length] == '\0' || ptr[length] == 0x0a || ptr[length] == 0x0d) { + length--; + + /* + * I used to cut off digits from the end of the string, but + * let's try to live without. We want to distinguish + * DUTCH951 from DUTCH952 + * + * while ((ptr[length] == ' ' || isdigit (ptr[length])) && length > 0) + * length--; + */ + } + else { + length--; + + while (ptr[length] == ' ' && length > 0) + length--; + } + length++; + } + } + + if (length == 0) { /* Still found nothing? We need *something*! */ + ptr = nofname; + length = strlen (nofname); + } + + if ((result = (char *) malloc (length + 1)) == NULL) { + UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), length+1); + return NULL; + } + + memcpy (result, ptr, length); + result[length] = '\0'; + + return result; +} + +/* + * Extract the Part Number from the subject line. + * We look first for numbers in (#/#)'s, then for numbers in [#/#]'s + * and then for digits that are not part of a string. + * If we cannot find anything, assume it is the next part of the + * previous file. + * If we find a part number, we put a pointer to it in *where. This is + * done so that the UUGetFileName function doesn't accidentally use the + * part number as the file name. *whend points to the end of this part + * number. + **/ + +static int +UUGetPartNo (char *subject, char **where, char **whend) +{ + char *ptr = subject, *iter, *delim, bdel[2]=" "; + int count, length=0, bpc; + + *where = NULL; bdel[0] = ' '; + *whend = NULL; bdel[1] = '\0'; + + iter = NULL; + delim = ""; + + if (subject == NULL) + return -1; + + if (uu_ignreply && + (subject[0] == 'R' || subject[0] == 'r') && /* Ignore replies, but not */ + (subject[1] == 'E' || subject[1] == 'e') && /* reposts */ + (subject[2] == ':' || subject[2] == ' ')) + return -2; + + /* + * First try numbers in () or [] (or vice versa, according to bracket + * policy) + */ + + for (bpc=0, length=0; brackchr[uu_bracket_policy][bpc]; bpc+=2) { + ptr = subject; + while ((iter = strchr (ptr, brackchr[uu_bracket_policy][bpc])) != NULL) { + count = length = 0; iter++; + + while (*iter == ' ' || *iter == '#') + iter++; + + if (!isdigit (*iter)) { + ptr = iter; + continue; + } + while (isdigit (iter[count])) + count++; + length = count; + + if (iter[count] == '\0' || iter[count+1] == '\0') { + iter += count; + length = 0; + break; + } + if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) { + *where = iter; + bdel[0] = brackchr[uu_bracket_policy][bpc+1]; + delim = bdel; + break; + } + + while (iter[count] == ' ' || iter[count] == '#' || + iter[count] == '/' || iter[count] == '\\') count++; + + if (_FP_strnicmp (iter + count, "of", 2) == 0) + count += 2; + + while (iter[count] == ' ') count++; + while (isdigit (iter[count])) count++; + while (iter[count] == ' ') count++; + + if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) { + *where = iter; + bdel[0] = brackchr[uu_bracket_policy][bpc+1]; + delim = bdel; + break; + } + + length = 0; + ptr = iter; + } + if (length) + break; + } + + /* + * look for the string "part " followed by a number + */ + + if (length == 0) { + if ((iter = _FP_stristr (subject, "part ")) != NULL) { + iter += 5; + + while (isspace (*iter) || *iter == '.' || *iter == '-') + iter++; + + while (isdigit (iter[length])) + length++; + + if (length == 0) { + if (_FP_strnicmp (iter, "one", 3) == 0) length = 1; + else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2; + else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3; + else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4; + else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5; + else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6; + else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7; + else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8; + else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9; + else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10; + + if (length && (*whend = strchr (iter, ' '))) { + *where = iter; + return length; + } + else + length = 0; + } + else { + *where = iter; + delim = "of"; + } + } + } + + /* + * look for the string "part" followed by a number + */ + + if (length == 0) { + if ((iter = _FP_stristr (subject, "part")) != NULL) { + iter += 4; + + while (isspace (*iter) || *iter == '.' || *iter == '-') + iter++; + + while (isdigit (iter[length])) + length++; + + if (length == 0) { + if (_FP_strnicmp (iter, "one", 3) == 0) length = 1; + else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2; + else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3; + else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4; + else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5; + else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6; + else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7; + else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8; + else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9; + else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10; + + if (length && (*whend = strchr (iter, ' '))) { + *where = iter; + return length; + } + else + length = 0; + } + else { + *where = iter; + delim = "of"; + } + } + } + + /* + * look for [0-9]* "of" [0-9]* + */ + + if (length == 0) { + if ((iter = _FP_strirstr (subject, "of")) != NULL) { + while (iter>subject && isspace (*(iter-1))) + iter--; + if (isdigit(*(iter-1))) { + while (iter>subject && isdigit (*(iter-1))) + iter--; + if (!isdigit (*iter) && !isalpha (*iter) && *iter != '.') + iter++; + ptr = iter; + + while (isdigit (*ptr)) { + ptr++; length++; + } + *where = iter; + delim = "of"; + } + } + } + + /* + * look for whitespace-separated (or '/'-separated) digits + */ + + if (length == 0) { + ptr = subject; + + while (*ptr && length==0) { + while (*ptr && !isdigit (*ptr)) + ptr++; + if (isdigit (*ptr) && (ptr==subject || *ptr==' ' || *ptr=='/')) { + while (isdigit (ptr[length])) + length++; + if (ptr[length]!='\0' && ptr[length]!=' ' && ptr[length]!='/') { + ptr += length; + length = 0; + } + else { + iter = ptr; + bdel[0] = ptr[length]; + delim = bdel; + } + } + else { + while (isdigit (*ptr)) + ptr++; + } + } + } + + /* + * look for _any_ digits -- currently disabled, because it also fell + * for "part numbers" in file names + */ + +#if 0 + if (length == 0) { + count = strlen(subject) - 1; + ptr = subject; + + while (count > 0) { + if (!isdigit(ptr[count])||isalpha(ptr[count+1])||ptr[count+1] == '.') { + count--; + continue; + } + length = 0; + + while (count >= 0 && isdigit (ptr[count])) { + count--; length++; + } + if (count>=0 && ((isalpha (ptr[count]) && + (ptr[count] != 's' || ptr[count+1] != 't') && + (ptr[count] != 'n' || ptr[count+1] != 'd')) || + ptr[count] == '/' || ptr[count] == '.' || + ptr[count] == '-' || ptr[count] == '_')) { + length = 0; + continue; + } + count++; + iter = ptr + count; + + if (length > 4) { + length = 0; + continue; + } + *where = iter; + delim = "of"; + break; + } + } +#endif + + /* + * look for part numbering as string + */ + + if (length == 0) { + /* + * some people use the strangest things, including spelling mistakes :-) + */ + if ((iter = _FP_stristr (subject, "first")) != NULL) length = 1; + else if ((iter = _FP_stristr (subject, "second")) != NULL) length = 2; + else if ((iter = _FP_stristr (subject, "third")) != NULL) length = 3; + else if ((iter = _FP_stristr (subject, "forth")) != NULL) length = 4; + else if ((iter = _FP_stristr (subject, "fourth")) != NULL) length = 4; + else if ((iter = _FP_stristr (subject, "fifth")) != NULL) length = 5; + else if ((iter = _FP_stristr (subject, "sixth")) != NULL) length = 6; + else if ((iter = _FP_stristr (subject, "seventh")) != NULL) length = 7; + else if ((iter = _FP_stristr (subject, "eigth")) != NULL) length = 8; + else if ((iter = _FP_stristr (subject, "nineth")) != NULL) length = 9; + else if ((iter = _FP_stristr (subject, "ninth")) != NULL) length = 9; + else if ((iter = _FP_stristr (subject, "tenth")) != NULL) length = 10; + else iter = NULL; + + if (length && iter && (*whend = strchr (iter, ' '))) { + *where = iter; + return length; + } + else + length = 0; + } + + if (iter == NULL || length == 0) /* should be equivalent */ + return -1; + + *where = iter; + + if (delim && delim[0]) { + if ((*whend=_FP_stristr (iter, delim)) != NULL && (*whend - *where) < 12) { + ptr = (*whend += strlen (delim)); + + while (*ptr == ' ') + ptr++; + + if (isdigit (*ptr)) { + *whend = ptr; + while (isdigit (**whend)) + *whend += 1; + } + } + else { + *whend = iter + length; + } + } + else { + *whend = iter + length; + } + + return atoi (iter); +} + +/* + * Obtain and process some information about the data. + **/ + +uufile * +UUPreProcessPart (fileread *data, int *ret) +{ + char *where, *whend, temp[80], *ptr, *p2; + uufile *result; + + if ((result = (uufile *) malloc (sizeof (uufile))) == NULL) { + UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), sizeof (uufile)); + *ret = UURET_NOMEM; + return NULL; + } + memset (result, 0, sizeof (uufile)); + + if (data->partno) { + where = whend = NULL; + result->partno = data->partno; + } + else if (uu_dumbness) { + result->partno = -1; + where = whend = NULL; + } + else if ((result->partno=UUGetPartNo(data->subject,&where,&whend)) == -2) { + *ret = UURET_NODATA; + UUkillfile (result); + return NULL; + } + + if (data->filename != NULL) { + if ((result->filename = _FP_strdup (data->filename)) == NULL) { + UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), + strlen (data->filename)+1); + *ret = UURET_NOMEM; + UUkillfile (result); + return NULL; + } + } + else + result->filename = NULL; + + if (uu_dumbness <= 1) + result->subfname = UUGetFileName (data->subject, where, whend); + else + result->subfname = NULL; + + result->mimeid = _FP_strdup (data->mimeid); + result->mimetype = _FP_strdup (data->mimetype); + + if (result->partno == -1 && + (data->uudet == PT_ENCODED || data->uudet == QP_ENCODED)) + result->partno = 1; + + if (data->flags & FL_SINGLE) { + /* + * Don't touch this part. But it should really have a filename + */ + if (result->filename == NULL) { + sprintf (temp, "%s.%03d", nofname, ++nofnum); + result->filename = _FP_strdup (temp); + } + if (result->subfname == NULL) + result->subfname = _FP_strdup (result->filename); + + if (result->filename == NULL || + result->subfname == NULL) { + UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), + (result->filename==NULL)? + (strlen(temp)+1):(strlen(result->filename)+1)); + *ret = UURET_NOMEM; + UUkillfile(result); + return NULL; + } + if (result->partno == -1) + result->partno = 1; + } + else if (result->subfname == NULL && data->uudet && + (data->begin || result->partno == 1 || + (!uu_dumbness && result->partno == -1 && + (data->subject != NULL || result->filename != NULL)))) { + /* + * If it's the first part of something and has some valid data, but + * no subject or anything, initialize lastvalid + */ + /* + * in this case, it really _should_ have a filename somewhere + */ + if (result->filename != NULL) + result->subfname = _FP_strdup (result->filename); + else { /* if not, escape to UNKNOWN. We need to fill subfname */ + sprintf (temp, "%s.%03d", nofname, ++nofnum); + result->subfname = _FP_strdup (temp); + } + /* + * in case the strdup failed + */ + if (result->subfname == NULL) { + UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), + (result->filename)? + (strlen(result->filename)+1):(strlen(temp)+1)); + *ret = UURET_NOMEM; + UUkillfile (result); + return NULL; + } + /* + * if it's also got an 'end', or is the last part in a MIME-Mail, + * then don't set lastvalid + */ + if (!data->end && (!data->partno || data->partno != data->maxpno)) { + /* + * initialize lastvalid + */ + lastvalid = 1; + lastenc = data->uudet; + lastpart = result->partno = 1; + _FP_strncpy (uucheck_lastname, result->subfname, 256); + } + else + result->partno = 1; + } + else if (result->subfname == NULL && data->uudet && data->mimeid) { + /* + * if it's got a file name, use it. Else use the mime-id for identifying + * this part, and hope there's no other files encoded in the same message + * under the same id. + */ + if (result->filename) + result->subfname = _FP_strdup (result->filename); + else + result->subfname = _FP_strdup (result->mimeid); + } + else if (result->subfname == NULL && data->uudet) { + /* + * ff we have lastvalid, use it. Make an exception for + * Base64-encoded files. + */ + if (data->uudet == B64ENCODED) { + /* + * Assume it's the first part. I wonder why it's got no part number? + */ + if (result->filename != NULL) + result->subfname = _FP_strdup (result->filename); + else { /* if not, escape to UNKNOWN. We need to fill subfname */ + sprintf (temp, "%s.%03d", nofname, ++nofnum); + result->subfname = _FP_strdup (temp); + } + if (result->subfname == NULL) { + UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), + (result->filename)? + (strlen(result->filename)+1):(strlen(temp)+1)); + *ret = UURET_NOMEM; + UUkillfile (result); + return NULL; + } + lastvalid = 0; + } + else if (lastvalid && data->uudet == lastenc) { + result->subfname = _FP_strdup (uucheck_lastname); + result->partno = ++lastpart; + + /* + * if it's the last part, invalidate lastvalid + */ + if (data->end || (data->partno && data->partno == data->maxpno)) + lastvalid = 0; + } + else { + /* + * it's got no info, it's got no begin, and we don't know anything + * about this part. Let's forget all about it. + */ + *ret = UURET_NODATA; + UUkillfile (result); + return NULL; + } + } + else if (result->subfname == NULL && result->partno == -1) { + /* + * This, too, is a part without any useful information that we + * should forget about. + */ + *ret = UURET_NODATA; + UUkillfile (result); + return NULL; + } + else if (result->subfname == NULL) { + /* + * This is a part without useful subject name, a valid part number + * but no encoded data. It *could* be the zeroeth part of something, + * but we don't care here. Just forget it. + */ + *ret = UURET_NODATA; + UUkillfile (result); + return NULL; + } + + /* + * now, handle some cases where we have a useful subject but no + * useful part number + */ + + if (result->partno == -1 && data->begin) { + /* + * hmm, this is reason enough to initialize lastvalid, at least + * if we have no end + */ + if (!data->end) { + _FP_strncpy (uucheck_lastname, result->subfname, 256); + result->partno = lastpart = 1; + lastenc = data->uudet; + lastvalid = 1; + } + else + result->partno = 1; + } + else if (result->partno == -1 && data->uudet) { + if (lastvalid && _FP_stricmp (uucheck_lastname, result->subfname) == 0) { + /* + * if the subject filename is the same as last time, use part no + * of lastvalid. If at end, invalidate lastvalid + */ + result->partno = ++lastpart; + + if (data->end) + lastvalid = 0; + } + else { + /* + * data but no part no. It's something UUInsertPartToList() should + * handle + */ + goto skipcheck; + } + } + else if (result->partno == -1) { + /* + * it's got no data, so why should we need this one anyway? + */ + *ret = UURET_NODATA; + UUkillfile (result); + return NULL; + } + + /* + * at this point, the part should have a valid subfname and a valid + * part number. If it doesn't, then fail. + */ + if (result->subfname == NULL || result->partno == -1) { + *ret = UURET_NODATA; + UUkillfile (result); + return NULL; + } + + skipcheck: + + if (result->filename) { + if (*(ptr = _FP_cutdir (result->filename))) { + p2 = _FP_strdup (ptr); + _FP_free (result->filename); + result->filename = p2; + } + } + + result->data = data; + result->NEXT = NULL; + + *ret = UURET_OK; + + return result; +} + +/* + * Insert one part of a file into the global list + **/ + +int +UUInsertPartToList (uufile *data) +{ + uulist *iter = UUGlobalFileList, *unew; + uufile *fiter, *last; + + /* + * Part belongs together, if + * (a) The file name received from the subject lines match _or_ + * the MIME-IDs match, + * (b) Not both parts have a begin line + * (c) Not both parts have an end line + * (d) Both parts don't have different MIME-IDs + * (e) Both parts don't encode different files + * (f) The other part wants to stay alone (FL_SINGLE) + */ + + /* + * check if this part wants to be left alone. If so, don't bother + * to do all the checks + */ + + while (iter) { + if (data->data->flags & FL_SINGLE) { + /* this space intentionally left blank */ + } + else if ((_FP_stricmp (data->subfname, iter->subfname) == 0 || + (data->mimeid && iter->mimeid && + strcmp (data->mimeid, iter->mimeid) == 0)) && + !(iter->begin && data->data->begin) && + !(iter->end && data->data->end) && + !(data->mimeid && iter->mimeid && + strcmp (data->mimeid, iter->mimeid) != 0) && + !(data->filename && iter->filename && + strcmp (data->filename, iter->filename) != 0) && + !(iter->flags & FL_SINGLE)) { + + /* + * if we already have this part, don't try to insert it + */ + + for (fiter=iter->thisfile; + fiter && (data->partno>fiter->partno) && !fiter->data->end; + fiter=fiter->NEXT) + /* empty loop */ ; + if (fiter && + (data->partno==fiter->partno || + (data->partno > fiter->partno && fiter->data->end))) + goto goahead; + + if (iter->filename == NULL && data->filename != NULL) { + if ((iter->filename = _FP_strdup (data->filename)) == NULL) + return UURET_NOMEM; + } + + /* + * special case when we might have tagged a part as Base64 when the + * file was really XX + */ + + if (data->data->uudet == B64ENCODED && + iter->uudet == XX_ENCODED && iter->begin) { + data->data->uudet = XX_ENCODED; + } + else if (data->data->uudet == XX_ENCODED && data->data->begin && + iter->uudet == B64ENCODED) { + iter->uudet = XX_ENCODED; + + fiter = iter->thisfile; + while (fiter) { + fiter->data->uudet = XX_ENCODED; + fiter = fiter->NEXT; + } + } + + /* + * If this is from a Message/Partial, we believe only the + * iter->uudet from the first part + */ + if (data->data->flags & FL_PARTIAL) { + if (data->partno == 1) { + iter->uudet = data->data->uudet; + iter->flags = data->data->flags; + } + } + else { + if (data->data->uudet) iter->uudet = data->data->uudet; + if (data->data->flags) iter->flags = data->data->flags; + } + + if (iter->mode == 0 && data->data->mode != 0) + iter->mode = data->data->mode; + if (data->data->begin) iter->begin = (data->partno)?data->partno:1; + if (data->data->end) iter->end = (data->partno)?data->partno:1; + + if (data->mimetype) { + _FP_free (iter->mimetype); + iter->mimetype = _FP_strdup (data->mimetype); + } + + /* + * insert part at the beginning + */ + + if (data->partno != -1 && data->partno < iter->thisfile->partno) { + iter->state = UUFILE_READ; + data->NEXT = iter->thisfile; + iter->thisfile = data; + return UURET_OK; + } + + /* + * insert part somewhere else + */ + + iter->state = UUFILE_READ; /* prepare for re-checking */ + fiter = iter->thisfile; + last = NULL; + + while (fiter) { + /* + * if we find the same part no again, check which one looks better + */ + if (data->partno == fiter->partno) { + if (fiter->data->subject == NULL) + return UURET_NODATA; + else if (_FP_stristr (fiter->data->subject, "repost") != NULL && + _FP_stristr (data->data->subject, "repost") == NULL) + return UURET_NODATA; + else if (fiter->data->uudet && !data->data->uudet) + return UURET_NODATA; + else { + /* + * replace + */ + data->NEXT = fiter->NEXT; + fiter->NEXT = NULL; + UUkillfile (fiter); + + if (last == NULL) + iter->thisfile = data; + else + last->NEXT = data; + + return UURET_OK; + } + } + + /* + * if at the end of the part list, add it + */ + + if (fiter->NEXT == NULL || + (data->partno != -1 && data->partno < fiter->NEXT->partno)) { + data->NEXT = fiter->NEXT; + fiter->NEXT = data; + + if (data->partno == -1) + data->partno = fiter->partno + 1; + + return UURET_OK; + } + last = fiter; + fiter = fiter->NEXT; + } + + return UURET_OK; /* Shouldn't get here */ + } + goahead: + /* + * we need iter below + */ + if (iter->NEXT == NULL) + break; + + iter = iter->NEXT; + } + /* + * handle new entry + */ + + if (data->partno == -1) { + /* + * if it's got no part no, and it's MIME mail, then assume this is + * part no. 1. If it's not MIME, then we can't handle it; if it + * had a 'begin', it'd have got a part number assigned by + * UUPreProcessPart(). + */ + if (data->data->uudet == B64ENCODED || data->data->uudet == BH_ENCODED) + data->partno = 1; + else + return UURET_NODATA; + } + + if ((unew = (uulist *) malloc (sizeof (uulist))) == NULL) { + return UURET_NOMEM; + } + + if ((unew->subfname = _FP_strdup (data->subfname)) == NULL) { + _FP_free (unew); + return UURET_NOMEM; + } + + if (data->filename != NULL) { + if ((unew->filename = _FP_strdup (data->filename)) == NULL) { + _FP_free (unew->subfname); + _FP_free (unew); + return UURET_NOMEM; + } + } + else + unew->filename = NULL; + + if (data->mimeid != NULL) { + if ((unew->mimeid = _FP_strdup (data->mimeid)) == NULL) { + _FP_free (unew->subfname); + _FP_free (unew->filename); + _FP_free (unew); + return UURET_NOMEM; + } + } + else + unew->mimeid = NULL; + + if (data->mimetype != NULL) { + if ((unew->mimetype = _FP_strdup (data->mimetype)) == NULL) { + _FP_free (unew->mimeid); + _FP_free (unew->subfname); + _FP_free (unew->filename); + _FP_free (unew); + return UURET_NOMEM; + } + } + else + unew->mimetype = NULL; + + unew->state = UUFILE_READ; + unew->binfile = NULL; + unew->thisfile = data; + unew->mode = data->data->mode; + unew->uudet = data->data->uudet; + unew->flags = data->data->flags; + unew->begin = (data->data->begin) ? ((data->partno)?data->partno:1) : 0; + unew->end = (data->data->end) ? ((data->partno)?data->partno:1) : 0; + unew->misparts = NULL; + unew->haveparts = NULL; + unew->NEXT = NULL; + + if (iter == NULL) + UUGlobalFileList = unew; + else + iter->NEXT = unew; + + return UURET_OK; +} + +/* + * At this point, all files are read in and stored in the + * "UUGlobalFileList". Do some checking. All parts there? + **/ + +uulist * +UUCheckGlobalList (void) +{ + int misparts[MAXPLIST], haveparts[MAXPLIST]; + int miscount, havecount, count, flag, part; + uulist *liter=UUGlobalFileList, *prev; + uufile *fiter; + long thesize; + + while (liter) { + miscount = 0; + thesize = 0; + + if (liter->state & UUFILE_OK) { + liter = liter->NEXT; + continue; + } + else if ((liter->uudet == QP_ENCODED || + liter->uudet == PT_ENCODED) && + (liter->flags & FL_SINGLE)) { + if ((liter->flags&FL_PROPER)==0) + liter->size = -1; + else + liter->size = liter->thisfile->data->length; + + liter->state = UUFILE_OK; + continue; + } + else if ((fiter = liter->thisfile) == NULL) { + liter->state = UUFILE_NODATA; + liter = liter->NEXT; + continue; + } + + /* + * Re-Check this file + */ + + flag = 0; + miscount = 0; + havecount = 0; + thesize = 0; + liter->state = UUFILE_READ; + + /* + * search encoded data + */ + + while (fiter && !fiter->data->uudet) { + if (havecountpartno; + } + fiter = fiter->NEXT; + } + + if (fiter == NULL) { + liter->state = UUFILE_NODATA; + liter = liter->NEXT; + continue; + } + + if (havecountpartno; + } + + if ((part = fiter->partno) > 1) { + if (!fiter->data->begin) { + for (count=1; count < part && miscount < MAXPLIST; count++) + misparts[miscount++] = count; + } + } + + /* + * don't care if so many parts are missing + */ + + if (miscount >= MAXPLIST) { + liter->state = UUFILE_MISPART; + liter = liter->NEXT; + continue; + } + + if (liter->uudet == B64ENCODED || + liter->uudet == QP_ENCODED || + liter->uudet == PT_ENCODED) + flag |= 3; /* Don't need begin or end with Base64 or plain text*/ + + if (fiter->data->begin) flag |= 1; + if (fiter->data->end) flag |= 2; + if (fiter->data->uudet) flag |= 4; + + /* + * guess size of part + */ + + switch (fiter->data->uudet) { + case UU_ENCODED: + case XX_ENCODED: + thesize += 3*fiter->data->length/4; + thesize -= 3*fiter->data->length/124; /* substract 2 of 62 chars */ + break; + case B64ENCODED: + thesize += 3*fiter->data->length/4; + thesize -= fiter->data->length/52; /* substract 2 of 78 chars */ + break; + case QP_ENCODED: + case PT_ENCODED: + thesize += fiter->data->length; + break; + } + + fiter = fiter->NEXT; + + while (fiter != NULL) { + for (count=part+1; countpartno && miscountpartno; + + if (havecountdata->begin) flag |= 1; + if (fiter->data->end) flag |= 2; + if (fiter->data->uudet) flag |= 4; + + switch (fiter->data->uudet) { + case UU_ENCODED: + case XX_ENCODED: + thesize += 3*fiter->data->length/4; + thesize -= 3*fiter->data->length/124; /* substract 2 of 62 chars */ + break; + case B64ENCODED: + thesize += 3*fiter->data->length/4; + thesize -= fiter->data->length/52; /* substract 2 of 78 chars */ + break; + case QP_ENCODED: + case PT_ENCODED: + thesize += fiter->data->length; + break; + } + + if (fiter->data->end) + break; + + fiter = fiter->NEXT; + } + + /* + * if in fast mode, we don't notice an 'end'. So if its uu or xx + * encoded, there's a begin line and encoded data, assume it's + * there. + */ + + if (uu_fast_scanning && (flag & 0x01) && (flag & 0x04) && + (liter->uudet == UU_ENCODED || liter->uudet == XX_ENCODED)) + flag |= 2; + + /* + * Set the parts we have and/or missing + */ + + _FP_free (liter->haveparts); + _FP_free (liter->misparts); + + liter->haveparts = NULL; + liter->misparts = NULL; + + if (havecount) { + if ((liter->haveparts=(int*)malloc((havecount+1)*sizeof(int)))!=NULL) { + memcpy (liter->haveparts, haveparts, havecount*sizeof(int)); + liter->haveparts[havecount] = 0; + } + } + + if (miscount) { + if ((liter->misparts=(int*)malloc((miscount+1)*sizeof(int)))!=NULL) { + memcpy (liter->misparts, misparts, miscount*sizeof(int)); + liter->misparts[miscount] = 0; + } + liter->state |= UUFILE_MISPART; + } + + /* + * Finalize checking + */ + + if ((flag & 4) == 0) liter->state |= UUFILE_NODATA; + if ((flag & 1) == 0) liter->state |= UUFILE_NOBEGIN; + if ((flag & 2) == 0) liter->state |= UUFILE_NOEND; + + if ((flag & 7) == 7 && miscount==0) { + liter->state = UUFILE_OK; + } + + if ((uu_fast_scanning && (liter->flags&FL_PROPER)==0) || thesize<=0) + liter->size = -1; + else + liter->size = thesize; + + if (liter->state==UUFILE_OK && + (liter->filename==NULL || liter->filename[0]=='\0')) { + /* + * Emergency backup if the file does not have a filename + */ + _FP_free (liter->filename); + if (liter->subfname && liter->subfname[0] && + _FP_strpbrk (liter->subfname, "()[];: ") == NULL) + liter->filename = _FP_strdup (liter->subfname); + else { + sprintf (uucheck_tempname, "%s.%03d", nofname, ++nofnum); + liter->filename = _FP_strdup (uucheck_tempname); + } + } + liter = liter->NEXT; + } + + /* + * Sets back (PREV) links + */ + + liter = UUGlobalFileList; + prev = NULL; + + while (liter) { + liter->PREV = prev; + prev = liter; + liter = liter->NEXT; + } + + return UUGlobalFileList; +} + + +/***************************************************************************** + + Frank Pilhofer fp@informatik.uni-frankfurt.de + + +---------------------------------------------------------------------------+ + | Department of Computer Sciences * University of Frankfurt / Main, Germany | + *****************************************************************************/ diff --git a/goldlib/uulib/uudeview.h b/goldlib/uulib/uudeview.h new file mode 100644 index 0000000..00ff19d --- /dev/null +++ b/goldlib/uulib/uudeview.h @@ -0,0 +1,245 @@ +/* + * This file is part of uudeview, the simple and friendly multi-part multi- + * file uudecoder program (c) 1994 by Frank Pilhofer. The author may be + * contacted by his email address, fp@informatik.uni-frankfurt.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __UUDEVIEW_H__ +#define __UUDEVIEW_H__ + +/* + * This include file features all the definitions that should + * be externally visible. This isn't much. + * + * $Id$ + */ + +#ifndef _ANSI_ARGS_ +#ifdef PROTOTYPES +#define _ANSI_ARGS_(c) c +#else +#define _ANSI_ARGS_(c) () +#endif +#endif + +/* + * Message Types + */ + +#define UUMSG_MESSAGE (0) /* just a message, nothing important */ +#define UUMSG_NOTE (1) /* something that should be noticed */ +#define UUMSG_WARNING (2) /* important msg, processing continues */ +#define UUMSG_ERROR (3) /* processing has been terminated */ +#define UUMSG_FATAL (4) /* decoder cannot process further requests */ +#define UUMSG_PANIC (5) /* recovery impossible, app must terminate */ + +/* + * Return Values + */ + +#define UURET_OK (0) /* everything went fine */ +#define UURET_IOERR (1) /* I/O Error - examine errno */ +#define UURET_NOMEM (2) /* not enough memory */ +#define UURET_ILLVAL (3) /* illegal value for operation */ +#define UURET_NODATA (4) /* decoder didn't find any data */ +#define UURET_NOEND (5) /* encoded data wasn't ended properly */ +#define UURET_UNSUP (6) /* unsupported function (encoding) */ +#define UURET_EXISTS (7) /* file exists (decoding) */ +#define UURET_CONT (8) /* continue -- special from ScanPart */ +#define UURET_CANCEL (9) /* operation canceled */ + +/* + * File states, may be OR'ed + */ + +#define UUFILE_READ (0) /* Read in, but not further processed */ +#define UUFILE_MISPART (1) /* Missing Part(s) detected */ +#define UUFILE_NOBEGIN (2) /* No 'begin' found */ +#define UUFILE_NOEND (4) /* No 'end' found */ +#define UUFILE_NODATA (8) /* File does not contain valid uudata */ +#define UUFILE_OK (16) /* All Parts found, ready to decode */ +#define UUFILE_ERROR (32) /* Error while decoding */ +#define UUFILE_DECODED (64) /* Successfully decoded */ +#define UUFILE_TMPFILE (128) /* Temporary decoded file exists */ + +/* + * Encoding Types + */ + +#define UU_ENCODED (1) /* UUencoded data */ +#define B64ENCODED (2) /* Mime-Base64 data */ +#define XX_ENCODED (3) /* XXencoded data */ +#define BH_ENCODED (4) /* Binhex encoded */ +#define PT_ENCODED (5) /* Plain-Text encoded (MIME) */ +#define QP_ENCODED (6) /* Quoted-Printable (MIME) */ + +/* + * Option indices for GetOption / SetOption + */ + +#define UUOPT_VERSION (0) /* version number MAJOR.MINORplPATCH (ro) */ +#define UUOPT_FAST (1) /* assumes only one part per file */ +#define UUOPT_DUMBNESS (2) /* switch off the program's intelligence */ +#define UUOPT_BRACKPOL (3) /* give numbers in [] higher precendence */ +#define UUOPT_VERBOSE (4) /* generate informative messages */ +#define UUOPT_DESPERATE (5) /* try to decode incomplete files */ +#define UUOPT_IGNREPLY (6) /* ignore RE:plies (off by default) */ +#define UUOPT_OVERWRITE (7) /* whether it's OK to overwrite ex. files */ +#define UUOPT_SAVEPATH (8) /* prefix to save-files on disk */ +#define UUOPT_IGNMODE (9) /* ignore the original file mode */ +#define UUOPT_DEBUG (10) /* print messages with FILE/LINE info */ +#define UUOPT_ERRNO (14) /* get last error code for UURET_IOERR (ro) */ +#define UUOPT_PROGRESS (15) /* retrieve progress information */ +#define UUOPT_USETEXT (16) /* handle text messages */ +#define UUOPT_PREAMB (17) /* handle Mime preambles/epilogues */ +#define UUOPT_TINYB64 (18) /* detect short B64 outside of Mime */ +#define UUOPT_ENCEXT (19) /* extension for single-part encoded files */ + +/* + * Code for the "action" in the progress structure + */ + +#define UUACT_IDLE (0) /* we don't do anything */ +#define UUACT_SCANNING (1) /* scanning an input file */ +#define UUACT_DECODING (2) /* decoding into a temp file */ +#define UUACT_COPYING (3) /* copying temp to target */ +#define UUACT_ENCODING (4) /* encoding a file */ + +/* + * forward definition + */ + +struct _uufile; + +/* + * Structure for holding the list of files that have been found + * uufile items are inserted into this list with UUInsertPartToList + * After inserting a bunch of files, UUCheckGlobalList must be called + * to update the states. + */ + +typedef struct _uulist { + short state; /* Status as described by the macros above */ + short mode; /* file mode as found on begin line */ + + int begin; /* part number where begin was detected */ + int end; /* part number where end was detected */ + + short uudet; /* Encoding type (see macros above) */ + int flags; /* flags, especially for single-part files */ + + long size; /* approximate size of resulting file */ + char *filename; /* malloc'ed file name */ + char *subfname; /* malloc'ed ID from subject line */ + char *mimeid; /* malloc'ed MIME-ID, if available */ + char *mimetype; /* malloc'ed Content-Type, if available */ + + char *binfile; /* name of temp file, if already decoded */ + + struct _uufile *thisfile; /* linked list of this file's parts */ + + int *haveparts; /* the parts we have (max. 256 are listed) */ + int *misparts; /* list of missing parts (max. 256) */ + + struct _uulist *NEXT; /* next item of the list */ + struct _uulist *PREV; /* previous item of the list */ +} uulist; + +/* + * The "progress" structure which is passed to the Busy Callback + */ + +typedef struct { + int action; /* see UUACT_* definitions above */ + char curfile[256]; /* the file we are working on, incl. path */ + int partno; /* part we're currently decoding */ + int numparts; /* total number of parts of this file */ + long fsize; /* size of the current file */ + int percent; /* % of _current part_ */ + long foffset; /* file offset -- internal use only */ + long totsize; /* file total size -- internal use only */ +} uuprogress; + + +/* + * Externally visible Functions + */ + +#ifndef UUEXPORT +#define UUEXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int UUEXPORT UUInitialize _ANSI_ARGS_((void)); +int UUEXPORT UUGetOption _ANSI_ARGS_((int, int *, char *, int)); +int UUEXPORT UUSetOption _ANSI_ARGS_((int, int, char *)); +char * UUEXPORT UUstrerror _ANSI_ARGS_((int)); +int UUEXPORT UUSetMsgCallback _ANSI_ARGS_((void *, + void (*) (void *, + char *, + int))); +int UUEXPORT UUSetBusyCallback _ANSI_ARGS_((void *, + int (*) (void *, + uuprogress *), + long)); +int UUEXPORT UUSetFileCallback _ANSI_ARGS_((void *, + int (*) (void *, char *, + char *, int))); +int UUEXPORT UUSetFNameFilter _ANSI_ARGS_((void *, + char * (*) (void *, + char *))); +char * UUEXPORT UUFNameFilter _ANSI_ARGS_((char *)); +int UUEXPORT UULoadFile _ANSI_ARGS_((char *, char *, int)); +uulist *UUEXPORT UUGetFileListItem _ANSI_ARGS_((int)); +int UUEXPORT UURenameFile _ANSI_ARGS_((uulist *, char *)); +int UUEXPORT UUDecodeToTemp _ANSI_ARGS_((uulist *)); +int UUEXPORT UURemoveTemp _ANSI_ARGS_((uulist *)); +int UUEXPORT UUDecodeFile _ANSI_ARGS_((uulist *, char *)); +int UUEXPORT UUInfoFile _ANSI_ARGS_((uulist *, void *, + int (*) (void *, + char *))); +int UUEXPORT UUSmerge _ANSI_ARGS_((int)); +int UUEXPORT UUCleanUp _ANSI_ARGS_((void)); + +int UUEXPORT UUQuickDecode _ANSI_ARGS_((FILE *, FILE *, + char *, long)); + +int UUEXPORT UUEncodeMulti _ANSI_ARGS_((FILE *, FILE *, + char *, int, + char *, char *, int)); +int UUEXPORT UUEncodePartial _ANSI_ARGS_((FILE *, FILE *, + char *, int, + char *, char *, + int, int, long)); +int UUEXPORT UUEncodeToStream _ANSI_ARGS_((FILE *, FILE *, + char *, int, + char *, int)); +int UUEXPORT UUEncodeToFile _ANSI_ARGS_((FILE *, char *, int, + char *, char *, long)); +int UUEXPORT UUE_PrepSingle _ANSI_ARGS_((FILE *, FILE *, + char *, int, + char *, int, + char *, char *, + char *, int)); +int UUEXPORT UUE_PrepPartial _ANSI_ARGS_((FILE *, FILE *, + char *, int, + char *, int, + int, long, long, char *, + char *, char *, int)); +#ifdef __cplusplus +} +#endif +#endif diff --git a/goldlib/uulib/uuencode.c b/goldlib/uulib/uuencode.c new file mode 100644 index 0000000..106a5d3 --- /dev/null +++ b/goldlib/uulib/uuencode.c @@ -0,0 +1,1230 @@ +/* + * This file is part of uudeview, the simple and friendly multi-part multi- + * file uudecoder program (c) 1994 by Frank Pilhofer. The author may be + * contacted by his email address, fp@informatik.uni-frankfurt.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SYSTEM_WINDLL +#include +#endif +#ifdef SYSTEM_OS2 +#include +#endif + +#include +#include +#include +#include +#include + +#ifdef STDC_HEADERS +#include +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif + +#include +#include +#include +#include + +/* for braindead systems */ +#ifndef SEEK_SET +#ifdef L_BEGIN +#define SEEK_SET L_BEGIN +#else +#define SEEK_SET 0 +#endif +#endif + +char * uuencode_id = "$Id$"; + +#if 0 +/* + * the End-Of-Line string. MIME enforces CRLF, so that's what we use. Some + * implementations of uudecode will complain about a missing end line, since + * they look for "end^J" but find "end^J^M". We don't care - especially be- + * cause they still decode the file properly despite this complaint. + */ + +#ifndef EOLSTRING +#define EOLSTRING "\015\012" +#endif + +#else + +/* + * Argh. Some delivery software (inews) has problems with the CRLF + * line termination. Let's try native EOL and see if we run into + * any problems. + * This involves opening output files in text mode instead of binary + */ + +#ifndef EOLSTRING +#define EOLSTRING "\n" +#endif + +#endif + + +/* + * ========================================================================= + * User-configurable settings end here. Don't spy below unless you know what + * you're doing. + * ========================================================================= + */ + +/* + * Define End-Of-Line sequence + */ + +#ifdef EOLSTRING +static unsigned char *eolstring = (unsigned char *) EOLSTRING; +#else +static unsigned char *eolstring = (unsigned char *) "\012"; +#endif + +/* + * Content-Transfer-Encoding types for non-MIME encodings + */ + +#define CTE_UUENC "x-uuencode" +#define CTE_XXENC "x-xxencode" +#define CTE_BINHEX "x-binhex" + +#define CTE_TYPE(y) (((y)==B64ENCODED) ? "Base64" : \ + ((y)==UU_ENCODED) ? CTE_UUENC : \ + ((y)==XX_ENCODED) ? CTE_XXENC : \ + ((y)==BH_ENCODED) ? CTE_BINHEX : "x-oops") + +/* + * encoding tables + */ + +unsigned char UUEncodeTable[64] = { + '`', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\',']', '^', '_' +}; + + +unsigned char B64EncodeTable[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/' +}; + +unsigned char XXEncodeTable[64] = { + '+', '-', '0', '1', '2', '3', '4', '5', + '6', '7', '8', '9', 'A', 'B', 'C', 'D', + 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', + 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', + 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' +}; + +unsigned char BHEncodeTable[64] = { + '!', '"', '#', '$', '%', '&', '\'', '(', + ')', '*', '+', ',', '-', '0', '1', '2', + '3', '4', '5', '6', '8', '9', '@', 'A', + 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', + 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'h', + 'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r' +}; + +typedef struct { + char *extension; + char *mimetype; +} mimemap; + +/* + * This table maps a file's extension into a Content-Type. The current + * official list can be downloaded as + * ftp://ftp.isi.edu/in-notes/iana/assignments/media-type + * I haven't listed any text types since it doesn't make sense to encode + * them. Everything not on the list gets mapped to application/octet-stream + */ + +static mimemap mimetable[] = { + { "gif", "image/gif" }, /* Grafics Interchange Format */ + { "jpg", "image/jpeg" }, /* JFIF encoded files */ + { "jpeg", "image/jpeg" }, + { "tif", "image/tiff" }, /* Tag Image File Format */ + { "tiff", "image/tiff" }, + { "cgm", "image/cgm" }, /* Computer Graphics Metafile */ + { "au", "audio/basic" }, /* 8kHz ulaw audio data */ + { "mov", "video/quicktime" }, /* Apple Quicktime */ + { "qt", "video/quicktime" }, /* Also infrequently used */ + { "mpeg", "video/mpeg" }, /* Motion Picture Expert Group */ + { "mpg", "video/mpeg" }, + { "mp2", "video/mpeg" }, /* dito, MPEG-2 encoded files */ + { "mp3", "video/mpeg" }, /* dito, MPEG-3 encoded files */ + { "ps", "application/postscript" }, /* Postscript Language */ + { "zip", "application/zip" }, /* ZIP archive */ + { "doc", "application/msword"},/* assume Microsoft Word */ + { NULL, NULL } +}; + +/* + * the order of the following two tables must match the + * Encoding Types definition in uudeview.h + */ + +/* + * encoded bytes per line + */ + +static int bpl[5] = { 0, 45, 57, 45, 45 }; + +/* + * tables + */ + +static unsigned char *etables[5] = { + NULL, + UUEncodeTable, + B64EncodeTable, + XXEncodeTable, + BHEncodeTable +}; + +/* + * variables to malloc upon initialization + */ + +char *uuestr_itemp; +char *uuestr_otemp; + +/* + * Encode one part of the data stream + */ + +static int +UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile) +{ + unsigned char *itemp = (char *) uuestr_itemp; + unsigned char *otemp = (char *) uuestr_otemp; + unsigned char *optr, *table, *tptr; + int index, count; + long line=0; + size_t llen; + + if (outfile==NULL || infile==NULL || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUEncodeStream()"); + return UURET_ILLVAL; + } + + + /* + * select charset + */ + + table = etables[encoding]; + + if (table==NULL || bpl[encoding]==0) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUEncodeStream()"); + return UURET_ILLVAL; + } + + while (!feof (infile) && (linperfile <= 0 || line < linperfile)) { + if ((count = fread (itemp, 1, bpl[encoding], infile)) != bpl[encoding]) { + if (count == 0) + break; + else if (ferror (infile)) + return UURET_IOERR; + } + optr = otemp; + llen = 0; + + /* + * Busy Callback + */ + + if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) { + UUMessage (uuencode_id, __LINE__, UUMSG_NOTE, + uustring (S_ENCODE_CANCEL)); + return UURET_CANCEL; + } + + /* + * for UU and XX, encode the number of bytes as first character + */ + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + *optr++ = table[count]; + llen++; + } + + for (index=0; index<=count-3; index+=3, llen+=4) { + *optr++ = table[itemp[index] >> 2]; + *optr++ = table[((itemp[index ] & 0x03) << 4) | (itemp[index+1] >> 4)]; + *optr++ = table[((itemp[index+1] & 0x0f) << 2) | (itemp[index+2] >> 6)]; + *optr++ = table[ itemp[index+2] & 0x3f]; + } + + /* + * Special handling for incomplete lines + */ + if (index != count) { + if (encoding == B64ENCODED) { + if (count - index == 2) { + *optr++ = table[itemp[index] >> 2]; + *optr++ = table[((itemp[index ] & 0x03) << 4) | + ((itemp[index+1] & 0xf0) >> 4)]; + *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; + *optr++ = '='; + } + else if (count - index == 1) { + *optr++ = table[ itemp[index] >> 2]; + *optr++ = table[(itemp[index] & 0x03) << 4]; + *optr++ = '='; + *optr++ = '='; + } + llen += 4; + } + else { + if (count - index == 2) { + *optr++ = table[itemp[index] >> 2]; + *optr++ = table[((itemp[index ] & 0x03) << 4) | + ( itemp[index+1] >> 4)]; + *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; + *optr++ = table[0]; + } + else if (count - index == 1) { + *optr++ = table[ itemp[index] >> 2]; + *optr++ = table[(itemp[index] & 0x03) << 4]; + *optr++ = table[0]; + *optr++ = table[0]; + } + llen += 4; + } + } + /* + * end of line + */ + tptr = eolstring; + + while (*tptr) + *optr++ = *tptr++; + + *optr++ = '\0'; + llen += strlen ((char *) eolstring); + + if (fwrite (otemp, 1, llen, outfile) != llen) + return UURET_IOERR; + + line++; + } + return UURET_OK; +} + +/* + * Encode as MIME multipart/mixed sub-message. + */ + +int UUEXPORT +UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding, + char *outfname, char *mimetype, int filemode) +{ + mimemap *miter=mimetable; + struct stat finfo; + int res, themode; + FILE *theifile; + char *ptr; + + if (outfile==NULL || + (infile == NULL && infname==NULL) || + (outfname==NULL && infname==NULL) || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUEncodeMulti()"); + return UURET_ILLVAL; + } + + progress.action = 0; + + if (infile==NULL) { + if (stat (infname, &finfo) == -1) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + if ((theifile = fopen (infname, "rb")) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); + progress.fsize = (long) finfo.st_size; + } + else { + if (fstat (fileno (infile), &finfo) != 0) { + themode = (filemode)?filemode:0644; + progress.fsize = -1; + } + else { + themode = (int) finfo.st_mode & 0777; + progress.fsize = (long) finfo.st_size; + } + theifile = infile; + } + + if (progress.fsize <= 0) + progress.fsize = -1; + + _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); + + progress.partno = 1; + progress.numparts = 1; + progress.percent = 0; + progress.foffset = 0; + progress.action = UUACT_ENCODING; + + /* + * If not given from outside, select an appropriate Content-Type by + * looking at the file's extension. If it is unknown, default to + * Application/Octet-Stream + */ + + if (mimetype == NULL) { + if ((ptr = _FP_strrchr ((outfname)?outfname:infname, '.'))) { + while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0) + miter++; + mimetype = miter->mimetype; + } + } + /* + * print sub-header + */ + + fprintf (outfile, "Content-Type: %s%s", + (mimetype)?mimetype:"Application/Octet-Stream", + eolstring); + fprintf (outfile, "Content-Transfer-Encoding: %s%s", + CTE_TYPE(encoding), eolstring); + fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", + UUFNameFilter ((outfname)?outfname:infname), eolstring); + fprintf (outfile, "%s", eolstring); + + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + fprintf (outfile, "begin %o %s%s", + (themode) ? themode : 0644, + UUFNameFilter ((outfname)?outfname:infname), + eolstring); + } + if ((res = UUEncodeStream (outfile, theifile, encoding, 0)) != UURET_OK) { + if (res != UURET_CANCEL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_ERR_ENCODING), + UUFNameFilter ((infname)?infname:outfname), + (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res)); + } + progress.action = 0; + return res; + } + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + fprintf (outfile, "%c%s", + (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], + eolstring); + fprintf (outfile, "end%s", eolstring); + } + /* + * empty line at end does no harm + */ + fprintf (outfile, "%s", eolstring); + + if (infile==NULL) + fclose (theifile); + + progress.action = 0; + return UURET_OK; +} + +/* + * Encode as MIME message/partial + */ + +int UUEXPORT +UUEncodePartial (FILE *outfile, FILE *infile, + char *infname, int encoding, + char *outfname, char *mimetype, + int filemode, int partno, long linperfile) +{ + mimemap *miter=mimetable; + static FILE *theifile; + int themode, numparts; + struct stat finfo; + long thesize; + char *ptr; + int res; + + if ((outfname==NULL&&infname==NULL) || partno<=0 || + (infile == NULL&&infname==NULL) || outfile==NULL || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUEncodePartial()"); + return UURET_ILLVAL; + } + + /* + * The first part needs a set of headers + */ + + progress.action = 0; + + if (partno == 1) { + if (infile==NULL) { + if (stat (infname, &finfo) == -1) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + if ((theifile = fopen (infname, "rb")) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ + (linperfile*bpl[encoding])); + + themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); + thesize = (long) finfo.st_size; + } + else { + if (fstat (fileno (infile), &finfo) != 0) { + UUMessage (uuencode_id, __LINE__, UUMSG_WARNING, + uustring (S_STAT_ONE_PART)); + numparts = 1; + themode = (filemode)?filemode:0644; + thesize = 0; + } + else { + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ + (linperfile*bpl[encoding])); + + themode = (int) finfo.st_mode & 0777; + thesize = (long) finfo.st_size; + } + theifile = infile; + } + + _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); + + progress.totsize = (thesize>0) ? thesize : -1; + progress.partno = 1; + progress.numparts = numparts; + progress.percent = 0; + progress.foffset = 0; + + /* + * If not given from outside, select an appropriate Content-Type by + * looking at the file's extension. If it is unknown, default to + * Application/Octet-Stream + */ + + if (mimetype == NULL) { + if ((ptr = _FP_strrchr ((outfname)?outfname:infname, '.'))) { + while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0) + miter++; + mimetype = miter->mimetype; + } + } + /* + * print sub-header + */ + + fprintf (outfile, "MIME-Version: 1.0%s", eolstring); + fprintf (outfile, "Content-Type: %s%s", + (mimetype)?mimetype:"Application/Octet-Stream", + eolstring); + fprintf (outfile, "Content-Transfer-Encoding: %s%s", + CTE_TYPE(encoding), eolstring); + fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", + UUFNameFilter ((outfname)?outfname:infname), eolstring); + fprintf (outfile, "%s", eolstring); + + /* + * for the first part of UU or XX messages, print a begin line + */ + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + fprintf (outfile, "begin %o %s%s", + (themode) ? themode : ((filemode)?filemode:0644), + UUFNameFilter ((outfname)?outfname:infname), eolstring); + } + } + + /* + * update progress information + */ + + progress.partno = partno; + progress.percent = 0; + progress.foffset = ftell (theifile); + + if (progress.totsize <= 0) + progress.fsize = -1; + else if (linperfile <= 0) + progress.fsize = progress.totsize; + else if (progress.foffset+linperfile*bpl[encoding] > progress.totsize) + progress.fsize = progress.totsize - progress.foffset; + else + progress.fsize = linperfile*bpl[encoding]; + + progress.action = UUACT_ENCODING; + + if ((res = UUEncodeStream (outfile, theifile, + encoding, linperfile)) != UURET_OK) { + if (infile==NULL) fclose (theifile); + if (res != UURET_CANCEL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_ERR_ENCODING), + UUFNameFilter ((outfname)?outfname:infname), + (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res)); + } + progress.action = 0; + return res; + } + /* + * print end line + */ + if (feof (theifile) && + (encoding == UU_ENCODED || encoding == XX_ENCODED)) { + fprintf (outfile, "%c%s", + (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], + eolstring); + fprintf (outfile, "end%s", eolstring); + } + /* + * empty line at end does no harm + */ + fprintf (outfile, "%s", eolstring); + + if (infile==NULL) { + if (res != UURET_OK) { + progress.action = 0; + fclose (theifile); + return res; + } + if (feof (theifile)) { + progress.action = 0; + fclose (theifile); + return UURET_OK; + } + return UURET_CONT; + } + + /* + * leave progress.action as-is + */ + + return UURET_OK; +} + +/* + * send output to a stream, don't do any headers at all + */ + +int UUEXPORT +UUEncodeToStream (FILE *outfile, FILE *infile, + char *infname, int encoding, + char *outfname, int filemode) +{ + struct stat finfo; + FILE *theifile; + int themode; + int res; + + if (outfile==NULL || + (infile == NULL&&infname==NULL) || + (outfname==NULL&&infname==NULL) || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUEncodeToStream()"); + return UURET_ILLVAL; + } + + progress.action = 0; + + if (infile==NULL) { + if (stat (infname, &finfo) == -1) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + if ((theifile = fopen (infname, "rb")) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); + progress.fsize = (long) finfo.st_size; + } + else { + if (fstat (fileno (infile), &finfo) == -1) { + /* gotta live with it */ + themode = 0644; + progress.fsize = -1; + } + else { + themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); + progress.fsize = (long) finfo.st_size; + } + theifile = infile; + } + + if (progress.fsize <= 0) + progress.fsize = -1; + + _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); + + progress.partno = 1; + progress.numparts = 1; + progress.percent = 0; + progress.foffset = 0; + progress.action = UUACT_ENCODING; + + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + fprintf (outfile, "begin %o %s%s", + (themode) ? themode : 0644, + UUFNameFilter ((outfname)?outfname:infname), + eolstring); + } + if ((res = UUEncodeStream (outfile, theifile, encoding, 0)) != UURET_OK) { + if (res != UURET_CANCEL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_ERR_ENCODING), + UUFNameFilter ((infname)?infname:outfname), + (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res)); + } + progress.action = 0; + return res; + } + if (encoding == UU_ENCODED || encoding == XX_ENCODED) { + fprintf (outfile, "%c%s", + (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], + eolstring); + fprintf (outfile, "end%s", eolstring); + } + /* + * empty line at end does no harm + */ + fprintf (outfile, "%s", eolstring); + + if (infile==NULL) fclose (theifile); + progress.action = 0; + + return UURET_OK; +} + +/* + * Encode to files on disk, don't generate any headers + */ + +int UUEXPORT +UUEncodeToFile (FILE *infile, char *infname, int encoding, + char *outfname, char *diskname, long linperfile) +{ + int part, numparts, len, filemode, res; + char *oname=NULL, *optr, *ptr; + FILE *theifile, *outfile; + struct stat finfo; + + if ((diskname==NULL&&infname==NULL) || + (outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUEncodeToFile()"); + return UURET_ILLVAL; + } + + if (diskname) { + if ((ptr = strchr (diskname, '/')) == NULL) + ptr = strchr (diskname, '\\'); + if (ptr) { + len = strlen (diskname) + ((uuencodeext)?strlen(uuencodeext):3) + 5; + + if ((oname = malloc (len)) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), len); + return UURET_NOMEM; + } + sprintf (oname, "%s", diskname); + } + else { + len = ((uusavepath)?strlen(uusavepath):0) + strlen (diskname) + + ((uuencodeext)?strlen(uuencodeext):0) + 5; + + if ((oname = malloc (len)) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), len); + return UURET_NOMEM; + } + sprintf (oname, "%s%s", (uusavepath)?uusavepath:"", diskname); + } + } + else { + len = ((uusavepath) ? strlen (uusavepath) : 0) + + strlen(UUFNameFilter(infname)) + + ((uuencodeext)?strlen(uuencodeext):0) + 5; + + if ((oname = malloc (len)) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), len); + return UURET_NOMEM; + } + optr = UUFNameFilter (infname); + sprintf (oname, "%s%s", + (uusavepath)?uusavepath:"", + (*optr=='.')?optr+1:optr); + } + + /* + * optr points after the last dot, so that we can print the part number + * there. + */ + + optr = _FP_strrchr (oname, '.'); + if (optr==NULL || strchr (optr, '/')!=NULL || strchr (optr, '\\')!=NULL) { + optr = oname + strlen (oname); + *optr++ = '.'; + } + else if (optr==oname || *(optr-1)=='/' || *(optr-1)=='\\') { + optr = oname + strlen (oname); + *optr++ = '.'; + } + else + optr++; + + progress.action = 0; + + if (infile==NULL) { + if (stat (infname, &finfo) == -1) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + infname, strerror (uu_errno=errno)); + _FP_free (oname); + return UURET_IOERR; + } + if ((theifile = fopen (infname, "rb")) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + infname, strerror (uu_errno=errno)); + _FP_free (oname); + return UURET_IOERR; + } + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) (((long)finfo.st_size + (linperfile*bpl[encoding]-1)) / + (linperfile*bpl[encoding])); + + filemode = (int) finfo.st_mode & 0777; + progress.totsize = (long) finfo.st_size; + } + else { + if (fstat (fileno (infile), &finfo) == -1) { + /* gotta live with it */ + filemode = 0644; + numparts = -1; + progress.totsize = -1; + } + else { + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ + (linperfile*bpl[encoding])); + + filemode = (int) finfo.st_mode & 0777; + progress.totsize = -1; + } + theifile = infile; + } + + _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); + + progress.totsize = (progress.totsize<=0) ? -1 : progress.totsize; + progress.numparts = numparts; + + for (part=1; !feof (theifile); part++) { + /* + * Attach extension + */ + if (progress.numparts==1 && progress.totsize!=-1 && uuencodeext!=NULL) + strcpy (optr, uuencodeext); + else + sprintf (optr, "%03d", part); + + /* + * check if target file exists + */ + + if (!uu_overwrite) { + if (stat (oname, &finfo) == 0) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_TARGET_EXISTS), oname); + if (infile==NULL) fclose (theifile); + progress.action = 0; + free (oname); + return UURET_EXISTS; + } + } + + /* + * update progress information + */ + + progress.action = 0; + progress.partno = part; + progress.percent = 0; + progress.foffset = ftell (theifile); + + if (progress.totsize == -1) + progress.fsize = -1; + else if (linperfile <= 0) + progress.fsize = progress.totsize; + else if (progress.foffset+linperfile*bpl[encoding] > progress.totsize) + progress.fsize = progress.totsize - progress.foffset; + else + progress.fsize = linperfile*bpl[encoding]; + + progress.action = UUACT_ENCODING; + + if ((outfile = fopen (oname, "w")) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_TARGET), + oname, strerror (uu_errno = errno)); + if (infile==NULL) fclose (theifile); + progress.action = 0; + free (oname); + return UURET_IOERR; + } + fprintf (outfile, "%s", eolstring); + fprintf (outfile, "_=_ %s", eolstring); + if (numparts == -1) + fprintf (outfile, "_=_ Part %03d of file %s%s", + part, UUFNameFilter ((outfname)?outfname:infname), + eolstring); + else + fprintf (outfile, "_=_ Part %03d of %03d of file %s%s", + part, numparts, + UUFNameFilter ((outfname)?outfname:infname), + eolstring); + fprintf (outfile, "_=_ %s", eolstring); + fprintf (outfile, "%s", eolstring); + + if (part==1 && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { + fprintf (outfile, "begin %o %s%s", + (filemode)?filemode : 0644, + UUFNameFilter ((outfname)?outfname:infname), + eolstring); + } + if ((res = UUEncodeStream (outfile, theifile, + encoding, linperfile)) != UURET_OK) { + if (res != UURET_CANCEL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_ERR_ENCODING), + UUFNameFilter ((infname)?infname:outfname), + (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res)); + } + if (infile==NULL) fclose (theifile); + progress.action = 0; + fclose (outfile); + unlink (oname); + _FP_free (oname); + return res; + } + if (feof (theifile) && + (encoding == UU_ENCODED || encoding == XX_ENCODED)) { + fprintf (outfile, "%c%s", + (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], + eolstring); + fprintf (outfile, "end%s", eolstring); + } + /* + * empty line at end does no harm + */ + fprintf (outfile, "%s", eolstring); + fclose (outfile); + } + if (infile==NULL) fclose (theifile); + progress.action = 0; + _FP_free (oname); + return UURET_OK; +} + +/* + * Encode a MIME Mail message or Newsgroup posting and send to a + * stream. Still needs a somewhat smart MDA, since we only gene- + * rate a minimum set of headers. + */ + +int UUEXPORT +UUE_PrepSingle (FILE *outfile, FILE *infile, + char *infname, int encoding, + char *outfname, int filemode, + char *destination, char *from, + char *subject, int isemail) +{ + mimemap *miter=mimetable; + char *subline, *oname; + char *mimetype, *ptr; + int res, len; + + if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUE_PrepSingle()"); + return UURET_ILLVAL; + } + + oname = UUFNameFilter ((outfname)?outfname:infname); + len = ((subject)?strlen(subject):0) + strlen(oname) + 40; + + if ((ptr = _FP_strrchr (oname, '.'))) { + while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0) + miter++; + mimetype = miter->mimetype; + } + else + mimetype = NULL; + + if ((subline = (char *) malloc (len)) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), len); + return UURET_NOMEM; + } + + if (subject) + sprintf (subline, "%s (001/001) - [ %s ]", subject, oname); + else + sprintf (subline, "[ %s ] (001/001)", oname); + + fprintf (outfile, "Subject: %s%s", subline, eolstring); + + if (from) { + fprintf (outfile, "From: %s%s", from, eolstring); + } + if (destination) { + fprintf (outfile, "%s: %s%s", + (isemail)?"To":"Newsgroups", + destination, eolstring); + } + fprintf (outfile, "MIME-Version: 1.0%s", eolstring); + fprintf (outfile, "Content-Type: %s; name=\"%s\"%s", + (mimetype)?mimetype:"Application/Octet-Stream", + UUFNameFilter ((outfname)?outfname:infname), + eolstring); + fprintf (outfile, "Content-Transfer-Encoding: %s%s", + CTE_TYPE(encoding), eolstring); + fprintf (outfile, "%s", eolstring); + + res = UUEncodeToStream (outfile, infile, infname, encoding, + outfname, filemode); + + _FP_free (subline); + return res; +} + +int UUEXPORT +UUE_PrepPartial (FILE *outfile, FILE *infile, + char *infname, int encoding, + char *outfname, int filemode, + int partno, long linperfile, long filesize, + char *destination, char *from, char *subject, + int isemail) +{ + static int numparts, themode; + static char mimeid[64]; + static FILE *theifile; + struct stat finfo; + char *subline, *oname; + long thesize; + int res, len; + + if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || + (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED)) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_PARM_CHECK), "UUE_PrepPartial()"); + return UURET_ILLVAL; + } + + oname = UUFNameFilter ((outfname)?outfname:infname); + len = ((subject)?strlen(subject):0) + strlen (oname) + 40; + + /* + * if first part, get information about the file + */ + if (partno == 1) { + if (infile==NULL) { + if (stat (infname, &finfo) == -1) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + if ((theifile = fopen (infname, "rb")) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + infname, strerror (uu_errno=errno)); + return UURET_IOERR; + } + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ + (linperfile*bpl[encoding])); + + themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); + thesize = (long) finfo.st_size; + } + else { + if (fstat (fileno (infile), &finfo) != 0) { + if (filesize <= 0) { + UUMessage (uuencode_id, __LINE__, UUMSG_WARNING, + uustring (S_STAT_ONE_PART)); + numparts = 1; + themode = (filemode)?filemode:0644; + thesize = 0; + } + else { + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) ((filesize+(linperfile*bpl[encoding]-1))/ + (linperfile*bpl[encoding])); + + themode = (filemode)?filemode:0644; + thesize = filesize; + } + } + else { + if (linperfile <= 0) + numparts = 1; + else + numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ + (linperfile*bpl[encoding])); + + filemode = (int) finfo.st_mode & 0777; + thesize = (long) finfo.st_size; + } + theifile = infile; + } + /* + * if there's one part only, don't use Message/Partial + */ + + if (numparts == 1) { + if (infile==NULL) fclose (theifile); + return UUE_PrepSingle (outfile, infile, infname, encoding, + outfname, filemode, destination, + from, subject, isemail); + } + + /* + * we also need a unique ID + */ + sprintf (mimeid, "UUDV-%ld.%ld.%s", + (long) time(NULL), thesize, + (strlen(oname)>16)?"oops":oname); + } + + if ((subline = (char *) malloc (len)) == NULL) { + UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, + uustring (S_OUT_OF_MEMORY), len); + if (infile==NULL) fclose (theifile); + return UURET_NOMEM; + } + + if (subject) + sprintf (subline, "%s (%03d/%03d) - [ %s ]", + subject, partno, numparts, oname); + else + sprintf (subline, "[ %s ] (%03d/%03d)", + oname, partno, numparts); + + fprintf (outfile, "Subject: %s%s", subline, eolstring); + + if (from) { + fprintf (outfile, "From: %s%s", from, eolstring); + } + if (destination) { + fprintf (outfile, "%s: %s%s", + (isemail)?"To":"Newsgroups", + destination, eolstring); + } + fprintf (outfile, "MIME-Version: 1.0%s", eolstring); + fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s", + partno, numparts, eolstring); + fprintf (outfile, "\tid=\"%s\"%s", + mimeid, eolstring); + fprintf (outfile, "%s", eolstring); + + res = UUEncodePartial (outfile, theifile, + infname, encoding, + (outfname)?outfname:infname, NULL, + themode, partno, linperfile); + + _FP_free (subline); + + if (infile==NULL) { + if (res != UURET_OK) { + fclose (theifile); + return res; + } + if (feof (theifile)) { + fclose (theifile); + return UURET_OK; + } + return UURET_CONT; + } + + return res; +} diff --git a/goldlib/uulib/uuint.h b/goldlib/uulib/uuint.h new file mode 100644 index 0000000..4113d22 --- /dev/null +++ b/goldlib/uulib/uuint.h @@ -0,0 +1,336 @@ +/* + * This file is part of uudeview, the simple and friendly multi-part multi- + * file uudecoder program (c) 1994 by Frank Pilhofer. The author may be + * contacted by his email address, fp@informatik.uni-frankfurt.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __UUINT_H__ +#define __UUINT_H__ + +/* + * This file describes the internal structures, variables and definitions + * of UUDeview. It should not be included from other packages. Subject to + * change without notice. Do not depend on anything here. + * + * $Id$ + */ + +#ifndef _ANSI_ARGS_ +#ifdef PROTOTYPES +#define _ANSI_ARGS_(c) c +#else +#define _ANSI_ARGS_(c) () +#endif +#endif + +/* + * Busy Polls will be made after processing ... lines + */ + +#define BUSY_LINE_TICKS 50 + +/* + * States of MIME scanner + */ + +#define MS_HEADERS 1 /* still inside of headers */ +#define MS_BODY 2 /* body of `simple' messages */ +#define MS_PREAMBLE 3 /* preamble of Multipart/Mixed */ +#define MS_SUBPART 4 /* within one of the Multiparts */ +#define MS_EPILOGUE 5 /* epilogue of Multipart/Mixed */ + +/* + * Number of subsequent encoded lines we require to believe this + * is valid data. + */ + +#define ELC_COUNT 4 + +/* + * Flags a part may have. FL_PROPER means that we are sure about the file's + * encoding, beginning and end, and don't have to use special care when de- + * coding. + */ + +#define FL_NONE 0 /* no flag, just plain normal */ +#define FL_SINGLE 1 /* standalone MSG, do not mix */ +#define FL_PARTIAL 2 /* from Message/Partial */ +#define FL_PROPER 4 /* proper MIME part */ +#define FL_TOEND 8 /* part continues to EOF */ + +/* + * Auxiliary macro: compute the percentage of a against b. + * The obvious answer is (100*a)/b, but this overflows for large a. + * a/(b/100) is better; we use a/((b/100)+1) so that we don't divide + * by zero for b<100 and the result doesn't become larger than 100% + */ + +#define UUPERCENT(a,b) ((int) ((unsigned long)(a) / \ + (((unsigned long)(b)/100)+1))) + +/* + * Make the Busy Callback easier. The macro returns true if the BusyCallback + * wants us to terminate. + */ + +extern unsigned long uuyctr; +#define UUBUSYPOLL(a,b) (((++uuyctr%BUSY_LINE_TICKS)==0) ? (progress.percent=UUPERCENT((a),(b)),UUBusyPoll()):0) + +/* + * How many lines of headers do we need to believe another mail + * header is approaching? Use more restrictive values for MIME + * mails, less restrictive for Freestyle + */ + +typedef struct { + int restart; /* restarting after a MIME body (not subpart) */ + int afterdata; /* after we had useful data in freestyle mode */ + int afternl; /* after an empty line in freestyle mode */ +} headercount; + +extern headercount hlcount; + +/* + * Information from the headers of a message. Each instance must + * have its very own copy of the strings. If `mimevers' is NULL, + * then this message does not comply to the MIME standard. + */ + +typedef struct _headers { + char *from; /* From: */ + char *subject; /* Subject: */ + char *rcpt; /* To: */ + char *date; /* Date: */ + char *mimevers; /* MIME-Version: */ + char *ctype; /* Content-Type: */ + char *ctenc; /* Content-Transfer-Encoding: */ + char *fname; /* Potential Filename from Content-Type Parameter */ + char *boundary; /* MIME-Boundary from Content-Type Parameter */ + char *mimeid; /* MIME-Id for Message/Partial */ + int partno; /* part number for Message/Partial */ + int numparts; /* number of parts for Message/Partial */ +} headers; + +/* + * Scanner state + */ + +typedef struct _scanstate { + int isfolder; /* if we think this is a valid email folder */ + int ismime; /* if we are within a valid MIME message */ + int mimestate; /* state of MIME scanner */ + int mimeenc; /* encoding of this MIME file */ + char *source; /* source filename */ + headers envelope; /* mail envelope headers */ +} scanstate; + +/* + * Structure that holds the information for a single file / part of + * a file. If a subject line is encountered, it is copied to subject; + * if a begin is found, the mode and name of the file is extracted. + * flags are set if 'begin' or 'end' is detected and 'uudet' if valid + * uuencoded data is found. If the file contains a 'From:' line with + * a '@' in it (indicating an origin email address), it is preserved + * in 'origin'. + **/ + +typedef struct _fileread { + char *subject; /* Whole subject line */ + char *filename; /* Only filled in if begin detected */ + char *origin; /* Whole 'From:' line */ + char *mimeid; /* the ID for Mime-encoded files */ + char *mimetype; /* Content-Type */ + short mode; /* Mode of File (from 'begin') */ + int begin; /* begin detected */ + int end; /* end detected */ + int flags; /* associated flags */ + + short uudet; /* valid encoded data. value indicates encoding */ + short partno; /* Mime-files have a part number within */ + short maxpno; /* ... plus the total number of parts */ + + char *sfname; /* Associated source file */ + long startpos; /* ftell() position where data starts */ + long length; /* length of data */ +} fileread; + +/* + * Structure for holding one part of a file, with some more information + * about it. The UUPreProcessPart() function takes one a fileread structure + * and produces this uufile structure. + * Linked List, ordered by partno. + **/ + +typedef struct _uufile { + char *filename; + char *subfname; + char *mimeid; + char *mimetype; + short partno; + fileread *data; + struct _uufile *NEXT; +} uufile; + +extern void *uu_MsgCBArg; +extern void *uu_BusyCBArg; +extern void *uu_FileCBArg; +extern void *uu_FFCBArg; + +/* + * variables + */ + +extern int uu_fast_scanning; +extern int uu_bracket_policy; +extern int uu_verbose; +extern int uu_desperate; +extern int uu_ignreply; +extern int uu_debug; +extern int uu_errno; +extern int uu_dumbness; +extern int uu_overwrite; +extern int uu_ignmode; +extern int uu_headercount; +extern int uu_usepreamble; +extern int uu_handletext; +extern int uu_tinyb64; + +extern char *uusavepath; +extern char *uuencodeext; + +/* + * Encoding/Decoding tables + */ + +extern unsigned char UUEncodeTable[]; +extern unsigned char XXEncodeTable[]; +extern unsigned char B64EncodeTable[]; +extern unsigned char BHEncodeTable[]; + +/* + * String tables from uustring.c + */ + +extern char *msgnames[]; +extern char *codenames[]; +extern char *uuretcodes[]; + +extern uulist *UUGlobalFileList; + +/* + * State of MIME variables and current progress + */ + +extern int nofnum, mssdepth; +extern int mimseqno, lastvalid; +extern int lastenc; +extern scanstate multistack[]; +extern headers localenv; +extern scanstate sstate; +extern uuprogress progress; + +/* + * mallocable areas + */ + +extern char *uugen_fnbuffer, *uugen_inbuffer; +extern char *uucheck_lastname, *uucheck_tempname; +extern char *uuestr_itemp, *uuestr_otemp; +extern char *uulib_msgstring, *uuncdl_fulline; +extern char *uuncdp_oline, *uuscan_shlline; +extern char *uuscan_pvvalue, *uuscan_phtext; +extern char *uuscan_sdline, *uuscan_sdbhds1; +extern char *uuscan_sdbhds2, *uuscan_spline; +extern char *uuutil_bhwtmp; +extern char *uunconc_UUxlat, *uunconc_UUxlen; +extern char *uunconc_B64xlat, *uunconc_XXxlat; +extern char *uunconc_BHxlat, *uunconc_save; + +#ifdef __cplusplus +extern "C" { +#endif + +extern void (*uu_MsgCallback) _ANSI_ARGS_((void *, char *, int)); +extern int (*uu_BusyCallback) _ANSI_ARGS_((void *, uuprogress *)); +extern int (*uu_FileCallback) _ANSI_ARGS_((void *, char *, char *, int)); +extern char * (*uu_FNameFilter) _ANSI_ARGS_((void *, char *)); + +/* + * Functions from uulib.c that aren't defined in + * Be careful about the definition with variable arguments. + */ + +#if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) +int UUMessage _ANSI_ARGS_((char *, int, + int, char *, ...)); +#else +int UUMessage (); +#endif +int UUBusyPoll _ANSI_ARGS_((void)); + +/* + * Functions from uucheck.c + */ + +uufile * UUPreProcessPart _ANSI_ARGS_((fileread *, int *)); +int UUInsertPartToList _ANSI_ARGS_((uufile *)); +uulist * UUCheckGlobalList _ANSI_ARGS_((void)); + +/* + * Functions from uuutil.c + */ + +void UUkillfread _ANSI_ARGS_((fileread *)); +void UUkillfile _ANSI_ARGS_((uufile *)); +void UUkilllist _ANSI_ARGS_((uulist *)); +void UUkillheaders _ANSI_ARGS_((headers *)); + +fileread * ScanPart _ANSI_ARGS_((FILE *, char *, int *)); + +int UUbhdecomp _ANSI_ARGS_((char *, char *, + char *, int *, + size_t, size_t, + size_t *)); +size_t UUbhwrite _ANSI_ARGS_((char *, size_t, size_t, + FILE *)); + +/* + * Functions from uunconc.c + */ + +int UURepairData _ANSI_ARGS_((FILE *, char *, + int, int *)); + +void UUInitConc _ANSI_ARGS_((void)); +int UUValidData _ANSI_ARGS_((char *, int, int *)); +size_t UUDecodeLine _ANSI_ARGS_((char *, char *, int)); +int UUDecodePart _ANSI_ARGS_((FILE *, FILE *, int *, + long, int, int, char *)); +int UUDecode _ANSI_ARGS_((uulist *)); + +/* + * Message retrieval from uustring.c + */ + +char * uustring _ANSI_ARGS_((int)); + +/* + * From uuscan.c + */ + +int UUScanHeader _ANSI_ARGS_((FILE *, headers *)); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/goldlib/uulib/uulib.all b/goldlib/uulib/uulib.all new file mode 100644 index 0000000..2d74acc --- /dev/null +++ b/goldlib/uulib/uulib.all @@ -0,0 +1,8 @@ +fptools c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uucheck c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uuencode c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uulib c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uunconc c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uuscan c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uustring c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg +uuutil c all ovl bcd bco bcx wcn wco wcx lnx emx djg rsx cyg diff --git a/goldlib/uulib/uulib.c b/goldlib/uulib/uulib.c new file mode 100644 index 0000000..3de38d6 --- /dev/null +++ b/goldlib/uulib/uulib.c @@ -0,0 +1,1200 @@ +/* + * This file is part of uudeview, the simple and friendly multi-part multi- + * file uudecoder program (c) 1994 by Frank Pilhofer. The author may be + * contacted by his email address, fp@informatik.uni-frankfurt.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * This file implements the externally visible functions, as declared + * in uudeview.h, and some internal interfacing functions + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SYSTEM_WINDLL +#include +#endif +#ifdef SYSTEM_OS2 +#include +#endif + +#include +#include +#include + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef STDC_HEADERS +#include +#include +#include +#else +#ifdef HAVE_STDARG_H +#include +#else +#ifdef HAVE_VARARGS_H +#include +#endif +#endif +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif + +/* to get open() in Windows */ +#if defined(HAVE_IO_H) && defined(__MINGW32__) +#include +#endif + +#include +#include +#include +#include + +char * uulib_id = "$Id$"; + +#ifdef SYSTEM_WINDLL +BOOL _export WINAPI +DllEntryPoint (HINSTANCE hInstance, DWORD seginfo, + LPVOID lpCmdLine) +{ + /* Don't do anything, so just return true */ + return TRUE; +} +#endif + +/* + * In DOS, we must open the file binary, O_BINARY is defined there + */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +/* for braindead systems */ +#ifndef SEEK_SET +#ifdef L_BEGIN +#define SEEK_SET L_BEGIN +#else +#define SEEK_SET 0 +#endif +#endif + +/* + * Callback functions and their opaque arguments + */ + +void (*uu_MsgCallback) _ANSI_ARGS_((void *, char *, int)) = NULL; +int (*uu_BusyCallback) _ANSI_ARGS_((void *, uuprogress *)) = NULL; +int (*uu_FileCallback) _ANSI_ARGS_((void *, char *, char *, int)) = NULL; +char * (*uu_FNameFilter) _ANSI_ARGS_((void *, char *)) = NULL; + +void *uu_MsgCBArg = NULL; +void *uu_BusyCBArg = NULL; +void *uu_FileCBArg = NULL; +void *uu_FFCBArg = NULL; + +/* + * Global variables + */ + +int uu_fast_scanning = 0; /* assumes at most 1 part per file */ +int uu_bracket_policy = 0; /* gives part numbers in [] higher priority */ +int uu_verbose = 1; /* enables/disables messages¬es */ +int uu_desperate = 0; /* desperate mode */ +int uu_ignreply = 0; /* ignore replies */ +int uu_debug = 0; /* debugging mode (print __FILE__/__LINE__) */ +int uu_errno = 0; /* the errno that caused this UURET_IOERR */ +int uu_dumbness = 0; /* switch off the program's intelligence */ +int uu_overwrite = 1; /* whether it's ok to overwrite ex. files */ +int uu_ignmode = 0; /* ignore the original file mode */ +int uu_handletext = 0; /* do we want text/plain messages */ +int uu_usepreamble = 0; /* do we want Mime preambles/epilogues */ +int uu_tinyb64 = 0; /* detect short B64 outside of MIME */ + +headercount hlcount = { + 3, /* restarting after a MIME body */ + 2, /* after useful data in freestyle mode */ + 1 /* after useful data and an empty line */ +}; + +/* + * version string + */ + +char uulibversion[256] = VERSION "pl" PATCH; + +/* + * prefix to the files on disk, usually a path name to save files to + */ + +char *uusavepath; + +/* + * extension to use when encoding single-part files + */ + +char *uuencodeext; + +/* + * areas to malloc + */ + +char *uulib_msgstring; +char *uugen_inbuffer; +char *uugen_fnbuffer; + +/* + * The Global List of Files + */ + +uulist *UUGlobalFileList = NULL; + +/* + * time values for BusyCallback. msecs is MILLIsecs here + */ + +static long uu_busy_msecs = 0; /* call callback function each msecs */ +static long uu_last_secs = 0; /* secs of last call to callback */ +static long uu_last_usecs = 0; /* usecs of last call to callback */ + +/* + * progress information + */ + +uuprogress progress; + +/* + * Linked list of files we want to delete after decoding + */ + +typedef struct _itbd { + char *fname; + struct _itbd *NEXT; +} itbd; +static itbd * ftodel = NULL; + +/* + * for the busy poll + */ + +unsigned long uuyctr; + +/* + * Areas to allocate. Instead of using static memory areas, we malloc() + * the memory in UUInitialize() and release them in UUCleanUp to prevent + * blowing up of the binary size + * This is a table with the pointers to allocate and required sizes. + * They are guaranteed to be never NULL. + */ + +typedef struct { + char **ptr; + size_t size; +} allomap; + +static allomap toallocate[] = { + { &uugen_fnbuffer, 1024 }, /* generic filename buffer */ + { &uugen_inbuffer, 1024 }, /* generic input data buffer */ + { &uucheck_lastname, 256 }, /* from uucheck.c */ + { &uucheck_tempname, 256 }, + { &uuestr_itemp, 256 }, /* from uuencode.c:UUEncodeStream() */ + { &uuestr_otemp, 256 }, + { &uulib_msgstring, 1024 }, /* from uulib.c:UUMessage() */ + { &uuncdl_fulline, 256 }, /* from uunconc.c:UUDecodeLine() */ + { &uuncdp_oline, 512 }, /* from uunconc.c:UUDecodePart() */ + { &uunconc_UUxlat, 256 * sizeof (int) }, /* from uunconc.c:toplevel */ + { &uunconc_UUxlen, 64 * sizeof (int) }, + { &uunconc_B64xlat, 256 * sizeof (int) }, + { &uunconc_XXxlat, 256 * sizeof (int) }, + { &uunconc_BHxlat, 256 * sizeof (int) }, + { &uunconc_save, 3*256 }, /* from uunconc.c:decoding buffer */ + { &uuscan_shlline, 1024 }, /* from uuscan.c:ScanHeaderLine() */ + { &uuscan_pvvalue, 256 }, /* from uuscan.c:ParseValue() */ + { &uuscan_phtext, 256 }, /* from uuscan.c:ParseHeader() */ + { &uuscan_sdline, 256 }, /* from uuscan.c:ScanData() */ + { &uuscan_sdbhds1, 256 }, + { &uuscan_sdbhds2, 256 }, + { &uuscan_spline, 256 }, /* from uuscan.c:ScanPart() */ + { &uuutil_bhwtmp, 256 }, /* from uuutil.c:UUbhwrite() */ + { NULL, 0 } +}; + +/* + * Handle the printing of messages. Works like printf. + */ + +#if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) +int +UUMessage (char *file, int line, int level, char *format, ...) +#else +int +UUMessage (va_alist) + va_dcl +#endif +{ + char *msgptr; +#if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) + va_list ap; + + va_start (ap, format); +#else + char *file, *format; + int line, level; + va_list ap; + + va_start (ap); + file = va_arg (ap, char *); + line = va_arg (ap, int); + level = va_arg (ap, int); + format = va_arg (ap, char *); +#endif + + if (uu_debug) { + sprintf (uulib_msgstring, "%s(%d): %s", file, line, msgnames[level]); + msgptr = uulib_msgstring + strlen (uulib_msgstring); + } + else { + sprintf (uulib_msgstring, "%s", msgnames[level]); + msgptr = uulib_msgstring + strlen (uulib_msgstring); + } + + if (uu_MsgCallback && (level>UUMSG_NOTE || uu_verbose)) { + vsprintf (msgptr, format, ap); + + (*uu_MsgCallback) (uu_MsgCBArg, uulib_msgstring, level); + } + + va_end (ap); + + return UURET_OK; +} + +/* + * Call the Busy Callback from time to time. This function must be + * polled from the Busy loops. + */ + +int +UUBusyPoll (void) +{ +#ifdef HAVE_GETTIMEOFDAY + struct timeval tv; + long msecs; + + if (uu_BusyCallback) { + (void) gettimeofday (&tv, NULL); + + msecs = 1000*(tv.tv_sec-uu_last_secs)+(tv.tv_usec-uu_last_usecs)/1000; + + if (uu_last_secs==0 || msecs > uu_busy_msecs) { + uu_last_secs = tv.tv_sec; + uu_last_usecs = tv.tv_usec; + + return (*uu_BusyCallback) (uu_BusyCBArg, &progress); + } + } +#else + time_t now; + long msecs; + + if (uu_BusyCallback) { + now = time(NULL); + if (uu_busy_msecs <= 0) { + msecs = 1; + } + else { + msecs = 1000 * (now - uu_last_secs); + } + + if (uu_last_secs==0 || msecs > uu_busy_msecs) { + uu_last_secs = now; + uu_last_usecs = 0; + + return (*uu_BusyCallback) (uu_BusyCBArg, &progress); + } + } +#endif + + return 0; +} + +/* + * Initialization function + */ + +int UUEXPORT +UUInitialize (void) +{ + allomap *aiter; + + progress.action = 0; + progress.curfile[0] = '\0'; + + ftodel = NULL; + + uusavepath = NULL; + uuencodeext = NULL; + + mssdepth = 0; + memset (&localenv, 0, sizeof (headers)); + memset (&sstate, 0, sizeof (scanstate)); + + nofnum = 0; + mimseqno = 0; + lastvalid = 0; + lastenc = 0; + uuyctr = 0; + + /* + * Allocate areas + */ + + for (aiter=toallocate; aiter->ptr; aiter++) + *(aiter->ptr) = NULL; + + for (aiter=toallocate; aiter->ptr; aiter++) { + if ((*(aiter->ptr) = (char *) malloc (aiter->size)) == NULL) { + /* + * oops. we may not print a message here, because we need these + * areas (uulib_msgstring) in UUMessage() + */ + for (aiter=toallocate; aiter->ptr; aiter++) { + _FP_free (*(aiter->ptr)); + } + return UURET_NOMEM; + } + } + + /* + * Must be called after areas have been malloced + */ + + UUInitConc (); + + return UURET_OK; +} + +/* + * Set and get Options + */ + +int UUEXPORT +UUGetOption (int option, int *ivalue, char *cvalue, int clength) +{ + int result; + + switch (option) { + case UUOPT_VERSION: + _FP_strncpy (cvalue, uulibversion, clength); + result = 0; + break; + case UUOPT_FAST: + if (ivalue) *ivalue = uu_fast_scanning; + result = uu_fast_scanning; + break; + case UUOPT_DUMBNESS: + if (ivalue) *ivalue = uu_dumbness; + result = uu_dumbness; + break; + case UUOPT_BRACKPOL: + if (ivalue) *ivalue = uu_bracket_policy; + result = uu_bracket_policy; + break; + case UUOPT_VERBOSE: + if (ivalue) *ivalue = uu_verbose; + result = uu_verbose; + break; + case UUOPT_DESPERATE: + if (ivalue) *ivalue = uu_desperate; + result = uu_desperate; + break; + case UUOPT_IGNREPLY: + if (ivalue) *ivalue = uu_ignreply; + result = uu_ignreply; + break; + case UUOPT_DEBUG: + if (ivalue) *ivalue = uu_debug; + result = uu_debug; + break; + case UUOPT_ERRNO: + if (ivalue) *ivalue = uu_errno; + result = uu_errno; + break; + case UUOPT_OVERWRITE: + if (ivalue) *ivalue = uu_overwrite; + result = uu_overwrite; + break; + case UUOPT_SAVEPATH: + _FP_strncpy (cvalue, uusavepath, clength); + result = 0; + break; + case UUOPT_PROGRESS: + if (clength==sizeof(uuprogress)) { + memcpy (cvalue, &progress, sizeof (uuprogress)); + result = 0; + } + else + result = -1; + break; + case UUOPT_IGNMODE: + if (ivalue) *ivalue = uu_ignmode; + result = uu_ignmode; + break; + case UUOPT_USETEXT: + if (ivalue) *ivalue = uu_handletext; + result = uu_handletext; + break; + case UUOPT_PREAMB: + if (ivalue) *ivalue = uu_usepreamble; + result = uu_usepreamble; + break; + case UUOPT_TINYB64: + if (ivalue) *ivalue = uu_tinyb64; + result = uu_tinyb64; + break; + case UUOPT_ENCEXT: + _FP_strncpy (cvalue, uuencodeext, clength); + result = 0; + break; + default: + return -1; + } + return result; +} + +int UUEXPORT +UUSetOption (int option, int ivalue, char *cvalue) +{ + switch (option) { + case UUOPT_FAST: + uu_fast_scanning = ivalue; + break; + case UUOPT_DUMBNESS: + uu_dumbness = ivalue; + break; + case UUOPT_BRACKPOL: + uu_bracket_policy = ivalue; + break; + case UUOPT_VERBOSE: + uu_verbose = ivalue; + break; + case UUOPT_DESPERATE: + uu_desperate = ivalue; + break; + case UUOPT_IGNREPLY: + uu_ignreply = ivalue; + break; + case UUOPT_DEBUG: + uu_debug = ivalue; + break; + case UUOPT_OVERWRITE: + uu_overwrite = ivalue; + break; + case UUOPT_SAVEPATH: + _FP_free (uusavepath); + uusavepath = _FP_strdup (cvalue); + break; + case UUOPT_IGNMODE: + uu_ignmode = ivalue; + break; + case UUOPT_USETEXT: + uu_handletext = ivalue; + break; + case UUOPT_PREAMB: + uu_usepreamble = ivalue; + break; + case UUOPT_TINYB64: + uu_tinyb64 = ivalue; + break; + case UUOPT_ENCEXT: + _FP_free (uuencodeext); + uuencodeext = _FP_strdup (cvalue); + break; + default: + return UURET_ILLVAL; + } + return UURET_OK; +} + +char * UUEXPORT +UUstrerror (int code) +{ + return uuretcodes[code]; +} + +/* + * Set the various Callback functions + */ + +int UUEXPORT +UUSetMsgCallback (void *opaque, + void (*func) _ANSI_ARGS_((void *, char *, int))) +{ + uu_MsgCallback = func; + uu_MsgCBArg = opaque; + + return UURET_OK; +} + +int UUEXPORT +UUSetBusyCallback (void *opaque, + int (*func) _ANSI_ARGS_((void *, uuprogress *)), + long msecs) +{ + uu_BusyCallback = func; + uu_BusyCBArg = opaque; + uu_busy_msecs = msecs; + + return UURET_OK; +} + +int UUEXPORT +UUSetFileCallback (void *opaque, + int (*func) _ANSI_ARGS_((void *, char *, char *, int))) +{ + uu_FileCallback = func; + uu_FileCBArg = opaque; + + return UURET_OK; +} + +int UUEXPORT +UUSetFNameFilter (void *opaque, + char * (*func) _ANSI_ARGS_((void *, char *))) +{ + uu_FNameFilter = func; + uu_FFCBArg = opaque; + + return UURET_OK; +} + +/* + * Return a pointer to the nth element of the GlobalFileList + * zero-based, returns NULL if item is too large. + */ + +uulist * UUEXPORT +UUGetFileListItem (int item) +{ + uulist *iter=UUGlobalFileList; + + if (item < 0) + return NULL; + while (item && iter) { + iter = iter->NEXT; + item--; + } + return iter; +} + +/* + * call the current filter + */ + +char * UUEXPORT +UUFNameFilter (char *fname) +{ + if (uu_FNameFilter) + return (*uu_FNameFilter) (uu_FFCBArg, fname); + + return fname; +} + +/* + * Load a File. We call ScanPart repeatedly until at EOF and + * add the parts to UUGlobalFileList + */ + +int UUEXPORT +UULoadFile (char *filename, char *fileid, int delflag) +{ + int res, sr, count=0; + struct stat finfo; + fileread *loaded; + uufile *fload; + itbd *killem; + FILE *datei; + + if ((datei = fopen (filename, "rb")) == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_SOURCE), + filename, strerror (uu_errno = errno)); + return UURET_IOERR; + } + + if (fstat (fileno(datei), &finfo) == -1) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + filename, strerror (uu_errno = errno)); + fclose (datei); + return UURET_IOERR; + } + + /* + * schedule for destruction + */ + + if (delflag && fileid==NULL) { + if ((killem = (itbd *) malloc (sizeof (itbd))) == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_WARNING, + uustring (S_OUT_OF_MEMORY), sizeof (itbd)); + } + else if ((killem->fname = _FP_strdup (filename)) == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_WARNING, + uustring (S_OUT_OF_MEMORY), strlen(filename)+1); + _FP_free (killem); + } + else { + killem->NEXT = ftodel; + ftodel = killem; + } + } + + progress.action = 0; + progress.partno = 0; + progress.numparts = 1; + progress.fsize = (long) ((finfo.st_size>0)?finfo.st_size:-1); + progress.percent = 0; + progress.foffset = 0; + _FP_strncpy (progress.curfile, + (strlen(filename)>255)? + (filename+strlen(filename)-255):filename, + 256); + progress.action = UUACT_SCANNING; + + if (fileid == NULL) + fileid = filename; + + while (!feof (datei) && !ferror (datei)) { + /* + * Peek file, or some systems won't detect EOF + */ + res = fgetc (datei); + if (feof (datei) || ferror (datei)) + break; + else + ungetc (res, datei); + + if ((loaded = ScanPart (datei, fileid, &sr)) == NULL) { + if (sr != UURET_NODATA && sr != UURET_OK && sr != UURET_CONT) { + UUkillfread (loaded); + if (sr != UURET_CANCEL) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_READ_ERROR), filename, + strerror (uu_errno)); + } + UUCheckGlobalList (); + progress.action = 0; + fclose (datei); + return sr; + } + continue; + } + + if (ferror (datei)) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_READ_ERROR), filename, + strerror (uu_errno = errno)); + UUCheckGlobalList (); + progress.action = 0; + fclose (datei); + return UURET_IOERR; + } + + if ((loaded->uudet == QP_ENCODED || loaded->uudet == PT_ENCODED) && + !uu_handletext && (loaded->flags&FL_PARTIAL)==0) { + /* + * Don't want text + */ + UUkillfread (loaded); + continue; + } + + if ((loaded->subject == NULL || *(loaded->subject) == '\0') && + (loaded->mimeid == NULL || *(loaded->mimeid) == '\0') && + (loaded->filename== NULL || *(loaded->filename)== '\0') && + (loaded->uudet == 0)) { + /* + * no useful data here + */ + UUkillfread (loaded); + if (uu_fast_scanning && sr != UURET_CONT) break; + continue; + } + + if ((fload = UUPreProcessPart (loaded, &res)) == NULL) { + /* + * no useful data found + */ + if (res != UURET_NODATA) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_READ_ERROR), filename, + (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res)); + } + UUkillfread (loaded); + if (uu_fast_scanning && sr != UURET_CONT) break; + continue; + } + + if ((loaded->subject && *(loaded->subject)) || + (loaded->mimeid && *(loaded->mimeid)) || + (loaded->filename&& *(loaded->filename))|| + (loaded->uudet)) { + UUMessage (uulib_id, __LINE__, UUMSG_MESSAGE, + uustring (S_LOADED_PART), + filename, + (loaded->subject) ? loaded->subject : "", + (fload->subfname) ? fload->subfname : "", + (loaded->filename) ? loaded->filename : "", + fload->partno, + (loaded->begin) ? "begin" : "", + (loaded->end) ? "end" : "", + codenames[loaded->uudet]); + } + + if ((res = UUInsertPartToList (fload))) { + /* + * couldn't use the data + */ + UUkillfile (fload); + + if (res != UURET_NODATA) { + UUCheckGlobalList (); + progress.action = 0; + fclose (datei); + return res; + } + if (uu_fast_scanning && sr != UURET_CONT) + break; + + continue; + } + + /* + * if in fast mode, we don't look any further, because we're told + * that each source file holds at most one encoded part + */ + + if (uu_fast_scanning && sr != UURET_CONT) + break; + + if (loaded->uudet) + count++; + } + fclose (datei); + + if (!uu_fast_scanning && count==0) { + UUMessage (uulib_id, __LINE__, UUMSG_NOTE, + uustring (S_NO_DATA_FOUND), filename); + } + + progress.action = 0; + UUCheckGlobalList (); + + return UURET_OK; +} + +/* + * decode to a temporary file. this is well handled by uudecode() + */ + +int UUEXPORT +UUDecodeToTemp (uulist *thefile) +{ + return UUDecode (thefile); +} + +/* + * decode file first to temp file, then copy it to a final location + */ + +int UUEXPORT +UUDecodeFile (uulist *thefile, char *destname) +{ + FILE *target, *source; + struct stat finfo; + int fildes, res; + size_t bytes; + + if (thefile == NULL) + return UURET_ILLVAL; + + if ((res = UUDecode (thefile)) != UURET_OK) + if (res != UURET_NOEND || !uu_desperate) + return res; + + if (thefile->binfile == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NO_BIN_FILE)); + return UURET_IOERR; + } + + if ((source = fopen (thefile->binfile, "rb")) == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + thefile->binfile, strerror (uu_errno = errno)); + return UURET_IOERR; + } + + /* + * for system security, strip setuid/setgid bits from mode + */ + + if ((thefile->mode & 0777) != thefile->mode) { + UUMessage (uulib_id, __LINE__, UUMSG_NOTE, + uustring (S_STRIPPED_SETUID), + destname, (int)thefile->mode); + thefile->mode &= 0777; + } + + /* + * Determine the name of the target file according to the rules: + * + * IF (destname!=NULL) THEN filename=destname; + * ELSE + * filename = thefile->filename + * IF (FilenameFilter!=NULL) THEN filename=FilenameFilter(filename); + * filename = SaveFilePath + filename + * END + */ + + if (destname) + strcpy (uugen_fnbuffer, destname); + else { + sprintf (uugen_fnbuffer, "%s%s", + (uusavepath)?uusavepath:"", + UUFNameFilter ((thefile->filename)? + thefile->filename:"unknown.xxx")); + } + + /* + * if we don't want to overwrite existing files, check if it's there + */ + + if (!uu_overwrite) { + if (stat (uugen_fnbuffer, &finfo) == 0) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_TARGET_EXISTS), uugen_fnbuffer); + fclose (source); + return UURET_EXISTS; + } + } + + if (fstat (fileno(source), &finfo) == -1) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_STAT_FILE), + thefile->binfile, strerror (uu_errno = errno)); + fclose (source); + return UURET_IOERR; + } + + progress.action = 0; + _FP_strncpy (progress.curfile, + (strlen(uugen_fnbuffer)>255)? + (uugen_fnbuffer+strlen(uugen_fnbuffer)-255):uugen_fnbuffer, + 256); + progress.partno = 0; + progress.numparts = 1; + progress.fsize = (long) ((finfo.st_size)?finfo.st_size:-1); + progress.foffset = 0; + progress.percent = 0; + progress.action = UUACT_COPYING; + + if ((fildes = open (uugen_fnbuffer, + O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, + (uu_ignmode)?0666:thefile->mode)) == -1) { + progress.action = 0; + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_TARGET), + uugen_fnbuffer, strerror (uu_errno = errno)); + fclose (source); + return UURET_IOERR; + } + + if ((target = fdopen (fildes, "wb")) == NULL) { + progress.action = 0; + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_IO_ERR_TARGET), + uugen_fnbuffer, strerror (uu_errno = errno)); + fclose (source); + close (fildes); + return UURET_IOERR; + } + + while (!feof (source)) { + + if (UUBUSYPOLL(ftell(source),progress.fsize)) { + UUMessage (uulib_id, __LINE__, UUMSG_NOTE, + uustring (S_DECODE_CANCEL)); + fclose (source); + fclose (target); + unlink (uugen_fnbuffer); + return UURET_CANCEL; + } + + bytes = fread (uugen_inbuffer, 1, 1024, source); + + if (ferror (source) || (bytes == 0 && !feof (source))) { + progress.action = 0; + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_READ_ERROR), + thefile->binfile, strerror (uu_errno = errno)); + fclose (source); + fclose (target); + unlink (uugen_fnbuffer); + return UURET_IOERR; + } + if (fwrite (uugen_inbuffer, 1, bytes, target) != bytes) { + progress.action = 0; + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_WR_ERR_TARGET), + uugen_fnbuffer, strerror (uu_errno = errno)); + fclose (source); + fclose (target); + unlink (uugen_fnbuffer); + return UURET_IOERR; + } + } + + fclose (target); + fclose (source); + + /* + * after a successful decoding run, we delete the temporary file + */ + + if (unlink (thefile->binfile)) { + UUMessage (uulib_id, __LINE__, UUMSG_WARNING, + uustring (S_TMP_NOT_REMOVED), + thefile->binfile, + strerror (uu_errno = errno)); + } + _FP_free (thefile->binfile); + thefile->binfile = NULL; + thefile->state &= ~UUFILE_TMPFILE; + thefile->state |= UUFILE_DECODED; + progress.action = 0; + + return UURET_OK; +} + +/* + * Calls a function repeatedly with all the info we have for a file + * If the function returns non-zero, we break and don't send any more + */ + +int UUEXPORT +UUInfoFile (uulist *thefile, void *opaque, + int (*func) _ANSI_ARGS_((void *, char *))) +{ + int errflag=0, res, bhflag=0, dd; + long maxpos; + FILE *inpfile; + + /* + * We might need to ask our callback function to download the file + */ + + if (uu_FileCallback) { + if ((res = (*uu_FileCallback) (uu_FileCBArg, + thefile->thisfile->data->sfname, + uugen_fnbuffer, + 1)) != UURET_OK) + return res; + if ((inpfile = fopen (uugen_fnbuffer, "rb")) == NULL) { + (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, + uugen_fnbuffer, 0); + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), uugen_fnbuffer, + strerror (uu_errno = errno)); + return UURET_IOERR; + } + } + else { + if ((inpfile = fopen (thefile->thisfile->data->sfname, "rb")) == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_OPEN_FILE), + thefile->thisfile->data->sfname, + strerror (uu_errno=errno)); + return UURET_IOERR; + } + _FP_strncpy (uugen_fnbuffer, thefile->thisfile->data->sfname, 1024); + } + + /* + * seek to beginning of info + */ + + fseek (inpfile, thefile->thisfile->data->startpos, SEEK_SET); + maxpos = thefile->thisfile->data->startpos + thefile->thisfile->data->length; + + while (!feof (inpfile) && + (uu_fast_scanning || ftell(inpfile) < maxpos)) { + if (_FP_fgets (uugen_inbuffer, 511, inpfile) == NULL) + break; + uugen_inbuffer[511] = '\0'; + + if (ferror (inpfile)) + break; + + dd = UUValidData (uugen_inbuffer, 0, &bhflag); + + if (thefile->uudet == B64ENCODED && dd == B64ENCODED) + break; + else if (thefile->uudet == BH_ENCODED && bhflag) + break; + else if ((thefile->uudet == UU_ENCODED || thefile->uudet == XX_ENCODED) && + strncmp (uugen_inbuffer, "begin ", 6) == 0) + break; + + if ((*func) (opaque, uugen_inbuffer)) + break; + } + + if (ferror (inpfile)) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_READ_ERROR), + uugen_fnbuffer, strerror (uu_errno = errno)); + errflag = 1; + } + + fclose (inpfile); + + if (uu_FileCallback) + (*uu_FileCallback) (uu_FileCBArg, + thefile->thisfile->data->sfname, + uugen_fnbuffer, 0); + + if (errflag) + return UURET_IOERR; + + return UURET_OK; +} + +int UUEXPORT +UURenameFile (uulist *thefile, char *newname) +{ + char *oldname; + + if (thefile == NULL) + return UURET_ILLVAL; + + oldname = thefile->filename; + + if ((thefile->filename = _FP_strdup (newname)) == NULL) { + UUMessage (uulib_id, __LINE__, UUMSG_ERROR, + uustring (S_NOT_RENAME), + oldname, newname); + thefile->filename = oldname; + return UURET_NOMEM; + } + _FP_free (oldname); + return UURET_OK; +} + +int UUEXPORT +UURemoveTemp (uulist *thefile) +{ + if (thefile == NULL) + return UURET_ILLVAL; + + if (thefile->binfile) { + if (unlink (thefile->binfile)) { + UUMessage (uulib_id, __LINE__, UUMSG_WARNING, + uustring (S_TMP_NOT_REMOVED), + thefile->binfile, + strerror (uu_errno = errno)); + } + _FP_free (thefile->binfile); + thefile->binfile = NULL; + thefile->state &= ~UUFILE_TMPFILE; + } + return UURET_OK; +} + +int UUEXPORT +UUCleanUp (void) +{ + itbd *iter=ftodel, *ptr; + allomap *aiter; + + UUkilllist (UUGlobalFileList); + UUGlobalFileList = NULL; + + /* + * delete input files + */ + while (iter) { + if (unlink (iter->fname)) { + UUMessage (uulib_id, __LINE__, UUMSG_WARNING, + uustring (S_TMP_NOT_REMOVED), + iter->fname, strerror (uu_errno = errno)); + } + _FP_free (iter->fname); + ptr = iter; + iter = iter->NEXT; + _FP_free (ptr); + } + ftodel = NULL; + + _FP_free (uusavepath); + _FP_free (uuencodeext); + _FP_free (sstate.source); + + uusavepath = NULL; + uuencodeext = NULL; + + UUkillheaders (&localenv); + UUkillheaders (&sstate.envelope); + memset (&localenv, 0, sizeof (headers)); + memset (&sstate, 0, sizeof (scanstate)); + + while (mssdepth) { + mssdepth--; + UUkillheaders (&(multistack[mssdepth].envelope)); + _FP_free (multistack[mssdepth].source); + } + + /* + * clean up the malloc'ed stuff + */ + + for (aiter=toallocate; aiter->ptr; aiter++) { + _FP_free (*(aiter->ptr)); + *(aiter->ptr) = NULL; + } + + return UURET_OK; +} + diff --git a/goldlib/uulib/uunconc.c b/goldlib/uulib/uunconc.c new file mode 100644 index 0000000..7ee6b1f --- /dev/null +++ b/goldlib/uulib/uunconc.c @@ -0,0 +1,1500 @@ +/* + * This file is part of uudeview, the simple and friendly multi-part multi- + * file uudecoder program (c) 1994 by Frank Pilhofer. The author may be + * contacted by his email address, fp@informatik.uni-frankfurt.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * These are the functions that are responsible for decoding. The + * original idea is from a freeware utility called "uunconc", and + * few lines of this code may still bear a remote resemblance to + * its code. If you are the author or know him, contact me. + * This program could only decode one multi-part, uuencoded file + * where the parts were in order. Base64, XX and BinHex decoding, + * support for multi-files and part-ordering covered by myself. + **/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef SYSTEM_WINDLL +#include +#endif +#ifdef SYSTEM_OS2 +#include +#endif + +#include +#include + +#ifdef STDC_HEADERS +#include +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif + +#include +#include +#include +#include + +char * uunconc_id = "$Id$"; + +/* for braindead systems */ +#ifndef SEEK_SET +#ifdef L_BEGIN +#define SEEK_SET L_BEGIN +#else +#define SEEK_SET 0 +#endif +#endif + +/* + * decoder states + */ + +#define BEGIN (1) +#define DATA (2) +#define END (3) +#define DONE (4) + +/* + * mallocable areas + */ + +char *uunconc_UUxlat; +char *uunconc_UUxlen; +char *uunconc_B64xlat; +char *uunconc_XXxlat; +char *uunconc_BHxlat; +char *uunconc_save; + +/* + * decoding translation tables and line length table + */ + +static int * UUxlen; /* initialized in UUInitConc() */ +static int * UUxlat; /* from the malloc'ed areas above */ +static int * B64xlat; +static int * XXxlat; +static int * BHxlat; + +/* + * buffer for decoding + */ + +static char *save[3]; + +/* + * mallocable areas + */ + +char *uuncdl_fulline; +char *uuncdp_oline; + +/* + * Return information for QuickDecode + */ + +static int uulboundary; + +/* + * To prevent warnings when using a char as index into an array + */ + +#define ACAST(s) ((int)(unsigned char)(s)) + +/* + * Initialize decoding tables + */ + +void +UUInitConc (void) +{ + int i, j; + + /* + * Update pointers + */ + UUxlen = (int *) uunconc_UUxlen; + UUxlat = (int *) uunconc_UUxlat; + B64xlat = (int *) uunconc_B64xlat; + XXxlat = (int *) uunconc_XXxlat; + BHxlat = (int *) uunconc_BHxlat; + + save[0] = uunconc_save; + save[1] = uunconc_save + 256; + save[2] = uunconc_save + 512; + + /* prepare decoding translation table */ + for(i = 0; i < 256; i++) + UUxlat[i] = B64xlat[i] = XXxlat[i] = BHxlat[i] = -1; + + /* + * At some time I received a file which used lowercase characters for + * uuencoding. This shouldn't be, but let's accept it. Must take special + * care that this doesn't break xxdecoding. This is giving me quite a + * headache. If this one file hadn't been a Pocahontas picture, I might + * have ignored it for good. + */ + + for (i = ' ', j = 0; i < ' ' + 64; i++, j++) + UUxlat[i] /* = UUxlat[i+64] */ = j; + for (i = '`', j = 0; i < '`' + 32; i++, j++) + UUxlat[i] = j; + + /* add special cases */ + UUxlat['`'] = UUxlat[' ']; + UUxlat['~'] = UUxlat['^']; + + /* prepare line length table */ + UUxlen[0] = 1; + for(i = 1, j = 5; i <= 60; i += 3, j += 4) + UUxlen[i] = UUxlen[i+1] = UUxlen[i+2] = j; + + /* prepare other tables */ + for (i=0; i<64; i++) { + B64xlat[ACAST(B64EncodeTable[i])] = i; + XXxlat [ACAST(XXEncodeTable [i])] = i; + BHxlat [ACAST(BHEncodeTable [i])] = i; + } +} + +/* + * Workaround for Netscape + */ + +/* + * Determines whether Netscape may have broken up a data line (by + * inserting a newline). This only seems to happen after ") > ptr) + return 2; + } + + ptr = string + len; + + while (len && (*(ptr-1)=='\015' || *(ptr-1)=='\012')) { + ptr--; len--; + } + if (len<3) return 0; + if (*--ptr == ' ') ptr--; + ptr--; + + if (_FP_strnicmp (ptr, "",4)). If the first expression + * becomes true, the costly function isn't called :-) + * + * Since '<', '>', '&' might even be replaced by their html equivalents + * in href strings, I'm now using two passes, the first one for & + co, + * the second one for hrefs. + */ + +int +UUNetscapeCollapse (char *string) +{ + char *p1=string, *p2=string; + int res = 0; + + if (string==NULL) + return 0; + + /* + * First pass + */ + while (*p1) { + if (*p1 == '&') { + if (_FP_strnicmp (p1, "&", 5) == 0) { p1+=5; *p2++='&'; } + else if (_FP_strnicmp (p1, "<", 4) == 0) { p1+=4; *p2++='<'; } + else if (_FP_strnicmp (p1, ">", 4) == 0) { p1+=4; *p2++='>'; } + else *p2++ = *p1++; + res = 1; + } + else *p2++ = *p1++; + } + *p2 = '\0'; + /* + * Second pass + */ + p1 = p2 = string; + + while (*p1) { + if (*p1 == '<') { + if ((_FP_strnicmp (p1, "") != 0 || _FP_strstr (p1, "") != 0)) { + while (*p1 && *p1!='>') p1++; + if (*p1=='\0' || *(p1+1)!='<') return 0; + p1++; + while (*p1 && (*p1!='<' || _FP_strnicmp(p1,"",4)!=0)) { + *p2++ = *p1++; + } + if (_FP_strnicmp(p1,"",4) != 0) + return 0; + p1+=4; + res=1; + } + else + *p2++ = *p1++; + } + else + *p2++ = *p1++; + } + *p2 = '\0'; + + return res; +} + +/* + * The second parameter is 0 if we are still searching for encoded data, + * otherwise it indicates the encoding we're using right now. If we're + * still in the searching stage, we must be a little more strict in + * deciding for or against encoding; there's too much plain text looking + * like encoded data :-( + */ + +int +UUValidData (char *ptr, int encoding, int *bhflag) +{ + int i=0, j, len=0, suspicious=0, flag=0; + char *s = ptr; + + if ((s == NULL) || (*s & 0x80)) { + return(0); /* bad string */ + } + + while (*s && *s!='\012' && *s!='\015') { + s++; + len++; + i++; + } + + if (i == 0) + return 0; + + switch (encoding) { + case UU_ENCODED: + goto _t_UU; + case XX_ENCODED: + goto _t_XX; + case B64ENCODED: + goto _t_B64; + case BH_ENCODED: + goto _t_Binhex; + } + + _t_Binhex: /* Binhex Test */ + len = i; s = ptr; + + /* + * bhflag notes the state we're in. Within the data, it's 1. If we're + * still looking for the initial :, it's 0 + */ + if (*bhflag == 0 && *s != ':') { + if (encoding==BH_ENCODED) return 0; + goto _t_B64; + } + else if (*bhflag == 0 /* *s == ':' */) { + s++; len--; + } + + while (len && BHxlat[ACAST(*s)] != -1) { + len--; s++; + } + + /* allow space characters at the end of the line if we are sure */ + /* that this is Binhex encoded data or the line was long enough */ + + flag = (*s == ':') ? 0 : 1; + + if (*s == ':' && len>0) { + s++; len--; + } + if (((i>=60 && len<=10) || encoding) && *s==' ') { + while (len && *s==' ') { + s++; len--; + } + } + + /* + * BinHex data shall have exactly 64 characters (except the last + * line). We ignore everything with less than 40 characters to + * be flexible + */ + + if (len != 0 || (flag && i < 40)) { + if (encoding==BH_ENCODED) return 0; + goto _t_B64; + } + + *bhflag = flag; + + return BH_ENCODED; + + _t_B64: /* Base64 Test */ + len = i; s = ptr; + + /* + * Face it: there _are_ Base64 lines that are not a multiple of four + * in length :-( + * + * if (len%4) + * goto _t_UU; + */ + + while (len--) { + if ((*s & 0x80) || (B64xlat[ACAST(*s)] == -1 && *s != '=')) { + /* allow space characters at the end of the line if we are sure */ + /* that this is Base64 encoded data or the line was long enough */ + if (((i>=60 && len<=10) || encoding) && *s++==' ') { + while (*s==' ' && len) s++; + if (len==0) return B64ENCODED; + } + if (encoding==B64ENCODED) return 0; + goto _t_UU; + } + else if (*s == '=') { /* special case at end */ + /* if we know this is B64encoded, allow spaces at end of line */ + s++; + if (*s=='=' && len>=1) { + len--; s++; + } + if (encoding && len && *s==' ') { + while (len && *s==' ') { + s++; len--; + } + } + if (len != 0) { + if (encoding==B64ENCODED) return 0; + goto _t_UU; + } + return B64ENCODED; + } + s++; + } + return B64ENCODED; + + _t_UU: + len = i; s = ptr; + + if (UUxlat[ACAST(*s)] == -1) { /* uutest */ + if (encoding==UU_ENCODED) return 0; + goto _t_XX; + } + + j = UUxlen[UUxlat[ACAST(*s)]]; + + if (len-1 == j) /* remove trailing character */ + len--; + if (len != j) { + switch (UUxlat[ACAST(*s)]%3) { + case 1: + if (j-2 == len) j-=2; + break; + case 2: + if (j-1 == len) j-=1; + break; + } + } + + /* + * some encoders are broken with respect to encoding the last line of + * a file and produce extraoneous characters beyond the expected EOL + * So were not too picky here about the last line, as long as it's longer + * than necessary and shorter than the maximum + * this tolerance broke the xxdecoding, because xxencoded data was + * detected as being uuencoded :( so don't accept 'h' as first character + * also, if the first character is lowercase, don't accept the line to + * have space characters. the only encoder I've heard of which uses + * lowercase characters at least accepts the special case of encoding + * 0 as `. The strchr() shouldn't be too expensive here as it's only + * evaluated if the first character is lowercase, which really shouldn't + * be in uuencoded text. + */ + if (len != j && + !(*ptr != 'M' && *ptr != 'h' && len > j && len <= UUxlen[UUxlat['M']])) { + if (encoding==UU_ENCODED) return 0; + goto _t_XX; /* bad length */ + } + + if (len != j || islower (*ptr)) { + /* + * if we are not in a 'uuencoded' state, don't allow the line to have + * space characters at all. if we know we _are_ decoding uuencoded + * data, the rest of the line, beyond the length of encoded data, may + * have spaces. + */ + if (encoding != UU_ENCODED) + if (strchr (ptr, ' ') != NULL) + goto _t_XX; + +/* suspicious = 1; we're careful here REMOVED 0.4.15 __FP__ */ + len = j; + } + + while (len--) { + if ((*s & 0x80) || UUxlat[ACAST(*s++)] < 0) { + if (encoding==UU_ENCODED) return 0; + goto _t_XX; /* bad code character */ + } + if (*s == ' ' && suspicious) { + if (encoding==UU_ENCODED) return 0; + goto _t_XX; /* this line looks _too_ suspicious */ + } + } + return UU_ENCODED; /* data is valid */ + + _t_XX: /* XX Test */ + len = i; s = ptr; + + if (XXxlat[ACAST(*s)] == -1) + return 0; + + j = UUxlen[XXxlat[ACAST(*s)]]; /* Same line length table as UUencoding */ + + if (len-1 == j) /* remove trailing character */ + len--; + if (len != j) + switch (UUxlat[ACAST(*s)]%3) { + case 1: + if (j-2 == len) j-=2; + break; + case 2: + if (j-1 == len) j-=1; + break; + } + /* + * some encoders are broken with respect to encoding the last line of + * a file and produce extraoneous characters beyond the expected EOL + * So were not too picky here about the last line, as long as it's longer + * than necessary and shorter than the maximum + */ + if (len != j && !(*ptr != 'h' && len > j && len <= UUxlen[UUxlat['h']])) + return 0; /* bad length */ + + while(len--) { + if((*s & 0x80) || XXxlat[ACAST(*s++)] < 0) { + return 0; /* bad code character */ + } + } + return XX_ENCODED; /* data is valid */ +} + +/* + * This function may be called upon a line that does not look like + * valid encoding on first sight, but might be erroneously encoded + * data from Netscape, Lynx or MS Exchange. We might need to read + * a new line from the stream, which is why we need the FILE. + * Returns the type of encoded data if successful or 0 otherwise. + */ + +int +UURepairData (FILE *datei, char *line, int encoding, int *bhflag) +{ + int nflag, vflag=0, safety=42; + char *ptr; + + nflag = UUBrokenByNetscape (line); + + while (vflag == 0 && nflag && safety--) { + if (nflag == 1) { /* need next line to repair */ + ptr = line + strlen (line); + while (ptr>line && (*(ptr-1)=='\015' || *(ptr-1)=='\012')) + ptr--; + if (_FP_fgets (ptr, 255-(ptr-line), datei) == NULL) + break; + } + else { /* don't need next line to repair */ + } + if (UUNetscapeCollapse (line)) { + if ((vflag = UUValidData (line, encoding, bhflag)) == 0) + nflag = UUBrokenByNetscape (line); + } + else + nflag = 0; + } + /* + * Sometimes, a line is garbled even without it being split into + * the next line. Then we try this in our despair + */ + if (vflag == 0) { + if (UUNetscapeCollapse (line)) + vflag = UUValidData (line, encoding, bhflag); + } + + /* + * If this line looks uuencoded, but the line is one character short + * of a valid line, it was probably broken by MS Exchange. According + * to my test cases, there is at most one space character missing; + * there are never two spaces together. + * If adding a space character helps making this line uuencoded, do + * it! + */ + + if (vflag == 0) { + ptr = line + strlen(line); + while (ptr>line && (*(ptr-1)=='\012' || *(ptr-1)=='\015')) { + ptr--; + } + *ptr++ = ' '; + *ptr-- = '\0'; + if ((vflag = UUValidData (line, encoding, bhflag)) != UU_ENCODED) { + *ptr = '\0'; + vflag = 0; + } + } + return vflag; +} + +/* + * Decode a single encoded line using method + */ + +size_t +UUDecodeLine (char *s, char *d, int method) +{ + int i, j, c, cc, count=0, z1, z2, z3, z4; + static int leftover=0; + int *table; + + /* + * for re-initialization + */ + + if (s == NULL || d == NULL) { + leftover = 0; + return 0; + } + + /* + * To shut up gcc -Wall + */ + z1 = z2 = z3 = z4 = 0; + + if (method == UU_ENCODED || method == XX_ENCODED) { + if (method == UU_ENCODED) + table = UUxlat; + else + table = XXxlat; + + i = table [ACAST(*s++)]; + j = UUxlen[i] - 1; + + while(j > 0) { + c = table[ACAST(*s++)] << 2; + cc = table[ACAST(*s++)]; + c |= (cc >> 4); + + if(i-- > 0) + d[count++] = c; + + cc <<= 4; + c = table[ACAST(*s++)]; + cc |= (c >> 2); + + if(i-- > 0) + d[count++] = cc; + + c <<= 6; + c |= table[ACAST(*s++)]; + + if(i-- > 0) + d[count++] = c; + + j -= 4; + } + } + else if (method == B64ENCODED) { + if (leftover) { + strcpy (uuncdl_fulline+leftover, s); + leftover = 0; + s = uuncdl_fulline; + } + + while ((z1 = B64xlat[ACAST(*s)]) != -1) { + if ((z2 = B64xlat[ACAST(*(s+1))]) == -1) break; + if ((z3 = B64xlat[ACAST(*(s+2))]) == -1) break; + if ((z4 = B64xlat[ACAST(*(s+3))]) == -1) break; + + d[count++] = (z1 << 2) | (z2 >> 4); + d[count++] = (z2 << 4) | (z3 >> 2); + d[count++] = (z3 << 6) | (z4); + + s += 4; + } + if (z1 != -1 && z2 != -1 && *(s+2) == '=') { + d[count++] = (z1 << 2) | (z2 >> 4); + s+=2; + } + else if (z1 != -1 && z2 != -1 && z3 != -1 && *(s+3) == '=') { + d[count++] = (z1 << 2) | (z2 >> 4); + d[count++] = (z2 << 4) | (z3 >> 2); + s+=3; + } + while (B64xlat[ACAST(*s)] != -1) + uuncdl_fulline[leftover++] = *s++; + } + else if (method == BH_ENCODED) { + if (leftover) { + strcpy (uuncdl_fulline+leftover, s); + leftover = 0; + s = uuncdl_fulline; + } + else if (*s == ':') + s++; + + while ((z1 = BHxlat[ACAST(*s)]) != -1) { + if ((z2 = BHxlat[ACAST(*(s+1))]) == -1) break; + if ((z3 = BHxlat[ACAST(*(s+2))]) == -1) break; + if ((z4 = BHxlat[ACAST(*(s+3))]) == -1) break; + + d[count++] = (z1 << 2) | (z2 >> 4); + d[count++] = (z2 << 4) | (z3 >> 2); + d[count++] = (z3 << 6) | (z4); + + s += 4; + } + if (z1 != -1 && z2 != -1 && *(s+2) == ':') { + d[count++] = (z1 << 2) | (z2 >> 4); + s+=2; + } + else if (z1 != -1 && z2 != -1 && z3 != -1 && *(s+3) == ':') { + d[count++] = (z1 << 2) | (z2 >> 4); + d[count++] = (z2 << 4) | (z3 >> 2); + s+=3; + } + while (BHxlat[ACAST(*s)] != -1) + uuncdl_fulline[leftover++] = *s++; + } + + return count; +} + +/* + * ``Decode'' Quoted-Printable text + */ + +int +UUDecodeQP (FILE *datain, FILE *dataout, int *state, + long maxpos, int method, int flags, + char *boundary) +{ + char *line=uugen_inbuffer, *p1, *p2; + int val; + + uulboundary = -1; + + while (!feof (datain) && + (ftell(datain)line && (*(ptr-1) == '\012' || *(ptr-1) == '\015')) + ptr--; + + + /* + * If the part ends directly after this line, the data does not end + * with a linebreak. Or, as the docs put it, "the CRLF preceding the + * encapsulation line is conceptually attached to the boundary. + * So if the part ends here, don't print a line break" + */ + if ((*ptr == '\012' || *ptr == '\015') && + (!feof (datain) && + (ftell(datain) 5) + tf = tc = 0; + vlc = 0; + continue; + } + + /* + * Busy Polls + */ + + if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) { + UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, + uustring (S_DECODE_CANCEL)); + return UURET_CANCEL; + } + + /* + * try to make sense of data + */ + + line[255] = '\0'; /* For Safety of string functions */ + count = 0; + + if (boundary && line[0]=='-' && line[1]=='-' && + strncmp (line+2, boundary, strlen (boundary)) == 0) { + if (line[strlen(boundary)+2]=='-') + uulboundary = 1; + else + uulboundary = 0; + return UURET_OK; + } + + /* + * Use this pseudo-handling only if !FL_PROPER + */ + + if ((flags&FL_PROPER) == 0) { + if (strncmp (line, "BEGIN", 5) == 0 && + _FP_strstr (line, "CUT HERE") && !tf) { /* I hate these lines */ + tc = tf = vlc = 0; + continue; + } + /* MIME body boundary */ + if (line[0] == '-' && line[1] == '-' && method == B64ENCODED) { + if ((haddata || tc) && (haddh || hadct)) { + *state = DONE; + vlc = 0; + lc[0] = lc[1] = 0; + continue; + } + hadct = 0; + haddh = 1; + continue; + } + if (_FP_strnicmp (line, "Content-Type", 12) == 0) + hadct = 1; + } + + if (*state == BEGIN) { + if (strncmp (line, "begin ", 6) == 0 || + _FP_strnicmp (line, "

begin ", 11) == 0) {    /* for LYNX */
+	*state = DATA;
+	continue;
+      }
+      else if (method == BH_ENCODED && line[0] == ':') {
+	if (UUValidData (line, BH_ENCODED, &bhflag) == BH_ENCODED) {
+	  bhflag = 0;
+	  *state = DATA;
+	}
+	else
+	  continue;
+      }
+      else
+	continue;
+      
+      tc = tf = vlc = 0;
+      lc[0] = lc[1] = 0;
+    }
+    else if ((*state == END) &&
+	     (method == UU_ENCODED || method == XX_ENCODED)) {
+      if (strncmp (line, "end", 3) == 0) {
+	*state = DONE;
+	break;
+      }
+    }
+    if (*state == DATA || *state == END) {
+      if (method==B64ENCODED && line[0]=='-' && line[1]=='-' && tc) {
+	break;
+      }
+
+      if ((vflag = UUValidData (line, (tf)?method:0, &bhflag)) == 0)
+	vflag = UURepairData (datain, line, (tf)?method:0, &bhflag);
+
+      /*
+       * correct XX/UUencoded lines that were declared Base64
+       */
+
+      if ((method == XX_ENCODED || method == UU_ENCODED) &&
+	  vflag == B64ENCODED) {
+	if (UUValidData (line, method, &bhflag) == method)
+	  vflag = method;
+      }
+
+      if (vflag == method) {
+	if (tf) {
+	  count  = UUDecodeLine (line, oline, method);
+	  vlc++; lc[1]++;
+	}
+	else if (tc == 3) {
+	  count  = UUDecodeLine (save[0], oline,         method);
+	  count += UUDecodeLine (save[1], oline + count, method);
+	  count += UUDecodeLine (save[2], oline + count, method);
+	  count += UUDecodeLine (line,    oline + count, method);
+	  tf     = 1;
+	  tc     = 0;
+
+	  /*
+	   * complain if we had one or two invalid lines amidst of
+	   * correctly encoded data. This usually means that the
+	   * file is in error
+	   */
+
+	  if (lc[1] > 10 && (lc[0] >= 1 && lc[0] <= 2) && !warning) {
+	    UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		       uustring (S_DATA_SUSPICIOUS));
+	    warning=1;
+	  }
+	  lc[0] = 0;
+	  lc[1] = 3;
+	}
+	else {
+	  _FP_strncpy (save[tc++], line, 256);
+	}
+	if (method == UU_ENCODED)
+	  *state = (line[0] == 'M') ? DATA : END;
+	else if (method == XX_ENCODED)
+	  *state = (line[0] == 'h') ? DATA : END;
+	else if (method == B64ENCODED)
+	  *state = (strchr (line, '=') == NULL) ? DATA : DONE;
+	else if (method == BH_ENCODED)
+	  *state = (!line[0] || strchr(line+1,':')==NULL)?DATA:DONE;
+      }
+      else {
+	vlc = tf = tc = 0;
+	haddh = 0;
+	lc[0]++;
+      }
+    }
+    else if (*state != DONE) {
+      return UURET_NOEND;
+    }
+    if (count) {
+      if (method == BH_ENCODED) {
+	if (UUbhwrite (oline, 1, count, dataout) != count) {
+	  UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		     uustring (S_WR_ERR_TEMP),
+		     strerror (uu_errno = errno));
+	  return UURET_IOERR;
+	}
+      }
+      else if (fwrite (oline, 1, count, dataout) != count) {
+	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		   uustring (S_WR_ERR_TEMP),
+		   strerror (uu_errno = errno));
+	return UURET_IOERR;
+      }
+      haddata++;
+      count = 0;
+    }
+  }
+
+  if (*state  == DONE ||
+      (*state == DATA && method == B64ENCODED &&
+       vflag == B64ENCODED && (flags&FL_PROPER || haddh))) {
+    for (tf=0; tfthisfile == NULL)
+    return UURET_ILLVAL;
+
+  if (data->state & UUFILE_TMPFILE)
+    return UURET_OK;
+
+  if (data->state & UUFILE_NODATA)
+    return UURET_NODATA;
+
+  if (data->state & UUFILE_NOBEGIN && !uu_desperate)
+    return UURET_NODATA;
+
+  if (data->uudet == QP_ENCODED || data->uudet == PT_ENCODED)
+    mode = "wt";	/* open text files in text mode */
+  else
+    mode = "wb";	/* otherwise in binary          */
+
+  if ((data->binfile = tempnam (NULL, "uu")) == NULL) {
+    UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+	       uustring (S_NO_TEMP_NAME));
+    return UURET_NOMEM;
+  }
+
+  if ((dataout = fopen (data->binfile, mode)) == NULL) {
+    /*
+     * we couldn't create a temporary file. Usually this means that TMP
+     * and TEMP aren't set
+     */
+    UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+	       uustring (S_WR_ERR_TARGET),
+	       data->binfile, strerror (uu_errno = errno));
+    _FP_free (data->binfile);
+    data->binfile = NULL;
+    uu_errno = errno;
+    return UURET_IOERR;
+  }
+  /*
+   * we don't have begin lines in Base64 or plain text files.
+   */
+  if (data->uudet == B64ENCODED || data->uudet == QP_ENCODED ||
+      data->uudet == PT_ENCODED)
+    state = DATA;
+
+  /*
+   * If we know that the file does not have a begin, we simulate
+   * it in desperate mode
+   */
+
+  if ((data->state & UUFILE_NOBEGIN) && uu_desperate)
+    state = DATA;
+
+  (void) UUDecodeLine (NULL, NULL, 0);                   /* init */
+  (void) UUbhwrite    (NULL, 0, 0, NULL);                /* dito */
+  (void) UUDecodePart (NULL, NULL, NULL, 0, 0, 0, NULL); /* yep  */
+
+  /*
+   * initialize progress information
+   */
+  progress.action = 0;
+  if (data->filename != NULL) {
+    _FP_strncpy (progress.curfile,
+		 (strlen(data->filename)>255)?
+		 (data->filename+strlen(data->filename)-255):data->filename,
+		 256);
+  }
+  else {
+    _FP_strncpy (progress.curfile,
+		 (strlen(data->binfile)>255)?
+		 (data->binfile+strlen(data->binfile)-255):data->binfile,
+		 256);
+  }
+  progress.partno   =  0;
+  progress.numparts =  0;
+  progress.fsize    = -1;
+  progress.percent  =  0;
+  progress.action   =  UUACT_DECODING;
+
+  iter = data->thisfile;
+  while (iter) {
+    progress.numparts = (iter->partno)?iter->partno:1;
+    iter = iter->NEXT;
+  }
+  
+  /*
+   * let's rock!
+   */
+
+  iter = data->thisfile;
+  while (iter) {
+    if (part != -1 && iter->partno != part+1)
+      break;
+    else
+      part = iter->partno;
+
+    if (iter->data->sfname == NULL) {
+      iter = iter->NEXT;
+      continue;
+    }
+
+    /*
+     * call our FileCallback to retrieve the file
+     */
+
+    if (uu_FileCallback) {
+      if ((res = (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname,
+				     uugen_fnbuffer, 1)) != UURET_OK)
+	break;
+      if ((datain = fopen (uugen_fnbuffer, "rb")) == NULL) {
+	(*uu_FileCallback) (uu_FileCBArg, iter->data->sfname,
+			    uugen_fnbuffer, 0);
+	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		   uustring (S_NOT_OPEN_FILE),
+		   uugen_fnbuffer, strerror (uu_errno = errno));
+	res = UURET_IOERR;
+	break;
+      }
+    }
+    else {
+      if ((datain = fopen (iter->data->sfname, "rb")) == NULL) {
+	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		   uustring (S_NOT_OPEN_FILE),
+		   iter->data->sfname, strerror (uu_errno = errno));
+	res = UURET_IOERR;
+	break;
+      }
+      _FP_strncpy (uugen_fnbuffer, iter->data->sfname, 1024);
+    }
+
+    progress.partno  = part;
+    progress.fsize   = (iter->data->length)?iter->data->length:-1;
+    progress.percent = 0;
+    progress.foffset = iter->data->startpos;
+
+    fseek              (datain, iter->data->startpos, SEEK_SET);
+    res = UUDecodePart (datain, dataout, &state,
+			iter->data->startpos+iter->data->length,
+			data->uudet, iter->data->flags, NULL);
+    fclose             (datain);
+
+    if (uu_FileCallback)
+      (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname, uugen_fnbuffer, 0);
+
+    if (state == DONE || res != UURET_OK)
+      break;
+
+    iter = iter->NEXT;
+  }
+
+  if (state == DATA && 
+      (data->uudet == B64ENCODED || data->uudet == QP_ENCODED ||
+       data->uudet == PT_ENCODED))
+    state = DONE; /* assume we're done */
+
+  fclose (dataout);
+
+  if (res != UURET_OK || (state != DONE && !uu_desperate)) {
+    unlink (data->binfile);
+    _FP_free (data->binfile);
+    data->binfile = NULL;
+    data->state  &= ~UUFILE_TMPFILE;
+    data->state  |=  UUFILE_ERROR;
+
+    if (res == UURET_OK && state != DONE)
+      res = UURET_NOEND;
+  }
+  else if (res != UURET_OK) {
+    data->state &= ~UUFILE_DECODED;
+    data->state |=  UUFILE_ERROR | UUFILE_TMPFILE;
+  }
+  else {
+    data->state &= ~UUFILE_ERROR;
+    data->state |=  UUFILE_TMPFILE;
+  }
+
+  /*
+   * If this was a BinHex file, we must extract its data or resource fork
+   */
+
+  if (data->uudet == BH_ENCODED && data->binfile) {
+    if ((ntmp = tempnam (NULL, "uu")) == NULL) {
+      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		 uustring (S_NO_TEMP_NAME));
+      progress.action = 0;
+      return UURET_NOMEM;
+    }
+    if ((datain = fopen (data->binfile, "rb")) == NULL) {
+      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		 uustring (S_NOT_OPEN_FILE),
+		 data->binfile, strerror (uu_errno = errno));
+      progress.action = 0;
+      free (ntmp);
+      return UURET_IOERR;
+    }
+    if ((dataout = fopen (ntmp, "wb")) == NULL) {
+      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		 uustring (S_NOT_OPEN_TARGET),
+		 ntmp, strerror (uu_errno = errno));
+      progress.action = 0;
+      fclose (datain);
+      free   (ntmp);
+      return UURET_IOERR;
+    }
+    /*
+     * read fork lengths. remember they're in Motorola format
+     */
+    r[0] = fgetc (datain);
+    hb   = (int) r[0] + 22;
+    fseek (datain, (int) r[0] + 12, SEEK_SET);
+    fread (r, 1, 8, datain);
+
+    dsize = (((long) 1 << 24) * (long) r[0]) +
+            (((long) 1 << 16) * (long) r[1]) +
+            (((long) 1 <<  8) * (long) r[2]) +
+            (                   (long) r[3]);
+    rsize = (((long) 1 << 24) * (long) r[4]) +
+	    (((long) 1 << 16) * (long) r[5]) +
+	    (((long) 1 <<  8) * (long) r[6]) +
+	    (                   (long) r[7]);
+
+    UUMessage (uunconc_id, __LINE__, UUMSG_MESSAGE,
+	       uustring (S_BINHEX_SIZES),
+	       dsize, rsize);
+
+    if (dsize == 0) {
+      fseek  (datain, dsize + hb + 2, SEEK_SET);
+      numbytes = rsize;
+    }
+    else if (rsize == 0) {
+      fseek  (datain, hb, SEEK_SET);
+      numbytes = dsize;
+    }
+    else {
+      /* we should let the user have the choice here */
+      UUMessage (uunconc_id, __LINE__, UUMSG_NOTE,
+		 uustring (S_BINHEX_BOTH));
+      fseek  (datain, hb, SEEK_SET);
+      numbytes = dsize;
+    }
+
+    progress.action   = 0;
+    progress.partno   = 0;
+    progress.numparts = 1;
+    progress.fsize    = (numbytes)?numbytes:-1;
+    progress.foffset  = hb;
+    progress.percent  = 0;
+    progress.action   = UUACT_COPYING;
+
+    /*
+     * copy the chosen fork
+     */
+
+    while (!feof (datain) && numbytes) {
+      if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) {
+	UUMessage (uunconc_id, __LINE__, UUMSG_NOTE,
+		   uustring (S_DECODE_CANCEL));
+	fclose (datain);
+	fclose (dataout);
+	unlink (ntmp);
+	free   (ntmp);
+	return UURET_CANCEL;
+      }
+
+      bytes = fread (uugen_inbuffer, 1,
+		     (size_t) ((numbytes>1024)?1024:numbytes), datain);
+
+      if (ferror (datain) || (bytes == 0 && !feof (datain))) {
+	progress.action = 0;
+	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		   uustring (S_SOURCE_READ_ERR),
+		   data->binfile, strerror (uu_errno = errno));
+	fclose (datain);
+	fclose (dataout);
+	unlink (ntmp);
+	free   (ntmp);
+	return UURET_IOERR;
+      }
+      if (fwrite (uugen_inbuffer, 1, bytes, dataout) != bytes) {
+	progress.action = 0;
+	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
+		   uustring (S_WR_ERR_TARGET),
+		   ntmp, strerror (uu_errno = errno));
+	fclose (datain);
+	fclose (dataout);
+	unlink (ntmp);
+	free   (ntmp);
+	return UURET_IOERR;
+      }
+      numbytes -= bytes;
+    }
+
+    if (numbytes) {
+      UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		 uustring (S_SHORT_BINHEX),
+		 (data->filename)?data->filename:
+		 (data->subfname)?data->subfname:"???",
+		 numbytes);
+    }
+
+    /*
+     * replace temp file
+     */
+
+    fclose (datain);
+    fclose (dataout);
+
+    if (unlink (data->binfile)) {
+      UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
+		 uustring (S_TMP_NOT_REMOVED),
+		 data->binfile, strerror (uu_errno = errno));
+    }
+
+    free (data->binfile);
+    data->binfile = ntmp;
+  }
+
+  progress.action = 0;
+  return res;
+}
+
+/*
+ * QuickDecode for proper MIME attachments. We expect the pointer to
+ * be on the first header line.
+ */
+
+int
+UUQuickDecode (FILE *datain, FILE *dataout, char *boundary, long maxpos)
+{
+  int state=BEGIN, encoding=-1;
+  headers myenv;
+
+  /*
+   * Read header and find out about encoding.
+   */
+
+  memset (&myenv, 0, sizeof (headers));
+  UUScanHeader (datain, &myenv);
+
+  if (_FP_stristr (myenv.ctenc, "uu") != NULL)
+    encoding = UU_ENCODED;
+  else if (_FP_stristr (myenv.ctenc, "xx") != NULL)
+    encoding = XX_ENCODED;
+  else if (_FP_stricmp (myenv.ctenc, "base64") == 0)
+    encoding = B64ENCODED;
+  else if (_FP_stricmp (myenv.ctenc, "quoted-printable") == 0)
+    encoding = QP_ENCODED;
+  else
+    encoding = PT_ENCODED;
+
+  UUkillheaders (&myenv);
+
+  /*
+   * okay, so decode this one
+   */
+
+  (void) UUDecodePart (NULL, NULL, NULL, 0, 0, 0, NULL); /* init  */
+  return UUDecodePart (datain, dataout, &state, maxpos,
+		       encoding, FL_PROPER|FL_TOEND,
+		       boundary);
+}
diff --git a/goldlib/uulib/uuscan.c b/goldlib/uulib/uuscan.c
new file mode 100644
index 0000000..c770d22
--- /dev/null
+++ b/goldlib/uulib/uuscan.c
@@ -0,0 +1,2751 @@
+/*
+ * This file is part of uudeview, the simple and friendly multi-part multi-
+ * file uudecoder  program  (c)  1994 by Frank Pilhofer. The author may be
+ * contacted by his email address,          fp@informatik.uni-frankfurt.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * These are very central functions of UUDeview. Here, we scan a file
+ * and decide whether it contains encoded data or not. ScanPart() must
+ * be called repeatedly on the same file until feof(file). Each time,
+ * it returns information about the next part found within.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef SYSTEM_WINDLL
+#include 
+#endif
+#ifdef SYSTEM_OS2
+#include 
+#endif
+
+#include 
+#include 
+
+#ifdef STDC_HEADERS
+#include 
+#include 
+#endif
+#ifdef HAVE_MALLOC_H
+#include 
+#endif
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+#ifdef HAVE_MEMORY_H
+#include 
+#endif
+#ifdef HAVE_ERRNO_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+char * uuscan_id = "$Id$";
+
+/*
+ * Header fields we recognize as such. See RFC822. We add "From ",
+ * the usual marker for a beginning of a new message, and a couple
+ * of usual MDA, News and MIME headers.
+ * We make a distinction of MIME headers as we need the difference
+ * to scan the bodies from partial multipart messages.
+ */
+
+static char *knownmsgheaders[] = {
+  "From ", "Return-Path:", "Received:", "Reply-To:",
+  "From:", "Sender:", "Resent-Reply-To:", "Resent-From:",
+  "Resent-Sender:", "Date:", "Resent-Date:", "To:",
+  "Resent-To:", "Cc:", "Bcc:", "Resent-bcc:",
+  "Message-ID:", "Resent-Message-Id:", "In-Reply-To:",
+  "References:", "Keywords:", "Subject:", "Comments:",
+  
+  "Delivery-Date:", "Posted-Date:", "Received-Date:",
+  "Precedence:", 
+
+  "Path:", "Newsgroups:", "Organization:", "Lines:",
+  "NNTP-Posting-Host:",
+  NULL
+};
+
+static char *knownmimeheaders[] = {
+  "Mime-Version:",  "Content-Transfer-Encoding:",
+  "Content-Type:", "Content-Disposition:", 
+  "Content-Description:", "Content-Length:",
+  NULL
+};
+
+/*
+ * for MIME (plaintext) parts without filename
+ */
+int mimseqno;
+
+/*
+ * how many lines do we read when checking for headers
+ */
+#define WAITHEADER	10
+
+/*
+ * The stack for encapsulated Multipart messages
+ */
+#define MSMAXDEPTH	3
+
+int       mssdepth = 0;
+scanstate multistack[MSMAXDEPTH+1];
+
+/*
+ * The state and the local envelope
+ */
+headers   localenv;
+scanstate sstate;
+
+/*
+ * mallocable areas
+ */
+
+char *uuscan_shlline;
+char *uuscan_pvvalue;
+char *uuscan_phtext;
+char *uuscan_sdline;
+char *uuscan_sdbhds1;
+char *uuscan_sdbhds2;
+char *uuscan_spline;
+
+/*
+ * If this is changed to define, some workarounds for broken files are
+ * disabled
+ */
+#undef MORE_MIME
+
+/*
+ * Macro: print cancellation message in UUScanPart
+ */
+
+#define SPCANCEL()	{UUMessage(uuscan_id,__LINE__,UUMSG_NOTE,uustring(S_SCAN_CANCEL));*errcode=UURET_CANCEL;goto ScanPartEmergency;}
+
+/*
+ * Is line empty? A line is empty if it is composed of whitespace.
+ */
+
+static int
+IsLineEmpty (char *data)
+{
+  if (data == NULL) return 0;
+  while (*data && isspace (*data)) data++;
+  return ((*data)?0:1);
+}
+
+/*
+ * Scans a potentially folded header line from the input file. If
+ * initial is non-NULL, it is the first line of the header, useful
+ * if the calling function just coincidentally noticed that this is
+ * a header.
+ * RFC0822 does not specify a maximum length for headers, but we
+ * truncate everything beyond an insane value of 1024 characters.
+ */
+
+static char *
+ScanHeaderLine (FILE *datei, char *initial)
+{
+  char *ptr=uuscan_shlline;
+  int llength, c;
+  long curpos;
+  int hadcr;
+
+  if (initial) {
+    _FP_strncpy (uuscan_shlline, initial, 1024);
+  }
+  else {
+    /* read first line */
+    if (feof (datei) || ferror (datei))
+      return NULL;
+    if (_FP_fgets (uuscan_shlline, 1023, datei) == NULL)
+      return NULL;
+    uuscan_shlline[1023] = '\0';
+  }
+
+  llength = strlen (uuscan_shlline);
+  hadcr   = 0;
+
+  /* strip whitespace at end */
+  ptr = uuscan_shlline + llength;
+  while (llength && isspace(*(ptr-1))) {
+    if (*(ptr-1) == '\012' || *(ptr-1) == '\015')
+      hadcr = 1;
+    ptr--; llength--;
+  }
+  if (llength == 0) {
+    uuscan_shlline[0] = '\0';
+    return uuscan_shlline;
+  }
+
+  while (!feof (datei)) {
+    c = fgetc (datei);
+    if (feof (datei))
+      break;
+
+    /*
+     * If the line didn't have a CR, it was longer than 256 characters
+     * and is continued anyway.
+     */
+
+    if (hadcr==1 && c != ' ' && c != '\t') {
+      /* no LWSP-char, header line does not continue */
+      ungetc (c, datei);
+      break;
+    }
+    while (!feof (datei) && (c == ' ' || c == '\t'))
+      c = fgetc (datei);
+
+    if (!feof (datei))
+      ungetc (c, datei);	/* push back for fgets() */
+
+    /* insert a single LWSP */
+    if (hadcr==1 && llength < 1023) {
+      *ptr++ = ' ';
+      llength++;
+    }
+    *ptr = '\0'; /* make lint happier */
+
+    if (feof (datei))
+      break;
+
+    /* read next line */
+    curpos = ftell (datei);
+    if (_FP_fgets (uugen_inbuffer, 255, datei) == NULL)
+      break;
+    uugen_inbuffer[255] = '\0';
+
+    if (IsLineEmpty (uugen_inbuffer)) { /* oops */
+      fseek (datei, curpos, SEEK_SET);
+      break;
+    }
+
+    _FP_strncpy (ptr, uugen_inbuffer, 1024-llength);
+
+    /*
+     * see if line was terminated with CR. Otherwise, it continues ...
+     */
+    c = strlen (ptr);
+    if (c>0 && (ptr[c-1] == '\012' || ptr[c-1] == '\015'))
+      hadcr = 1;
+    else
+      hadcr = 0;
+
+    /*
+     * strip whitespace
+     */
+
+    ptr     += c;
+    llength += c;
+    while (llength && isspace(*(ptr-1))) {
+      ptr--; llength--;
+    }
+  }
+  *ptr = '\0';
+
+  if (llength == 0)
+    return NULL;
+
+  return uuscan_shlline;
+}
+
+/*
+ * Extract the value from a MIME attribute=value pair. This function
+ * receives a pointer to the attribute.
+ */
+static char *
+ParseValue (char *attribute)
+{
+  char *ptr=uuscan_pvvalue;
+  int length=0;
+
+  if (attribute == NULL)
+    return NULL;
+
+  while ((isalnum(*attribute) || *attribute=='_') && *attribute != '=')
+    attribute++;
+
+  while (isspace(*attribute))
+    attribute++;
+
+  if (*attribute == '=') {
+    attribute++;
+    while (isspace (*attribute))
+      attribute++;
+  }
+  else
+    return NULL;
+
+  if (*attribute == '"') {
+    /* quoted-string */
+    attribute++;
+    while (*attribute && *attribute != '"' && length < 255) {
+      if (*attribute == '\\')
+	*ptr++ = *++attribute;
+      else
+	*ptr++ = *attribute;
+      attribute++;
+      length++;
+    }
+    *ptr = '\0';
+  }
+  else {
+    /* tspecials from RFC1521 */
+
+    while (*attribute && !isspace (*attribute) &&
+	   *attribute != '(' && *attribute != ')' &&
+	   *attribute != '<' && *attribute != '>' &&
+	   *attribute != '@' && *attribute != ',' &&
+	   *attribute != ';' && *attribute != ':' &&
+	   *attribute != '\\' &&*attribute != '"' &&
+	   *attribute != '/' && *attribute != '[' &&
+	   *attribute != ']' && *attribute != '?' &&
+	   *attribute != '=' && length < 255)
+      *ptr++ = *attribute++;
+
+    *ptr = '\0';
+  }
+  return uuscan_pvvalue;
+}
+
+/*
+ * Extract the information we need from header fields
+ */
+
+static headers *
+ParseHeader (headers *theheaders, char *line)
+{
+  char **variable=NULL;
+  char *value, *ptr, *thenew;
+  int delimit, length;
+
+  if (line == NULL)
+    return theheaders;
+
+  value = NULL; delimit = 0;
+
+  if (_FP_strnicmp (line, "From:", 5) == 0) {
+    if (theheaders->from) return theheaders;
+    variable = &theheaders->from;
+    value    = line+5;
+  }
+  else if (_FP_strnicmp (line, "Subject:", 8) == 0) {
+    if (theheaders->subject) return theheaders;
+    variable = &theheaders->subject;
+    value    = line+8;
+  }
+  else if (_FP_strnicmp (line, "To:", 3) == 0) {
+    if (theheaders->rcpt) return theheaders;
+    variable = &theheaders->rcpt;
+    value    = line+3;
+  }
+  else if (_FP_strnicmp (line, "Date:", 5) == 0) {
+    if (theheaders->date) return theheaders;
+    variable = &theheaders->date;
+    value    = line+5;
+  }
+  else if (_FP_strnicmp (line, "Mime-Version:", 13) == 0) {
+    if (theheaders->mimevers) return theheaders;
+    variable = &theheaders->mimevers;
+    value    = line+13;
+  }
+  else if (_FP_strnicmp (line, "Content-Type:", 13) == 0) {
+    if (theheaders->ctype) return theheaders;
+    variable = &theheaders->ctype;
+    value    = line+13;
+    delimit  = ';';
+
+    /* we can probably extract more information */
+    if ((ptr = _FP_stristr (line, "boundary")) != NULL) {
+      if ((thenew = ParseValue (ptr))) {
+	if (theheaders->boundary) free (theheaders->boundary);
+	theheaders->boundary = _FP_strdup (thenew);
+      }
+    }
+    if ((ptr = _FP_stristr (line, "name")) != NULL) {
+      if ((thenew = ParseValue (ptr))) {
+	if (theheaders->fname) free (theheaders->fname);
+	theheaders->fname = _FP_strdup (thenew);
+      }
+    }
+    if ((ptr = _FP_stristr (line, "id")) != NULL) {
+      if ((thenew = ParseValue (ptr))) {
+	if (theheaders->mimeid) free (theheaders->mimeid);
+	theheaders->mimeid = _FP_strdup (thenew);
+      }
+    }
+    if ((ptr = _FP_stristr (line, "number")) != NULL) {
+      if ((thenew = ParseValue (ptr))) {
+	theheaders->partno = atoi (thenew);
+      }
+    }
+    if ((ptr = _FP_stristr (line, "total")) != NULL) {
+      if ((thenew = ParseValue (ptr))) {
+	theheaders->numparts = atoi (thenew);
+      }
+    }
+  }
+  else if (_FP_strnicmp (line, "Content-Transfer-Encoding:", 26) == 0) {
+    if (theheaders->ctenc) return theheaders;
+    variable = &theheaders->ctenc;
+    value    = line+26;
+    delimit  = ';';
+  }
+  else if (_FP_strnicmp (line, "Content-Disposition:", 20) == 0) {
+    /*
+     * Some encoders mention the original filename as parameter to
+     * Content-Type, others as parameter to Content-Disposition. We
+     * do prefer the first solution, but accept this situation, too.
+     * TODO: Read RFC1806
+     */
+    if ((ptr = _FP_stristr (line, "name")) != NULL) {
+      if (theheaders->fname == NULL && (thenew=ParseValue(ptr)) != NULL) {
+	theheaders->fname = _FP_strdup (thenew);
+      }
+    }
+    variable = NULL;
+  }
+  else {
+    /*
+     * nothing interesting
+     */
+    variable = NULL;
+  }
+
+  /*
+   * okay, so extract the actual data
+   */
+  if (variable) {
+    length = 0;
+    ptr = uuscan_phtext;
+
+    while (isspace (*value))
+      value++;
+    while (*value && (delimit==0 || *value!=delimit) &&
+	   *value != '\012' && *value != '\015' && length < 255) {
+      *ptr++ = *value++;
+      length++;
+    }
+    while (length && isspace(*(ptr-1))) {
+      ptr--; length--;
+    }
+    *ptr = '\0';
+
+    if ((*variable = _FP_strdup (uuscan_phtext)) == NULL)
+      return NULL;
+  }
+
+  return theheaders;
+}
+
+/*
+ * is this a header line we know about?
+ */
+
+static int
+IsKnownHeader (char *line)
+{
+  char **iter = knownmsgheaders;
+
+  while (iter && *iter) {
+    if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
+      return 1;
+    iter++;
+  }
+
+  iter = knownmimeheaders;
+
+  while (iter && *iter) {
+    if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
+      return 2;
+    iter++;
+  }
+
+  return 0;
+}
+
+/*
+ * Scan a header
+ */
+
+int
+UUScanHeader (FILE *datei, headers *envelope)
+{
+  char *ptr;
+
+  while (!feof (datei)) {
+    if ((ptr = ScanHeaderLine (datei, NULL)) == NULL)
+      break;
+    if (*ptr == '\0' || *ptr == '\012' || *ptr == '\015')
+      break;
+    ParseHeader (envelope, ptr);
+  }
+  return 0;
+}
+
+/*
+ * Scan something for encoded data and fill the fileread* structure.
+ * If boundary is non-NULL, we stop after having read it. If Check-
+ * Headers != 0, we also stop after we've found uu_headercount recog-
+ * nized header lines.
+ * If we have a boundary, then we also don't accept Base64; MIME mails
+ * really should handle this properly.
+ * We return -1 if something went wrong, 0 if everything is normal,
+ * 1 if we found a new header and 2 if we found a boundary.
+ * In MIME message bodies (not multiparts), we also disable our reduced
+ * MIME handling.
+ */
+
+static int
+ScanData (FILE *datei, char *fname, int *errcode,
+	  char *boundary, int ismime, int checkheaders,
+	  fileread *result)
+{
+  char *line=uuscan_sdline, *bhds1=uuscan_sdbhds1, *bhds2=uuscan_sdbhds2;
+  static char *ptr, *p2, *p3=NULL, *bhdsp, bhl;
+  int bhflag=0, vflag, haddh=0, hadct=0;
+  int bhrpc=0, bhnf=0, c, hcount, lcount, blen;
+  int encoding=0, dflag=0, ctline=42;
+  int dontcare=0, hadnl=0;
+  long preheaders = 0, oldposition;
+  size_t dcc, bhopc;
+
+  *errcode = UURET_OK;
+  (void) UUDecodeLine (NULL, NULL, 0);          /* init */
+  bhdsp = bhds2;
+
+  if (datei == NULL || feof (datei))
+    return -1;
+
+  result->startpos = ftell (datei);
+  hcount = lcount  = 0;
+
+  blen = (boundary) ? strlen (boundary) : 0;
+
+  while (!feof (datei)) {
+    oldposition = ftell (datei);
+    if (_FP_fgets (line, 255, datei) == NULL)
+      break;
+    if (ferror (datei))
+      break;
+
+    line[255] = '\0'; /* For Safety of string functions */
+
+    if (IsLineEmpty (line)) { /* line empty? */
+      hcount = 0;
+      hadnl  = 1;
+      continue;                                   /* then ignore */
+    }
+
+    /*
+     * Make Busy Polls
+     */
+    if (UUBUSYPOLL(ftell(datei),progress.fsize)) {
+      UUMessage (uuscan_id, __LINE__, UUMSG_NOTE,
+		 uustring (S_SCAN_CANCEL));
+      *errcode = UURET_CANCEL;
+      break;
+    }
+
+    if (checkheaders) {
+      if (IsKnownHeader (line)) {
+	(void) ScanHeaderLine (datei, line);
+
+	if (hcount == 0) {
+	  preheaders = oldposition;
+	  lcount     = 0;
+	}
+	hcount++;
+	lcount++;
+
+	/*
+	 * check for the various restart counters
+	 */
+
+	if ((hcount >= hlcount.restart) ||
+	    (hcount >= hlcount.afterdata && ismime == 0) ||
+	    (hcount >= hlcount.afterdata && result->uudet) ||
+	    (hcount >= hlcount.afternl   && result->uudet && hadnl)) {
+	  /*
+	   * Hey, a new header starts here
+	   */
+	  fseek (datei, preheaders, SEEK_SET);
+	  break;
+	}
+	/* continue; */
+      }
+      else if (lcount > WAITHEADER) {
+	hcount = 0;
+	lcount = 0;
+	dontcare=0;
+      }
+      else if (hcount) {
+	lcount++;
+	dontcare=1;
+      }
+      else {
+	dontcare=0;
+      }
+    }
+    else {
+      dontcare=0;
+    }
+    if (boundary != NULL && 
+	line[0] == '-' && line[1] == '-' &&
+	strncmp (line+2, boundary, blen) == 0) {
+      fseek (datei, oldposition, SEEK_SET);
+      break;
+    }
+    if (boundary != NULL && line[0] == 'C' && line[1] == 'o' &&
+	_FP_strnicmp (line, "Content-Type:", 13) == 0) {
+      ptr = ScanHeaderLine (datei, line);
+      p2  = (ptr)?_FP_stristr(ptr,"boundary"):NULL;
+      p3  = (p2)?ParseValue(p2):NULL;
+
+      if (p3 && strcmp (p3, boundary) == 0) {
+	fseek (datei, oldposition, SEEK_SET);
+	break;
+      }
+      else {
+	p3 = NULL;
+      }
+    }
+
+    if (strncmp      (line, "begin ",       6) == 0 ||
+	_FP_strnicmp (line, "
begin ", 11) == 0) {
+      if (result->begin || result->end ||
+	  result->uudet == B64ENCODED || result->uudet == BH_ENCODED) {
+	fseek (datei, oldposition, SEEK_SET);
+	break;
+      }
+      
+      if (*line == '<')
+	ptr = line + 10;
+      else
+	ptr = line + 5;
+
+      while (*ptr == ' ') ptr++;
+      while (isdigit (*ptr)) 
+	result->mode = result->mode * 8 + *ptr++ - '0';
+      while (*ptr == ' ') ptr++;
+
+      /*
+       * We may have picked up a filename from a uuenview-style header
+       */
+      _FP_free (result->filename);
+      result->filename = _FP_strdup (ptr);
+      result->begin    = 1;
+
+      while (isspace (result->filename[strlen(result->filename)-1]))
+	result->filename[strlen(result->filename)-1] = '\0';
+
+      continue;
+    }
+
+    if ((strncmp (line, "end", 3) == 0) && result->uudet != BH_ENCODED) {
+      if (result->uudet == B64ENCODED && result->begin)
+	result->uudet = XX_ENCODED;
+
+      if (result->uudet != B64ENCODED) {
+	result->end = 1;
+	if (dflag && encoding)
+	  result->uudet = encoding;
+	continue;
+      }
+    }
+
+    hadnl = 0;
+
+    /*
+     * Detect a UUDeview-Style header
+     */
+
+    if (_FP_strnicmp (line, "_=_ Part ", 9) == 0) {
+      if (result->uudet) {
+	fseek (datei, oldposition, SEEK_SET);
+	break;
+      }
+      result->partno = atoi (line + 8);
+      if ((ptr = _FP_stristr (line, "of file ")) != NULL) {
+	ptr += 8;
+	while (isspace (*ptr)) ptr++;
+	p2 = ptr;
+	while (isalnum(*p2) || 
+	       *p2 == '.' || *p2=='_' || *p2 == '-' ||
+	       *p2 == '!' || *p2=='@' || *p2 == '$')
+	  p2++;
+	c = *p2; *p2 = '\0';
+	if (p2 != ptr && result->filename == NULL)
+	  result->filename = _FP_strdup (ptr);
+	else if (p2 - ptr > 5 && strchr (ptr, '.') != NULL) {
+	  /*
+	   * This file name looks good, too. Let's use it
+	   */
+	  _FP_free (result->filename);
+	  result->filename = _FP_strdup (ptr);
+	}
+	*p2 = c;
+      }
+    }
+
+    /*
+     * Some reduced MIME handling. Only use if boundary == NULL. Also
+     * accept the "X-Orcl-Content-Type" used by some braindead program.
+     */
+    if (boundary == NULL && !ismime) {
+      if (_FP_strnicmp (line, "Content-Type", 12) == 0 ||
+	  _FP_strnicmp (line, "X-Orcl-Content-Type", 19) == 0) {
+	/*
+	 * We use Content-Type to mark a new attachment and split the file.
+	 * However, we do not split if we haven't found anything encoded yet.
+	 */
+	if (result->uudet) {
+	  fseek (datei, oldposition, SEEK_SET);
+	  break;
+	}
+	if ((ptr = strchr (line, ':')) != NULL) {
+	  ptr++;
+	  while (isspace (*ptr)) ptr++; p2 = ptr;
+	  while (!isspace (*p2) && *p2 != ';') p2++;
+	  c = *p2; *p2 = '\0';
+	  if (p2 != ptr) {
+	    _FP_free (result->mimetype);
+	    result->mimetype = _FP_strdup (ptr);
+	  }
+	  *p2 = c;
+	}
+	ctline=0;
+	hadct=1;
+      }
+      if ((ptr = _FP_stristr (line, "number=")) && ctline<4) {
+	ptr += 7; if (*ptr == '"') ptr++;
+	result->partno = atoi (ptr);
+      }
+      if ((ptr = _FP_stristr (line, "total=")) && ctline<4) {
+	ptr += 6; if (*ptr == '"') ptr++;
+	result->maxpno = atoi (ptr);
+      }
+      if ((ptr = _FP_stristr (line, "name=")) && ctline<4) {
+	ptr += 5;
+	while (isspace (*ptr)) ptr++;
+	if (*ptr == '"' && *(ptr+1) && (p2 = strchr (ptr+2, '"')) != NULL) {
+	  c = *p2; *p2 = '\0';
+	  _FP_free (result->filename);
+	  result->filename = _FP_strdup (ptr+1);
+	  *p2 = c;
+	}
+	else if (*ptr=='\''&&*(ptr+1)&&(p2 = strchr(ptr+2, '\'')) != NULL) {
+	  c = *p2; *p2 = '\0';
+	  _FP_free (result->filename);
+	  result->filename = _FP_strdup (ptr+1);
+	  *p2 = c;
+	}
+	else {
+	  p2 = ptr;
+	  while (isalnum(*p2) || 
+		 *p2 == '.' || *p2=='_' || *p2 == '-' ||
+		 *p2 == '!' || *p2=='@' || *p2 == '$')
+	    p2++;
+	  c = *p2; *p2 = '\0';
+	  if (p2 != ptr && result->filename == NULL)
+	    result->filename = _FP_strdup (ptr);
+	  else if (p2 - ptr > 5 && strchr (ptr, '.') != NULL) {
+	    /*
+	     * This file name looks good, too. Let's use it
+	     */
+	    _FP_free (result->filename);
+	    result->filename = _FP_strdup (ptr);
+	  }
+	  *p2 = c;
+	}
+      }
+      if ((ptr = _FP_stristr (line, "id=")) && ctline<4) {
+	p2 = ptr += 3;
+	if (*p2 == '"') {
+	  p2 = strchr (++ptr, '"');
+	}
+	else {
+	  while (*p2 && isprint(*p2) && !isspace(*p2) && *p2 != ';')
+	    p2++;
+	}
+	if (p2 && *p2 && p2!=ptr) {
+	  c = *p2; *p2 = '\0';
+	  if (result->mimeid)
+	    _FP_free (result->mimeid);
+	  result->mimeid = _FP_strdup (ptr);
+	  *p2 = c;
+	}
+      }
+      
+      /* 
+       * Handling for very short Base64 files.
+       */
+      if (uu_tinyb64) {
+	if (line[0] == '-' && line[1] == '-') {
+	  if (dflag && (encoding==B64ENCODED || result->uudet==B64ENCODED)) {
+	    if (encoding==B64ENCODED && result->uudet==0 && (haddh||hadct)) {
+	      result->uudet = encoding;
+	      encoding = dflag = 0;
+	    }
+	    haddh = 1;
+	    continue;
+	  }
+	  hadct = 0;
+	}
+      }
+    } /* end of reduced MIME handling */
+
+    /*
+     * if we haven't yet found anything encoded, try to find something
+     */
+
+#if 0
+    if (!(result->uudet)) {
+#endif
+      /*
+       * Netscape-Repair code is the same as in uunconc.c
+       */
+
+      if ((vflag = UUValidData (line, 0, &bhflag)) == 0)
+	vflag = UURepairData (datei, line, 0, &bhflag);
+
+      /*
+       * In a few cases, we might mistake uu or xx-encoded data for
+       * Base64, because their alphabets overlap (XX and Base64 differ
+       * in only one character) and the Base64 check is performed
+       * first. If vflag==B64 and we had a begin line, try to see if
+       * the data is consistent with XX or UU.
+       */
+      if (vflag == B64ENCODED && result->begin) {
+	if (UUValidData (line, UU_ENCODED, &bhflag) == UU_ENCODED)
+	  vflag = UU_ENCODED;
+	else if (UUValidData (line, XX_ENCODED, &bhflag) == XX_ENCODED)
+	  vflag = XX_ENCODED;
+      }
+
+      if (vflag) {
+	/*
+	 * For BinHex data, we can use the initial colon ':' as begin
+	 * and the terminating colon as ':'.
+	 * If (vflag && !bhflag), this is the last line,
+	 */
+	if (vflag == BH_ENCODED) {
+	  if (line[0] == ':')
+	    result->begin = 1;
+	  if (bhflag == 0) {
+	    result->uudet = BH_ENCODED;
+	    result->end   = 1;
+	  }
+	}
+	/*
+	 * For BinHex files, the file name is encoded in the first encoded
+	 * data bytes. We try to extract it here
+	 */
+	if (vflag == BH_ENCODED && bhnf == 0 && result->filename == NULL) {
+	  if (bhdsp == bhds2 ||
+	      ((bhdsp-bhds2) <= (int) bhds2[0] &&
+	       (bhdsp-bhds2) <  256)) { 
+	    dcc = UUDecodeLine (line, bhds1, BH_ENCODED);
+	    UUbhdecomp (bhds1, bhdsp, &bhl, &bhrpc,
+			dcc, 256-(bhdsp-bhds2), &bhopc);
+	    bhdsp += bhopc;
+	  }
+	  if ((bhdsp-bhds2) > (int) bhds2[0] && bhds2[0]>0 &&
+	      result->filename==NULL) {
+	    memcpy (bhds1, bhds2+1, (int) bhds2[0]);
+	    bhds1[(int)bhds2[0]]='\0';
+	    result->filename = _FP_strdup (bhds1);
+	    bhnf             = 1;
+	  }
+	  else if (bhdsp-bhds2 >= 256 && bhds2[0]>0) {
+	    memcpy (bhds1, bhds2+1, 255);
+	    bhds1[255]       = '\0';
+	    result->filename = _FP_strdup (bhds1);
+	    bhnf             = 1;
+	  }
+	  else if (bhds2[0] <= 0)
+	    bhnf = 1;
+	}
+	/*
+	 * everything is fine after we've found three encoded lines
+	 */
+        if (dflag>=3 && (vflag==encoding || vflag==result->uudet)) {
+	  result->uudet = vflag;
+          encoding = dflag = 0;
+
+	  /*
+	   * If we're in fast mode, we're told we don't have to look
+	   * for anything below, so we can as well break out of every-
+	   * thing
+	   * We cannot fast-scan if we have a boundary to look after.
+	   */
+
+	  if (uu_fast_scanning && boundary == NULL)
+	    break;
+
+	  /*
+	   * Skip the encoded data. We simply wait for a boundary, for
+	   * a header or for an empty line. But we also try to pick up
+	   * an "end"
+	   */
+
+	  hcount = lcount = 0;
+
+	  while (!feof (datei)) {
+	    /*
+	     * Make Busy Polls
+	     */
+	    if (UUBUSYPOLL(ftell(datei),progress.fsize)) {
+	      UUMessage (uuscan_id, __LINE__, UUMSG_NOTE,
+			 uustring (S_SCAN_CANCEL));
+	      *errcode = UURET_CANCEL;
+	      break;
+	    }
+
+	    oldposition = ftell (datei);
+	    if (_FP_fgets (line, 255, datei) == NULL)
+	      break;
+	    if (ferror (datei))
+	      break;
+
+	    line[255] = '\0';
+
+	    /*
+	     * Stop scanning at an empty line or a MIME-boundary.
+	     */
+	    if (IsLineEmpty (line))
+	      break;
+	    if (boundary && line[0] == '-' && line[1] == '-' &&
+		strncmp (line+2, boundary, blen) == 0) {
+	      fseek (datei, oldposition, SEEK_SET);
+	      break;
+	    }
+	    else if (line[0] == 'e' && (result->uudet == UU_ENCODED ||
+					result->uudet == XX_ENCODED)) {
+	      if (strncmp (line, "end", 3) == 0) {
+		result->end = 1;
+		break;
+	      }
+	    }
+	    else if (line[0] == 'b') {
+	      if (strncmp (line, "begin ", 6) == 0) {
+		fseek (datei, oldposition, SEEK_SET);
+		break;
+	      }
+	    }
+
+	    if (checkheaders) {
+	      if (IsKnownHeader (line)) {
+		(void) ScanHeaderLine (datei, line);
+		if (hcount == 0)
+		  preheaders = oldposition;
+		hcount++;
+		lcount++;
+		if ((hcount >= hlcount.restart) ||
+		    (hcount >= hlcount.afterdata && result->uudet)) {
+		  /*
+		   * Hey, a new header starts here
+		   */
+		  fseek (datei, preheaders, SEEK_SET);
+		  break;
+		}
+	      }
+	      else if (lcount > WAITHEADER) {
+		hcount = 0;
+		lcount = 0;
+	      }
+	      else if (hcount) {
+		lcount++;
+	      }
+	    }
+	    if (result->uudet == BH_ENCODED) {
+	      /* pick up ``EOF'' for BinHex files. Slow :-< */
+	      if (line[0] && strchr (line+1, ':') != NULL) {
+		result->end = 1;
+		break;
+	      }
+	    }
+	  }
+	  if (ferror (datei) || *errcode == UURET_CANCEL)
+	    break;
+
+	  if (line[0] == '-' && line[1] == '-')
+	    haddh = 1;
+
+	  /*
+	   * Okay, got everything we need. If we had headers or a
+	   * boundary, we break out of the outer loop immediately.
+	   */
+
+	  if (IsKnownHeader (line) ||
+	      (boundary && line[0] == '-' && line[1] == '-' &&
+	       strncmp (line+2, boundary, blen) == 0)) {
+	    break;
+	  }
+	  /*
+	   * Otherwise, we wait until finding something more interesting
+	   * in the outer loop
+	   */
+	}
+	else if (encoding == XX_ENCODED && vflag == B64ENCODED) {
+	  dflag++;
+	}
+	else if (result->uudet) {
+	  if (vflag == result->uudet)
+	    dflag++;
+	  else
+	    dflag=0;
+	}
+        else if (encoding != vflag) {
+          encoding = vflag;
+          dflag = 1;
+        }
+        else {
+          encoding = vflag;
+          dflag++;
+        }
+      }
+      else if (!dontcare) {
+	encoding = 0;
+        dflag = 0;
+	haddh = 0;
+      }
+#if 0
+    } /* if (!uudet) */
+#endif
+    /*
+     * End of scanning loop
+     */
+  } /* while (!feof (datei)) */
+
+  if (feof (datei))
+    oldposition = ftell (datei);
+
+  if (dflag && encoding == B64ENCODED && haddh)
+    result->uudet = B64ENCODED;
+  else if (dflag && encoding == BH_ENCODED)
+    result->uudet = BH_ENCODED;
+
+  /* Base64 doesn't have begin or end, so it was probably XX */
+  if (result->uudet == B64ENCODED && result->begin && result->end)
+    result->uudet = XX_ENCODED;
+
+  /* Base64 doesn't have begin or end */
+  if (result->uudet == B64ENCODED)
+    result->begin = result->end = 0;
+
+  /* Base64 and BinHex don't have a file mode */
+  if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED)
+    result->mode  = 6*64+4*8+4;
+
+  /*
+   * In fast mode, this length will yield a false value. We don't care.
+   * This must be checked for in uunconc(), where we usually stop decoding
+   * after reaching startpos+length
+   */
+
+  if (uu_fast_scanning)
+    result->length = progress.fsize-result->startpos;
+  else
+    result->length = ftell(datei)-result->startpos;
+
+  if (ferror (datei)) {
+    *errcode = UURET_IOERR;
+    uu_errno = errno;
+    return -1;
+  }
+  if (*errcode != UURET_OK) {
+    return -1;
+  }
+
+  if (boundary && line[0] == '-' && line[1] == '-' &&
+      strncmp (line+2, boundary, blen) == 0)
+    return 2;
+  else if (boundary && p3 &&
+	   line[0] == 'C' && line[1] == 'o' &&
+	   _FP_strnicmp (line, "Content-Type:", 13) == 0 &&
+	   strcmp (p3, boundary) == 0)
+    return 2;
+  else if (IsKnownHeader (line))
+    return 1;
+
+  return 0;
+}
+
+/*
+ * This is the main scanning function.
+ */
+
+fileread *
+ScanPart (FILE *datei, char *fname, int *errcode)
+{
+  int ecount, hcount, lcount;
+  int bhflag, begflag, vflag, blen = 0, res;
+  long preheaders, prevpos = 0, preenc, before;
+  char *line=uuscan_spline;
+  fileread *result;
+  char *ptr1, *ptr2;
+
+  (void) UUDecodeLine (NULL, NULL, 0);          /* init */
+  if (datei == NULL || feof (datei)) {
+    *errcode = UURET_OK;
+    return NULL;
+  }
+
+  *errcode = UURET_OK;
+
+  if ((result = (fileread *) malloc (sizeof (fileread))) == NULL) {
+    *errcode = UURET_NOMEM;
+    return NULL;
+  }
+  memset (result, 0, sizeof (fileread));
+  result->startpos = ftell (datei);
+  preheaders       = result->startpos;
+  before           = result->startpos;
+
+  /* if this is a new file, reset our scanning state */
+  if (sstate.source == NULL || strcmp (fname, sstate.source) != 0) {
+    sstate.isfolder  = 1;		/* assume yes            */
+    sstate.ismime    = 0;		/* wait for MIME-Version */
+    sstate.mimestate = MS_HEADERS;	/* assume headers follow */
+    /* mimseqno      = 1; */
+
+    while (mssdepth) {
+      mssdepth--;
+      UUkillheaders (&(multistack[mssdepth].envelope));
+      _FP_free (multistack[mssdepth].source);
+    }
+
+    UUkillheaders (&sstate.envelope);
+    memset (&sstate.envelope, 0, sizeof (headers));
+
+    _FP_free (sstate.source);
+    if ((sstate.source = _FP_strdup (fname)) == NULL) {
+      *errcode = UURET_NOMEM;
+      _FP_free (result);
+      return NULL;
+    }
+
+    /* ignore empty lines at the beginning of a file */
+    preheaders = ftell (datei);
+    while (!feof (datei)) {
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      if (_FP_fgets (line, 255, datei) == NULL)
+	break;
+      if (!IsLineEmpty (line)) {
+	fseek (datei, preheaders, SEEK_SET);
+	line[255] = '\0';
+	break;
+      }
+      preheaders = ftell (datei);
+    }
+  }
+
+  if (ferror(datei) || feof(datei)) {
+    _FP_free (result);
+    return NULL;
+  }
+
+  /*
+   * If we are confident that this is a mail folder and are at the
+   * beginning of the file, expecting to read some headers, scan
+   * the envelope.
+   */
+
+  if (sstate.isfolder && sstate.mimestate == MS_HEADERS) {
+    hcount = 0;
+    lcount = 0;
+    UUkillheaders (&sstate.envelope);
+
+    /*
+     * clean up leftovers from invalid messages
+     */
+
+    while (mssdepth) {
+      mssdepth--;
+      UUkillheaders (&(multistack[mssdepth].envelope));
+      _FP_free (multistack[mssdepth].source);
+    }
+
+    if (_FP_fgets (line, 255, datei) == NULL) {
+      _FP_free (result);
+      return NULL;
+    }
+    line[255] = '\0';
+
+    while (!feof (datei) && !IsLineEmpty (line)) {
+      if (IsKnownHeader (line))
+	hcount++;
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      ptr1 = ScanHeaderLine (datei, line);
+      if (ParseHeader (&sstate.envelope, ptr1) == NULL) {
+	*errcode = UURET_NOMEM;
+	_FP_free (result);
+	return NULL;
+      }
+      /*
+       * if we've read too many lines without finding headers, then
+       * this probably isn't a mail folder after all
+       */
+      lcount++;
+      if (lcount > WAITHEADER && hcount < hlcount.afternl)
+	break;
+
+      if (_FP_fgets (line, 255, datei) == NULL)
+	break;
+      line[255] = '\0';
+    }
+    /* skip empty lines */
+    prevpos = ftell (datei);
+    while (!feof (datei)) {
+      if (_FP_fgets (line, 255, datei) == NULL)
+	break;
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      if (!IsLineEmpty (line)) {
+	fseek (datei, prevpos, SEEK_SET);
+	line[255] = '\0';
+	break;
+      }
+      prevpos = ftell (datei);
+    }
+    /*
+     * If we don't have all valid MIME headers yet, but the following
+     * line is a MIME header, accept it anyway.
+     */
+#ifndef MORE_MIME
+    if ((sstate.envelope.mimevers == NULL &&
+	 _FP_strnicmp (line, "Mime-Version:", 13) == 0) ||
+	(sstate.envelope.ctype == NULL &&
+	 _FP_strnicmp (line, "Content-Type:", 13) == 0) ||
+	(sstate.envelope.mimevers == NULL &&
+	 sstate.envelope.ctype    == NULL &&
+	 sstate.envelope.ctenc    == NULL &&
+	 _FP_strnicmp (line, "Content-Transfer-Encoding:", 26) == 0)) {
+      /*
+       * see above
+       */
+      if (_FP_fgets (line, 255, datei) == NULL) {
+	line[0] = '\012';
+	line[1] = '\0';
+      }
+      line[255] = '\0';
+
+      while (!feof (datei) && !IsLineEmpty (line)) {
+	if (IsKnownHeader (line))
+	  hcount++;
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	ptr1 = ScanHeaderLine (datei, line);
+	if (ParseHeader (&sstate.envelope, ptr1) == NULL) {
+	  *errcode = UURET_NOMEM;
+	  _FP_free (result);
+	  return NULL;
+	}
+	/*
+	 * if we've read too many lines without finding headers, then
+	 * this probably isn't a mail folder after all
+	 */
+	lcount++;
+	if (lcount > WAITHEADER && hcount < hlcount.afternl)
+	  break;
+	
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	line[255] = '\0';
+      }
+      /* skip empty lines */
+      prevpos = ftell (datei);
+      while (!feof (datei)) {
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	if (!IsLineEmpty (line)) {
+	  fseek (datei, prevpos, SEEK_SET);
+	  line[255] = '\0';
+	  break;
+	}
+	prevpos = ftell (datei);
+      }
+    }
+#endif
+    /*
+     * A partial multipart message probably has only a Content-Type
+     * header but nothing else. In this case, at least simulate a
+     * MIME message
+     * if mimevers is not set but there are other well-known MIME
+     * headers, don't be too picky about it.
+     */
+    if (sstate.envelope.ctype && sstate.envelope.mimevers==NULL  &&
+	_FP_stristr (sstate.envelope.ctype, "multipart") != NULL &&
+	sstate.envelope.boundary != NULL) {
+      sstate.envelope.mimevers = _FP_strdup ("1.0");
+      hcount = hlcount.afternl;
+    }
+    else if (sstate.envelope.mimevers==NULL && sstate.envelope.ctype &&
+	     sstate.envelope.fname && sstate.envelope.ctenc) {
+      sstate.envelope.mimevers = _FP_strdup ("1.0");
+      hcount = hlcount.afternl;
+    }
+
+    if (hcount < hlcount.afternl) {
+      /* not a folder after all */
+      fseek (datei, preheaders, SEEK_SET);
+      sstate.isfolder = 0;
+      sstate.ismime   = 0;
+    }
+    else if (sstate.envelope.mimevers != NULL) {
+      /* this is a MIME file. check the Content-Type */
+      sstate.ismime = 1;
+      if (_FP_stristr (sstate.envelope.ctype, "multipart") != NULL) {
+	if (sstate.envelope.boundary == NULL) {
+	  UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		     uustring (S_MIME_NO_BOUNDARY));
+	  sstate.mimestate = MS_BODY;
+	  _FP_free (sstate.envelope.ctype);
+	  sstate.envelope.ctype = _FP_strdup ("text/plain");
+	}
+	else {
+	  sstate.mimestate = MS_PREAMBLE;
+	}
+      }
+      else {
+	sstate.mimestate = MS_BODY;	/* just a `simple' message */
+      }
+    }
+  }
+
+  if (feof (datei) || ferror (datei)) { /* oops */
+    _FP_free (result);
+    return NULL;
+  }
+
+  /*
+   * Handle MIME stuff
+   */
+
+  /*
+   * Read Preamble. This must be ended by a sstate.envelope.boundary line.
+   * If uu_usepreamble is set, we produce a result from this one
+   */
+
+  if (sstate.ismime && sstate.mimestate == MS_PREAMBLE) {
+    result->startpos = ftell (datei);	/* remember start of preamble */
+    prevpos          = ftell (datei);
+    preheaders       = ftell (datei);
+
+    blen   = strlen (sstate.envelope.boundary);
+    lcount = 0;
+    
+    while (!feof (datei)) {
+      if (_FP_fgets (line, 255, datei) == NULL) {
+	line[0] = '\0';
+	break;
+      }
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      if (line[0] == '-' && line[1] == '-' &&
+	  strncmp (line+2, sstate.envelope.boundary, blen) == 0)
+	break;
+      if (!IsLineEmpty (line))
+	lcount++;
+
+      prevpos = ftell (datei);
+    }
+    if (feof (datei) || ferror (datei)) {
+      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		 uustring (S_MIME_B_NOT_FOUND));
+      /*
+       * restart and try again; don't restart if uu_fast_scanning
+       */
+      sstate.isfolder  = 0;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_BODY;
+
+      if (!uu_fast_scanning) {
+	*errcode = UURET_CONT;
+	fseek (datei, preheaders, SEEK_SET);
+      }
+      _FP_free (result);
+      return NULL;
+    }
+    if (line[0] == '-' && line[1] == '-' &&
+	strncmp (line+2, sstate.envelope.boundary, blen) == 0) {
+      ptr1 = line + 2 + blen;
+      if (*ptr1 == '-' && *(ptr1+1) == '-') {
+	/* Empty Multipart Message. Duh. */
+	sstate.mimestate = MS_EPILOGUE;
+      }
+      else {
+	sstate.mimestate = MS_SUBPART;
+      }
+    }
+    else { /* shouldn't happen */
+      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		 uustring (S_MIME_B_NOT_FOUND));
+      /*
+       * restart and try again; don't restart if uu_fast_scanning
+       */
+      sstate.isfolder  = 0;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_BODY;
+
+      if (!uu_fast_scanning) {
+	*errcode = UURET_CONT;
+	fseek (datei, preheaders, SEEK_SET);
+      }
+      _FP_free (result);
+      return NULL;
+    }
+    /* produce result if uu_usepreamble is set */
+    if (uu_usepreamble && lcount) {
+      sprintf (line, "%04d.txt", ++mimseqno);
+      result->subject  = _FP_strdup (sstate.envelope.subject);
+      result->filename = _FP_strdup (line);
+      result->origin   = _FP_strdup (sstate.envelope.from);
+      result->mimeid   = _FP_strdup (sstate.envelope.mimeid);
+      result->mimetype = _FP_strdup ("text/plain");
+      result->mode     = 0644;
+      result->uudet    = PT_ENCODED;	/* plain text */
+      result->sfname   = _FP_strdup (fname);
+      result->flags    = FL_SINGLE | FL_PROPER;
+      /* result->startpos set from above */
+      result->length   = prevpos - result->startpos;
+      result->partno   = 1;
+
+      /* MIME message, let's continue */
+      *errcode = UURET_CONT;
+
+      if ((sstate.envelope.subject != NULL && result->subject == NULL) ||
+	  result->filename == NULL || result->sfname == NULL) {
+	*errcode = UURET_NOMEM;
+      }
+
+      return result;
+    }
+    /* MIME message, let's continue */
+    if (*errcode == UURET_OK)
+      *errcode = UURET_CONT;
+
+    /* otherwise, just return NULL */
+    _FP_free (result);
+    return NULL;
+  }
+
+  /*
+   * Read Epilogue, the plain text after the last boundary.
+   * This can either end with new headers from the next message of a
+   * mail folder or with a `parent' boundary if we are inside an
+   * encapsulated Multipart message. Oh yes, and of course the file
+   * may also simply end :-)
+   * Another possibility is that we might find plain encoded data
+   * without encapsulating message. We're not _too_ flexible here,
+   * we won't detect Base64, and require a proper `begin' line for
+   * uuencoding and xxencoding
+   * If uu_usepreamble is set, we produce a result from this one
+   */
+
+  if (sstate.ismime && sstate.mimestate == MS_EPILOGUE) {
+    result->startpos = ftell (datei);	/* remember start of epilogue */
+    prevpos          = ftell (datei);
+    preheaders       = ftell (datei);
+    preenc           = ftell (datei);
+    hcount = lcount  = 0;
+    ecount = bhflag  = 0;
+    begflag = vflag  = 0;
+    res = 0;
+
+    /*
+     * If we are in the outermost message and uu_fast_scanning, we
+     * know (or assume) that no more messages will follow, so there's
+     * no need to scan the rest.
+     */
+    if (uu_fast_scanning && mssdepth == 0) {
+      /*
+       * check if the epilogue is empty
+       */
+      while (!feof (datei) && !ferror (datei) && lcount<10 && res==0) {
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	if (!IsLineEmpty (line))
+	  res++;
+	lcount++;
+      }
+      if (uu_usepreamble && res) {
+	sprintf (line, "%04d.txt", ++mimseqno);
+	result->subject  = _FP_strdup (sstate.envelope.subject);
+	result->filename = _FP_strdup (line);
+	result->origin   = _FP_strdup (sstate.envelope.from);
+	result->mimeid   = _FP_strdup (sstate.envelope.mimeid);
+	result->mimetype = _FP_strdup ("text/plain");
+	result->mode     = 0644;
+	result->uudet    = PT_ENCODED;	/* plain text */
+	result->sfname   = _FP_strdup (fname);
+	result->flags    = FL_SINGLE | FL_PROPER | FL_TOEND;
+	result->partno   = 1;
+	/* result->startpos set from above */
+	result->length   = progress.fsize - result->startpos;
+
+	if ((sstate.envelope.subject != NULL && result->subject == NULL) ||
+	    result->filename == NULL || result->sfname == NULL) {
+	  *errcode = UURET_NOMEM;
+	}
+
+	return result;
+      }
+      _FP_free (result);
+      return NULL;
+    }
+
+    if (mssdepth > 0)
+      blen = strlen (multistack[mssdepth-1].envelope.boundary);
+
+    while (!feof (datei)) {
+      if (_FP_fgets (line, 255, datei) == NULL) {
+	line[0] = '\0';
+	break;
+      }
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      line[255] = '\0';
+      /* check for parent boundary */
+      if (mssdepth > 0 && line[0] == '-' && line[1] == '-' &&
+	  strncmp (line+2,
+		   multistack[mssdepth-1].envelope.boundary, blen) == 0)
+	break;
+
+      /* check for next headers only at outermost level */
+      if (mssdepth == 0 && IsKnownHeader (line)) {
+	(void) ScanHeaderLine (datei, line);
+	if (hcount == 0) {
+	  preheaders = prevpos;
+	  lcount     = 0;
+	}
+	hcount++; 
+	lcount++;
+
+	if (hcount >= hlcount.restart) {
+	  /* okay, new headers */
+	  break;
+	}
+      }
+      else if (lcount > WAITHEADER) {
+	hcount = 0;
+	lcount = 0;
+      }
+      else if (hcount) {
+	lcount++;
+      }
+      else {
+	hcount = lcount = 0;
+      }
+
+#ifndef MORE_MIME
+      /* check for begin and encoded data only at outermost level */
+      if (mssdepth == 0) {
+	if (strncmp      (line, "begin ",       6) == 0 ||
+	    _FP_strnicmp (line, "
begin ", 11) == 0) {
+	  preenc  = prevpos;
+	  begflag = 1;
+	}
+	else if (strncmp (line, "end", 3) == 0 && begflag) {
+	  ecount = ELC_COUNT;
+	  break;
+	}
+	else if ((vflag = UUValidData (line, 0, &bhflag)) != 0) {
+	  if (vflag == BH_ENCODED && bhflag == 0) {
+	    /* very short BinHex file follows */
+	    preenc = prevpos;
+	    break;
+	  }
+	  /* remember that XX can easily be mistaken as Base64 */
+	  if ((vflag == UU_ENCODED || vflag == XX_ENCODED ||
+	       vflag == B64ENCODED) && begflag) {
+	    if (++ecount >= ELC_COUNT)
+	      break;
+	  }
+	  else {
+	    begflag = 0;
+	    ecount  = 0;
+	  }
+	}
+	else {
+	  begflag = 0;
+	  ecount  = 0;
+	}
+      }
+#endif
+
+      if (!IsLineEmpty (line))
+	res++;
+
+      prevpos = ftell (datei);
+    }
+    if (mssdepth > 0 &&	line[0] == '-' && line[1] == '-' &&
+	strncmp (line+2,
+		 multistack[mssdepth-1].envelope.boundary, blen) == 0) {
+      /* restore previous state */
+      mssdepth--;
+      UUkillheaders (&sstate.envelope);
+      _FP_free  (sstate.source);
+      memcpy (&sstate, &(multistack[mssdepth]), sizeof (scanstate));
+
+      ptr1 = line + 2 + strlen (sstate.envelope.boundary);
+
+      if (*ptr1 == '-' && *(ptr1+1) == '-') {
+	sstate.mimestate = MS_EPILOGUE;
+      }
+      else {
+	sstate.mimestate = MS_SUBPART;
+      }
+      result->length = prevpos - result->startpos;
+      *errcode = UURET_CONT;
+    }
+    else if (mssdepth > 0) {
+      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		 uustring (S_MIME_B_NOT_FOUND));
+      /*
+       * restart and try again; don't restart if uu_fast_scanning
+       */
+      sstate.isfolder  = 0;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_BODY;
+
+      while (mssdepth) {
+	mssdepth--;
+	UUkillheaders (&(multistack[mssdepth].envelope));
+	_FP_free (multistack[mssdepth].source);
+      }
+
+      if (!uu_fast_scanning) {
+	*errcode = UURET_CONT;
+	fseek (datei, preheaders, SEEK_SET);
+      }
+      _FP_free (result);
+      return NULL;
+    }
+    else if (IsKnownHeader (line)) {
+      /* new message follows */
+      sstate.isfolder  = 1;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_HEADERS;
+      result->length   = preheaders - result->startpos;
+      fseek (datei, preheaders, SEEK_SET);
+    }
+    else if (ecount >= ELC_COUNT) {
+      /* new plain encoding */
+      sstate.isfolder  = 0;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_BODY;
+      result->length   = preenc - result->startpos;
+      fseek (datei, preenc, SEEK_SET);
+    }
+
+    /* produce result if uu_usepreamble is set */
+    if (uu_usepreamble && res) {
+      sprintf (line, "%04d.txt", ++mimseqno);
+      result->subject  = _FP_strdup (sstate.envelope.subject);
+      result->filename = _FP_strdup (line);
+      result->origin   = _FP_strdup (sstate.envelope.from);
+      result->mimeid   = _FP_strdup (sstate.envelope.mimeid);
+      result->mimetype = _FP_strdup ("text/plain");
+      result->mode     = 0644;
+      result->uudet    = PT_ENCODED;	/* plain text */
+      result->sfname   = _FP_strdup (fname);
+      result->flags    = FL_SINGLE | FL_PROPER;
+      result->partno   = 1;
+      /* result->startpos set from above */
+      /* result->length set from above */
+
+      if ((sstate.envelope.subject != NULL && result->subject == NULL) ||
+	  result->filename == NULL || result->sfname == NULL) {
+	*errcode = UURET_NOMEM;
+      }
+
+      return result;
+    }
+    /* otherwise, just return NULL */
+    _FP_free (result);
+    return NULL;
+  }
+
+  /*
+   * Scan a new part from a Multipart message. Check for a new local
+   * envelope (which defaults to `Content-Type: text/plain') and
+   * evaluate its Content-Type and Content-Transfer-Encoding. If this
+   * is another Multipart/something, push the current state onto our
+   * stack and dive into the new environment, starting with another
+   * preamble.
+   */
+			   
+  if (sstate.ismime && sstate.mimestate == MS_SUBPART) {
+    memset (&localenv, 0, sizeof (headers));
+    result->startpos = ftell (datei);
+    prevpos = ftell (datei);
+    hcount  = 0;
+    lcount  = 0;
+
+    /*
+     * Duplicate some data from outer envelope
+     */
+
+    localenv.mimevers = _FP_strdup (sstate.envelope.mimevers);
+    localenv.from     = _FP_strdup (sstate.envelope.from);
+    localenv.subject  = _FP_strdup (sstate.envelope.subject);
+    localenv.rcpt     = _FP_strdup (sstate.envelope.rcpt);
+    localenv.date     = _FP_strdup (sstate.envelope.date);
+
+    if ((sstate.envelope.mimevers != NULL && localenv.mimevers == NULL) ||
+	(sstate.envelope.from     != NULL && localenv.from     == NULL) ||
+	(sstate.envelope.subject  != NULL && localenv.subject  == NULL) ||
+	(sstate.envelope.rcpt     != NULL && localenv.rcpt     == NULL) ||
+	(sstate.envelope.date     != NULL && localenv.date     == NULL)) {
+
+      while (mssdepth) {
+	mssdepth--;
+	UUkillheaders (&(multistack[mssdepth].envelope));
+	_FP_free (multistack[mssdepth].source);
+      }
+      sstate.isfolder = 0;
+      sstate.ismime   = 0;
+      
+      UUkillheaders (&localenv);
+      *errcode = UURET_NOMEM;
+      _FP_free (result);
+      return NULL;
+    }
+    
+    /* Scan subheader. But what if there is no subheader? */
+    hcount = 0;
+    lcount = 0;
+    preheaders = prevpos;
+    
+    if (_FP_fgets (line, 255, datei) == NULL) {
+      sstate.isfolder = 0;
+      sstate.ismime   = 0;
+      while (mssdepth) {
+	mssdepth--;
+	UUkillheaders (&(multistack[mssdepth].envelope));
+	_FP_free (multistack[mssdepth].source);
+      }
+      UUkillheaders (&localenv);
+      _FP_free (result);
+      return NULL;
+    }
+    line[255] = '\0';
+
+    while (!feof (datei) && !IsLineEmpty (line)) {
+      if (IsKnownHeader (line))
+	hcount++;
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      if (lcount > WAITHEADER && hcount == 0) {
+	fseek (datei, preheaders, SEEK_SET);
+	prevpos = preheaders;
+	break;
+      }
+      ptr1 = ScanHeaderLine (datei, line);
+      if (ParseHeader (&localenv, ptr1) == NULL)
+	*errcode = UURET_NOMEM;
+
+      if (line[0] == '-' && line[1] == '-')
+	break;
+
+      prevpos = ftell (datei);
+
+      if (_FP_fgets (line, 255, datei) == NULL)
+	break;
+      line[255] = '\0';
+      lcount++;
+    }
+    if (line[0] == '-' && line[1] == '-') {
+      /*
+       * this shouldn't happen, there must always be an empty line,
+       * but let's accept it anyway. Just skip back to before the
+       * boundary, so that it gets handled below
+       */
+      fseek (datei, prevpos, SEEK_SET);
+    }
+
+    if (_FP_stristr (localenv.ctype, "multipart") != NULL) {
+      /* oh no, not again */
+      if (mssdepth >= MSMAXDEPTH) {
+	/* Argh, what an isane message. Treat as plain text */
+	UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		   uustring (S_MIME_MULTI_DEPTH));
+      }
+      else if (localenv.boundary == NULL) {
+	UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		   uustring (S_MIME_NO_BOUNDARY));
+      }
+      else {
+	memcpy (&multistack[mssdepth], &sstate, sizeof (scanstate));
+	memcpy (&sstate.envelope,    &localenv, sizeof (headers));
+	memset (&localenv, 0, sizeof (headers));
+	sstate.mimestate = MS_PREAMBLE;
+	if ((sstate.source = _FP_strdup (sstate.source)) == NULL)
+	  *errcode = UURET_NOMEM;
+
+	if (*errcode == UURET_OK)
+	  *errcode = UURET_CONT;
+
+	mssdepth++;
+	/* need a restart */
+	_FP_free (result);
+	return NULL;
+      }
+    }
+    /*
+     * So this subpart is either plain text or something else. Check
+     * the Content-Type and Content-Transfer-Encoding. If the latter
+     * is a defined value, we know what to do and just copy everything
+     * up to the boundary.
+     * If Content-Transfer-Encoding is unknown or missing, look at the
+     * Content-Type. If it's "text/plain" or undefined, we subject the
+     * message to our encoding detection. Otherwise, treat as plain
+     * text.
+     * This is done because users might `attach' a uuencoded file, which
+     * would then be correctly typed as `text/plain'.
+     */
+    if (_FP_stristr (localenv.ctenc, "base64") != NULL)
+      result->uudet = B64ENCODED;
+    else if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
+      result->uudet = QP_ENCODED;
+    else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
+	     _FP_stristr (localenv.ctenc, "8bit") != NULL)
+      result->uudet = PT_ENCODED;
+    else if (_FP_stristr (localenv.ctype, "message") != NULL)
+      result->uudet = PT_ENCODED;
+
+    if (result->uudet) {
+      /*
+       * Oh-kay, go ahead. Just read and wait for the boundary
+       */
+      result->startpos = ftell (datei);
+      prevpos          = ftell (datei);
+      blen = strlen (sstate.envelope.boundary);
+      lcount = 0;
+      
+      while (!feof (datei)) {
+	if (_FP_fgets (line, 255, datei) == NULL) {
+	  line[0] = '\0';
+	  break;
+	}
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	line[255] = '\0';
+	if (line[0] == '-' && line[1] == '-' &&
+	    strncmp (line+2, sstate.envelope.boundary, blen) == 0)
+	  break;
+	/*
+	 * I've had a report of someone who tried to decode a huge file
+	 * that had an early truncated multipart message and later another
+	 * multipart message with the *same* boundary. Consequently, all
+	 * some hundred messages inbetween were ignored ...
+	 * This check here doesn't cover folded header lines, but we don't
+	 * want to slow down scanning too much. We just check for
+	 * Content-Type: multipart/... boundary="same-boundary"
+	 */
+	if (line[0] == 'C' && line[1] == 'o' &&
+	    _FP_strnicmp (line, "Content-Type:", 13) == 0) {
+	  ptr1 = ScanHeaderLine (datei, line);
+	  ptr2 = (ptr1)?_FP_stristr(ptr1,"boundary"):NULL;
+	  ptr1 = (ptr2)?ParseValue(ptr2):NULL;
+	  if (ptr1 && strcmp (ptr1, sstate.envelope.boundary) == 0)
+	    break;
+	  for (res=0; ptr1 && resstartpos, SEEK_SET);
+
+	UUkillfread (result);
+	if ((result = (fileread *) malloc (sizeof (fileread))) == NULL) {
+	  *errcode = UURET_NOMEM;
+	  sstate.isfolder = 0;
+	  sstate.ismime   = 0;
+	  UUkillheaders (&localenv);
+	  return NULL;
+	}
+	memset (result, 0, sizeof (fileread));
+
+	if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result))==-1) {
+	  /* oops, something went wrong */
+	  sstate.isfolder = 0;
+	  sstate.ismime   = 0;
+	  UUkillfread   (result);
+	  UUkillheaders (&localenv);
+	  return NULL;
+	}
+	if (res == 1) {
+	  /*
+	   * new headers found
+	   */
+	  sstate.isfolder  = 1;
+	  sstate.ismime    = 0;
+	  sstate.mimestate = MS_HEADERS;
+	}
+	else {
+	  sstate.isfolder  = 0;
+	  sstate.ismime    = 0;
+	}
+      }
+      /* produce result if uu_handletext is set */
+      if ((result->uudet == B64ENCODED || uu_handletext) &&
+	  (result->uudet != QP_ENCODED ||
+	   result->uudet != PT_ENCODED || lcount>0)) {
+	if (localenv.fname) {
+	  _FP_free (result->filename);
+	  if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
+	    *errcode = UURET_NOMEM;
+	}
+	else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
+		 result->filename == NULL) {
+	  sprintf (line, "%04d.txt", ++mimseqno);
+	  if ((result->filename = _FP_strdup (line)) == NULL)
+	    *errcode = UURET_NOMEM;
+	}
+	result->subject  = _FP_strdup (localenv.subject);
+	result->origin   = _FP_strdup (localenv.from);
+	result->mimeid   = _FP_strdup (localenv.mimeid);
+	result->mimetype = _FP_strdup (localenv.ctype);
+	result->mode     = 0644;
+	result->sfname   = _FP_strdup (fname);
+	result->flags    = FL_SINGLE | FL_PROPER;
+	result->partno   = 1;
+	/* result->uudet determined above */
+	/* result->startpos set from above */
+	result->length   = prevpos - result->startpos;
+
+	if ((localenv.subject != NULL && result->subject == NULL) ||
+	    result->filename == NULL  || result->sfname == NULL) {
+	  *errcode = UURET_NOMEM;
+	}
+      }
+      else {
+	/* don't produce a result */
+	_FP_free (result);
+	result = NULL;
+      }
+      if (*errcode == UURET_OK)
+	*errcode = UURET_CONT;
+      /*
+       * destroy local envelope
+       */
+      UUkillheaders (&localenv);
+      return result;
+    }
+    /*
+     * we're in a subpart, but the local headers don't give us any
+     * clue about what's to find here. So look for encoded data by
+     * ourselves.
+     */
+    if ((res = ScanData (datei, fname, errcode,
+			 sstate.envelope.boundary, 1, 0, result)) == -1) {
+      /* oops, something went wrong */
+      sstate.isfolder = 0;
+      sstate.ismime   = 0;
+      UUkillfread   (result);
+      UUkillheaders (&localenv);
+      return NULL;
+    }
+    /*
+     * we should really be at a boundary here, but check again
+     */
+    blen    = strlen (sstate.envelope.boundary);
+    prevpos = ftell  (datei);
+
+    while (!feof (datei)) {
+      if (_FP_fgets (line, 255, datei) == NULL) {
+	line[0] = '\0';
+	break;
+      }
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      line[255] = '\0';
+      if (line[0] == '-' && line[1] == '-' &&
+	  strncmp (line+2, sstate.envelope.boundary, blen) == 0)
+	break;
+      if (line[0] == 'C' && line[1] == 'o' &&
+	  _FP_strnicmp (line, "Content-Type:", 13) == 0) {
+	ptr1 = ScanHeaderLine (datei, line);
+	ptr2 = (ptr1)?_FP_stristr(ptr1,"boundary"):NULL;
+	ptr1 = (ptr2)?ParseValue(ptr2):NULL;
+	if (ptr1 && strcmp (ptr1, sstate.envelope.boundary) == 0)
+	  break;
+      }
+      prevpos = ftell (datei);
+    }
+    /*
+     * check if this was the last subpart
+     */
+    if (line[0] == '-' && line[1] == '-' &&
+	strncmp (line+2, sstate.envelope.boundary, blen) == 0) {
+      ptr1 = line + 2 + blen;
+      if (*ptr1 == '-' && *(ptr1+1) == '-')
+	sstate.mimestate = MS_EPILOGUE;
+      else
+	sstate.mimestate = MS_SUBPART;
+    }
+    else {
+      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		 uustring (S_MIME_B_NOT_FOUND));
+      
+      while (mssdepth) {
+	mssdepth--;
+	UUkillheaders (&(multistack[mssdepth].envelope));
+	_FP_free (multistack[mssdepth].source);
+      }
+
+      if (uu_fast_scanning) {
+	UUkillheaders (&localenv);
+	sstate.isfolder  = 0;
+	sstate.ismime    = 0;
+	sstate.mimestate = MS_BODY;
+	_FP_free (result);
+	return NULL;
+      }
+
+      /*
+       * Retry, listening to headers this time
+       */
+      fseek (datei, result->startpos, SEEK_SET);
+      
+      UUkillfread (result);
+      if ((result = (fileread *) malloc (sizeof (fileread))) == NULL) {
+	*errcode = UURET_NOMEM;
+	sstate.isfolder = 0;
+	sstate.ismime   = 0;
+	UUkillheaders (&localenv);
+	return NULL;
+      }
+      memset (result, 0, sizeof (fileread));
+
+      if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result))==-1) {
+	/* oops, something went wrong */
+	sstate.isfolder = 0;
+	sstate.ismime   = 0;
+	UUkillfread   (result);
+	UUkillheaders (&localenv);
+	return NULL;
+      }
+      if (res == 1) {
+	/*
+	 * new headers found
+	 */
+	sstate.isfolder  = 1;
+	sstate.ismime    = 0;
+	sstate.mimestate = MS_HEADERS;
+      }
+      else {
+	sstate.isfolder  = 0;
+	sstate.ismime    = 0;
+      }
+    }
+    /*
+     * produce result
+     */
+    if (result->uudet == 0 && uu_handletext) {
+      result->uudet = PT_ENCODED; /* plain text */
+    }
+    else if (result->uudet == 0) {
+      UUkillheaders (&localenv);
+      _FP_free (result);
+      return NULL;
+    }
+
+    if (localenv.fname) {
+      _FP_free (result->filename);
+      if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) &&
+	     result->filename==NULL) {
+      sprintf (line, "%04d.txt", ++mimseqno);
+      if ((result->filename = _FP_strdup (line)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else {
+      /* assign a filename lateron */
+    }
+    if (result->mimetype) _FP_free (result->mimetype);
+    if (result->uudet) {
+      if (_FP_stristr (localenv.ctype, "text") != NULL &&
+	  result->uudet != QP_ENCODED && result->uudet != PT_ENCODED)
+	result->mimetype = NULL; /* better don't set it */
+      else
+	result->mimetype = _FP_strdup (localenv.ctype);
+    }
+    if (result->origin) _FP_free  (result->origin);
+    result->origin  = _FP_strdup  (localenv.from);
+
+    if (result->subject) _FP_free (result->subject);
+    result->subject = _FP_strdup  (localenv.subject);
+
+    if (result->sfname == NULL)
+      if ((result->sfname = _FP_strdup (fname)) == NULL)
+	*errcode = UURET_NOMEM;
+
+    result->length = prevpos - result->startpos;
+    result->flags  = FL_SINGLE | FL_PROPER;
+    result->partno = 1;
+
+    if (result->mode == 0)
+      result->mode = 0644;
+
+    /*
+     * the other fields should already be set appropriately
+     */
+
+    if (*errcode == UURET_OK)
+      *errcode = UURET_CONT;
+
+    /*
+     * kill local envelope
+     */
+    UUkillheaders (&localenv);
+    
+    return result;
+  }
+
+  /*
+   * All right, so we're not in a Multipart message. Phew, took quite
+   * long to figure this out. But this might still be a MIME message
+   * body. And if it's a message/partial, we need more special handling
+   */
+
+  if (sstate.isfolder && sstate.ismime && sstate.mimestate == MS_BODY &&
+      _FP_stristr (sstate.envelope.ctype, "message") != NULL &&
+      _FP_stristr (sstate.envelope.ctype, "partial") != NULL) {
+
+    result->startpos = ftell (datei);
+
+    if (sstate.envelope.partno == 1) {
+      /* read local envelope */
+      UUkillheaders (&localenv);
+      memset (&localenv, 0, sizeof (headers));
+
+      /* skip over blank lines first */
+      prevpos = ftell (datei);
+      while (!feof (datei)) {
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	line[255] = '\0';
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	if (!IsLineEmpty (line))
+	  break;
+	prevpos = ftell (datei);
+      }
+      /* Next, read header. But what if there is no subheader? */
+      hcount = 0;
+      lcount = 0;
+      preheaders = prevpos;
+
+      while (!feof (datei) && !IsLineEmpty (line)) {
+	if (IsKnownHeader (line))
+	  hcount++;
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	if (lcount > WAITHEADER && hcount == 0) {
+	  fseek (datei, preheaders, SEEK_SET);
+	  break;
+	}
+	ptr1 = ScanHeaderLine (datei, line);
+	if (ParseHeader (&localenv, ptr1) == NULL)
+	  *errcode = UURET_NOMEM;
+
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	line[255] = '\0';
+	lcount++;
+      }
+      prevpos = ftell (datei);
+      /*
+       * Examine local header. We're mostly interested in the Content-Type
+       * and the Content-Transfer-Encoding.
+       */
+      if (_FP_stristr (localenv.ctype, "multipart") != NULL) {
+	UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
+		   uustring (S_MIME_PART_MULTI));
+      }
+      if (localenv.subject)
+	result->subject  = _FP_strdup (localenv.subject);
+      else
+	result->subject  = _FP_strdup (sstate.envelope.subject);
+
+      if (localenv.from)
+	result->origin   = _FP_strdup (localenv.from);
+      else
+	result->origin   = _FP_strdup (sstate.envelope.from);
+
+      if (localenv.ctype)
+	result->mimetype = _FP_strdup (localenv.ctype);
+      else
+	result->mimetype = _FP_strdup ("text/plain");
+
+      if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
+	result->uudet = QP_ENCODED;
+      else if (_FP_stristr (localenv.ctenc, "base64") != NULL)
+	result->uudet = B64ENCODED;
+      else if (_FP_stristr (localenv.ctype, "multipart") != NULL ||
+	       _FP_stristr (localenv.ctype, "message")   != NULL)
+	result->uudet = PT_ENCODED;
+    }
+    else {
+      memset (&localenv, 0, sizeof (headers));
+    }
+
+    /*
+     * If this is Quoted-Printable or Plain Text, just try looking
+     * for the next message header. If uu_fast_scanning, and the
+     * encoding is known, there's no need to look below. Otherwise,
+     * we check the type of encoding first.
+     * The encoding type is determined on the first part; in all
+     * others, we also don't read on.
+     * If we have a partial multipart message, scan for headers, but
+     * do not react on standard MIME headers, as they are probably
+     * from the subparts. However, we're stuck if there's an embedded
+     * message/rfc822 :-(
+     * If it is a "trivial" (non-embedded) message/rfc822, skip over
+     * the message header and then start looking for the next header.
+     */
+    if (uu_fast_scanning && (result->uudet!=0||sstate.envelope.partno!=1)) {
+      /* do nothing */
+      res = 0;
+    }
+    else if (result->uudet != 0) {
+      hcount = lcount = 0;
+
+      prevpos = ftell (datei);
+
+      if (_FP_stristr (localenv.ctype, "message") != NULL &&
+	  _FP_stristr (localenv.ctype, "rfc822")  != NULL) {
+	/*
+	 * skip over empty lines and local header
+	 */
+	preheaders = ftell (datei);
+	while (!feof (datei)) {
+	  if (_FP_fgets (line, 255, datei) == NULL)
+	    break;
+	  if (!IsLineEmpty (line)) {
+	    fseek (datei, preheaders, SEEK_SET);
+	    line[255] = '\0';
+	    break;
+	  }
+	}
+	if (_FP_fgets (line, 255, datei) == NULL) {
+	  _FP_free (result);
+	  return NULL;
+	}
+	line[255] = '\0';
+
+	while (!feof (datei) && !IsLineEmpty (line)) { 
+	  if (IsKnownHeader (line))
+	    hcount++;
+	  lcount++;
+	  if (lcount > WAITHEADER && hcount < hlcount.afternl)
+	    break;
+
+	  if (_FP_fgets (line, 255, datei) == NULL)
+	    break;
+	  line[255] = '\0';
+	}
+	if (hcount < hlcount.afternl)
+	  fseek (datei, preheaders, SEEK_SET);
+	hcount = lcount = 0;
+      }
+
+      /*
+       * look for next header
+       */
+
+      while (!feof (datei)) {
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	if (ferror (datei))
+	  break;
+	line[255] = '\0';
+
+	if ((vflag = IsKnownHeader (line))) {
+	  (void) ScanHeaderLine (datei, line);
+
+	  if (result->uudet != PT_ENCODED || vflag == 1) {
+	    if (hcount == 0)
+	      preheaders = prevpos;
+	    hcount++;
+	    lcount++;
+	    if (hcount >= hlcount.restart) {
+	      /*
+	       * Hey, a new header starts here
+	       */
+	      fseek (datei, preheaders, SEEK_SET);
+	      prevpos = preheaders;
+	      break;
+	    }
+	  }
+	}
+	else if (lcount > WAITHEADER) {
+	  hcount = 0;
+	  lcount = 0;
+	}
+	else if (hcount) {
+	  lcount++;
+	}
+	prevpos = ftell (datei);
+      }
+      res = 1;
+    }
+    else {
+      /*
+       * Otherwise, let's see what we can find ourself. No
+       * boundary (NULL) but MIME, and respect new headers.
+       */
+      if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result)) == -1) {
+	/* oops, something went wrong */
+	sstate.isfolder = 0;
+	sstate.ismime   = 0;
+	UUkillfread   (result);
+	UUkillheaders (&localenv);
+	return NULL;
+      }
+      if (result->uudet == 0 && uu_handletext)
+	result->uudet = PT_ENCODED;
+
+      prevpos = ftell (datei);
+    }
+    /*
+     * produce result
+     */
+    if (localenv.fname) {
+      _FP_free (result->filename);
+      if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else if (sstate.envelope.fname) {
+      _FP_free (result->filename);
+      if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) &&
+	     result->filename == NULL) {
+      sprintf (line, "%04d.txt", ++mimseqno);
+      if ((result->filename = _FP_strdup (line)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else {
+      /* assign a filename lateron */
+    }
+    if (result->subject == NULL) {
+      if (sstate.envelope.subject)
+	result->subject = _FP_strdup (sstate.envelope.subject);
+    }
+    result->partno = sstate.envelope.partno;
+    result->maxpno = sstate.envelope.numparts;
+    result->flags  = FL_PARTIAL | 
+      ((res==1 || uu_fast_scanning) ? FL_PROPER : 0) |
+	((uu_fast_scanning) ? FL_TOEND : 0);
+    result->mimeid = _FP_strdup (sstate.envelope.mimeid);
+
+    if (uu_fast_scanning)
+      result->length = progress.fsize - result->startpos;
+    else
+      result->length = prevpos - result->startpos;
+
+    if (result->sfname == NULL)
+      result->sfname = _FP_strdup (fname);
+
+    if (result->mode == 0)
+      result->mode = 0644;
+
+    /*
+     * the other fields should already be set appropriately
+     */
+
+    if (res == 1) {
+      /*
+       * new headers found
+       */
+      sstate.isfolder  = 1;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_HEADERS;
+      
+      UUkillheaders (&sstate.envelope);
+      memset (&sstate.envelope, 0, sizeof (headers));
+    }
+    else {
+      /*
+       * otherwise, this can't be a mail folder
+       */
+      sstate.isfolder  = 0;
+      sstate.ismime    = 0;
+    }
+    /*
+     * kill local envelope
+     */
+    UUkillheaders (&localenv);
+    return result;
+  }
+
+  /*
+   * if this is a MIME body, honor a Content-Type different than
+   * text/plain or a proper Content-Transfer-Encoding.
+   */
+  if (sstate.isfolder && sstate.ismime &&
+      sstate.mimestate == MS_BODY &&
+      (_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL ||
+       _FP_stristr (sstate.envelope.ctenc, "base64")           != NULL ||
+       _FP_stristr (sstate.envelope.ctype, "message")          != NULL)) {
+
+    if (sstate.envelope.subject)
+      result->subject = _FP_strdup (sstate.envelope.subject);
+    if (sstate.envelope.from)
+      result->origin  = _FP_strdup (sstate.envelope.from);
+
+    if (sstate.envelope.ctype)
+      result->mimetype = _FP_strdup (sstate.envelope.ctype);
+    else
+      result->mimetype = _FP_strdup ("text/plain");
+
+    if (_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL)
+      result->uudet = QP_ENCODED;
+    else if (_FP_stristr (sstate.envelope.ctenc, "base64") != NULL)
+      result->uudet = B64ENCODED;
+    else if (_FP_stristr (sstate.envelope.ctype, "multipart") != NULL ||
+	     _FP_stristr (sstate.envelope.ctype, "message")   != NULL)
+      result->uudet = PT_ENCODED;
+
+    prevpos = ftell (datei);
+    
+    /*
+     * If this is Quoted-Printable or Plain Text, just try looking
+     * for the next message header. If uu_fast_scanning, we know
+     * there won't be more headers.
+     */
+    if (result->uudet != 0 && uu_fast_scanning) {
+      /* do nothing */
+      res = 0;
+    }
+    else if (result->uudet != 0) {
+      hcount = lcount = 0;
+
+      prevpos = ftell (datei);
+      while (!feof (datei)) {
+	if (_FP_fgets (line, 255, datei) == NULL)
+	  break;
+	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+	if (ferror (datei))
+	  break;
+	line[255] = '\0';
+
+	if (IsKnownHeader (line)) {
+	  (void) ScanHeaderLine (datei, line);
+	  if (hcount == 0)
+	    preheaders = prevpos;
+	  hcount++;
+	  lcount++;
+	  if (hcount >= hlcount.restart) {
+	    /*
+	     * Hey, a new header starts here
+	     */
+	    fseek (datei, preheaders, SEEK_SET);
+	    prevpos = preheaders;
+	    break;
+	  }
+	}
+	else if (lcount > WAITHEADER) {
+	  hcount = 0;
+	  lcount = 0;
+	}
+	else if (hcount) {
+	  lcount++;
+	}
+	prevpos = ftell (datei);
+      }
+      res = 1;
+    }
+    else {
+      /*
+       * Otherwise, let's see what we can find ourself. No
+       * boundary (NULL) but MIME, and respect new headers.
+       */
+      if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result)) == -1) {
+	/* oops, something went wrong */
+	sstate.isfolder = 0;
+	sstate.ismime   = 0;
+	UUkillfread   (result);
+	return NULL;
+      }
+      if (result->uudet == 0 && uu_handletext) {
+	result->startpos = before;	/* display headers */
+	result->uudet = PT_ENCODED;
+      }
+
+      prevpos = ftell (datei);
+    }
+    /*
+     * produce result
+     */
+    if (sstate.envelope.fname) {
+      _FP_free (result->filename);
+      if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
+	     result->filename == NULL) {
+      sprintf (line, "%04d.txt", ++mimseqno);
+      if ((result->filename = _FP_strdup (line)) == NULL)
+	*errcode = UURET_NOMEM;
+    }
+    else {
+      /* assign a filename lateron */
+    }
+    if (result->subject == NULL) {
+      if (sstate.envelope.subject)
+	result->subject = _FP_strdup (sstate.envelope.subject);
+    }
+    result->flags  = ((res==1||uu_fast_scanning)?FL_PROPER:0) |
+      ((uu_fast_scanning) ? FL_TOEND : 0);
+    result->mimeid = _FP_strdup (sstate.envelope.mimeid);
+
+    if (uu_fast_scanning)
+      result->length = progress.fsize - result->startpos;
+    else
+      result->length = prevpos - result->startpos;
+
+    if (result->sfname == NULL)
+      result->sfname = _FP_strdup (fname);
+
+    if (result->mode == 0)
+      result->mode = 0644;
+
+    /*
+     * the other fields should already be set appropriately
+     */
+
+    if (res == 1) {
+      /*
+       * new headers found
+       */
+      sstate.isfolder  = 1;
+      sstate.ismime    = 0;
+      sstate.mimestate = MS_HEADERS;
+
+      UUkillheaders (&sstate.envelope);
+      memset (&sstate.envelope, 0, sizeof (headers));
+    }
+    else {
+      /*
+       * otherwise, this can't be a mail folder
+       */
+      sstate.isfolder  = 0;
+      sstate.ismime    = 0;
+    }
+
+    return result;
+  }
+
+#ifndef MORE_MIME
+  /*
+   * Some files have reduced headers, and what should be a multipart
+   * message is missing the proper Content-Type. If the first thing
+   * we find after a couple of empty lines is a boundary, try it!
+   * But make sure that this is indeed intended as being a boundary.
+   *
+   * Only accept it if there was indeed no Content-Type header line
+   * and if the following line is a proper Content-Type header. BTW,
+   * we know that sstate.envelope.boundary is NULL, or we wouldn't
+   * be here!
+   */
+  if (sstate.envelope.ctype == NULL ||
+      _FP_stristr (sstate.envelope.ctype, "multipart") != NULL) {
+    prevpos = ftell (datei);
+    while (!feof (datei)) {
+      if (_FP_fgets (line, 255, datei) == NULL) {
+	line[0] = '\0';
+	break;
+      }
+      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
+      if (!IsLineEmpty (line))
+	break;
+    }
+    if (line[0] == '-' && line[1] == '-' &&
+	!IsLineEmpty (line+2) && !feof (datei)) {
+      ptr1 = _FP_strrstr (line+2, "--");
+      ptr2 = ScanHeaderLine (datei, NULL);
+      if ((ptr1 == NULL || (*(ptr1+2) != '\012' && *(ptr1+2) != '\015')) &&
+	  ptr2 && _FP_strnicmp (ptr2, "Content-", 8) == 0) {
+	/*
+	 * hmm, okay, let's do it!
+	 */
+	sstate.isfolder  = 1;
+	sstate.ismime    = 1;
+	sstate.mimestate = MS_PREAMBLE;
+	/*
+	 * get boundary
+	 */
+	ptr1 = line+2;
+	while (*ptr1 && !isspace(*ptr1))
+	  ptr1++;
+	*ptr1 = '\0';
+	
+	sstate.envelope.boundary = _FP_strdup (line+2);
+	
+	/*
+	 * need restart
+	 */
+	
+	fseek (datei, prevpos, SEEK_SET);
+	
+	_FP_free (result);
+	return NULL;
+      }
+    }
+    fseek (datei, prevpos, SEEK_SET);
+  }
+#endif
+
+  /*
+   * Hmm, we're not in a ''special'' state, so it's more or less
+   * Freestyle time. Anyway, if this seems to be a Mime message,
+   * don't allow the minimal Base64 handling.
+   */
+
+  if (sstate.envelope.subject)
+    result->subject = _FP_strdup (sstate.envelope.subject);
+  if (sstate.envelope.from)
+    result->origin  = _FP_strdup (sstate.envelope.from);
+
+  if (sstate.envelope.ctype)
+    result->mimetype = _FP_strdup (sstate.envelope.ctype);
+  
+  if ((res=ScanData (datei, fname, errcode, NULL, 
+		     sstate.ismime, 1, result))==-1) {
+    /* oops, something went wrong */
+    sstate.isfolder = 0;
+    sstate.ismime   = 0;
+    UUkillfread   (result);
+    return NULL;
+  }
+  /*
+   * produce result
+   */
+  if (result->uudet == 0 && uu_handletext) {
+    result->startpos = before;	/* display headers */
+    result->uudet  = PT_ENCODED;
+    result->partno = 1;
+  }
+
+  if (sstate.envelope.fname) {
+    _FP_free (result->filename);
+    if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
+      *errcode = UURET_NOMEM;
+  }
+  else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
+	   result->filename == NULL) {
+    sprintf (line, "%04d.txt", ++mimseqno);
+    if ((result->filename = _FP_strdup (line)) == NULL)
+      *errcode = UURET_NOMEM;
+  }
+  else {
+    /* assign a filename lateron */
+  }
+  if (result->subject == NULL) {
+    if (sstate.envelope.subject)
+      result->subject = _FP_strdup (sstate.envelope.subject);
+  }
+
+  result->flags  = (result->uudet==PT_ENCODED)?FL_SINGLE:0;
+  result->mimeid = _FP_strdup (sstate.envelope.mimeid);
+  result->length = ftell (datei) - result->startpos;
+
+  if (result->mode == 0)
+    result->mode = 0644;
+
+  if (result->sfname == NULL)
+    result->sfname = _FP_strdup (fname);
+
+  if (res == 1) {
+    /*
+     * new headers found
+     */
+    sstate.isfolder  = 1;
+    sstate.ismime    = 0;
+    sstate.mimestate = MS_HEADERS;
+
+    UUkillheaders (&sstate.envelope);
+    memset (&sstate.envelope, 0, sizeof (headers));
+  }
+  else {
+    /*
+     * otherwise, this can't be a mail folder
+     */
+    sstate.isfolder  = 0;
+    sstate.ismime    = 0;
+  }
+
+  return result;
+
+  /*
+   * Emergency handling. Set errcode before jumping here.
+   */
+ ScanPartEmergency:
+  UUkillfread   (result);
+  UUkillheaders (&localenv);
+
+  while (mssdepth) {
+    mssdepth--;
+    UUkillheaders (&(multistack[mssdepth].envelope));
+    _FP_free (multistack[mssdepth].source);
+  }
+
+  return NULL;
+}
+
diff --git a/goldlib/uulib/uustring.c b/goldlib/uulib/uustring.c
new file mode 100644
index 0000000..e854d9b
--- /dev/null
+++ b/goldlib/uulib/uustring.c
@@ -0,0 +1,165 @@
+/*
+ * This file is part of uudeview, the simple and friendly multi-part multi-
+ * file uudecoder  program  (c)  1994 by Frank Pilhofer. The author may be
+ * contacted by his email address,          fp@informatik.uni-frankfurt.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * Strings used in the library for easier translation etc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef SYSTEM_WINDLL
+#include 
+#endif
+#ifdef SYSTEM_OS2
+#include 
+#endif
+
+#include 
+#include 
+
+#ifdef STDC_HEADERS
+#include 
+#include 
+#endif
+#ifdef HAVE_MALLOC_H
+#include 
+#endif
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+#ifdef HAVE_MEMORY_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+
+char * uustring_id = "$Id$";
+
+typedef struct {
+  int code;
+  char * msg;
+} stringmap;
+
+/*
+ * Map of messages. This table is not exported, the messages must
+ * be retrieved via the below uustring() function.
+ */
+
+static stringmap messages[] = {
+  /* I/O related errors/messages. Last parameter is strerror() */
+  { S_NOT_OPEN_SOURCE,  "Could not open source file %s: %s" },
+  { S_NOT_OPEN_TARGET,  "Could not open target file %s for writing: %s" },
+  { S_NOT_OPEN_FILE,    "Could not open file %s: %s" },
+  { S_NOT_STAT_FILE,    "Could not stat file %s: %s" },
+  { S_SOURCE_READ_ERR,  "Read error on source file: %s" },
+  { S_READ_ERROR,       "Error reading from %s: %s" },
+  { S_IO_ERR_TARGET,    "I/O error on target file %s: %s" },
+  { S_WR_ERR_TARGET,    "Write error on target file %s: %s" },
+  { S_WR_ERR_TEMP,      "Write error on temp file: %s" },
+  { S_TMP_NOT_REMOVED,  "Could not remove temp file %s: %s (ignored)" },
+
+  /* some other problems */
+  { S_OUT_OF_MEMORY,    "Out of memory allocating %d bytes" },
+  { S_TARGET_EXISTS,    "Target file %s exists and overwriting is not allowed" },
+  { S_NOT_RENAME,       "Could not change name of %s to %s" },
+  { S_ERR_ENCODING,     "Error while encoding %s: %s" },
+  { S_STAT_ONE_PART,    "Could not stat input, encoding to one part only" },
+  { S_PARM_CHECK,       "Parameter check failed in %s" },
+  { S_SHORT_BINHEX,     "BinHex encoded file %s ended prematurely (%ld bytes left)" },
+  { S_DECODE_CANCEL,    "Decode operation canceled" },
+  { S_ENCODE_CANCEL,    "Encode operation canceled" },
+  { S_SCAN_CANCEL,      "Scanning canceled" },
+
+  /* informational messages */
+  { S_LOADED_PART,      "Loaded from %s: '%s' (%s): %s part %d %s %s %s" },
+  { S_NO_DATA_FOUND,    "No encoded data found in %s" },
+  { S_NO_BIN_FILE,      "Oops, could not find decoded file?" },
+  { S_STRIPPED_SETUID,  "Stripped setuid/setgid bits from target file %s mode %d" },
+  { S_DATA_SUSPICIOUS,  "Data looks suspicious. Decoded file might be corrupt." },
+  { S_NO_TEMP_NAME,     "Could not get name for temporary file" },
+  { S_BINHEX_SIZES,     "BinHex file: data/resource fork sizes %ld/%ld" },
+  { S_BINHEX_BOTH,      "BinHex file: both forks non-empty, decoding data fork" },
+  { S_SMERGE_MERGED,    "Parts of '%s' merged with parts of '%s' (%d)" },
+  
+  /* MIME-related messages */
+  { S_MIME_NO_BOUNDARY, "Multipart message without boundary ignored" },
+  { S_MIME_B_NOT_FOUND, "Boundary expected on Multipart message but found EOF" },
+  { S_MIME_MULTI_DEPTH, "Multipart message nested too deep" },
+  { S_MIME_PART_MULTI,  "Handling partial multipart message as plain text" },
+
+  { 0, "" }
+};
+
+/*
+ * description of the return values UURET_*
+ */
+
+char *uuretcodes[] = {
+  "OK",
+  "File I/O Error",
+  "Not Enough Memory",
+  "Illegal Value",
+  "No Data found",
+  "Unexpected End of File",
+  "Unsupported function",
+  "File exists",
+  "Continue -- no error",	/* only to be seen internally */
+  "Operation Canceled"
+};
+
+/*
+ * Names of encoding types
+ */
+
+char *codenames[7] = {
+  "", "UUdata", "Base64", "XXdata", "Binhex", "Text", "Text"
+};
+
+/*
+ * Message types
+ */
+
+char *msgnames[6] = {
+  "", "Note: ", "Warning: ", "ERROR: ", "FATAL ERROR: ", "PANIC: "
+};
+
+/*
+ * Retrieve one of the messages. We never return NULL
+ * but instead escape to "oops".
+ */
+
+char *
+uustring (int codeno)
+{
+  static char * faileddef = "oops";
+  stringmap *ptr = messages;
+
+  while (ptr->code) {
+    if (ptr->code == codeno)
+      return ptr->msg;
+    ptr++;
+  }
+
+  UUMessage (uustring_id, __LINE__, UUMSG_ERROR,
+	     "Could not retrieve string no %d",
+	     codeno);
+
+  return faileddef;
+}
diff --git a/goldlib/uulib/uustring.h b/goldlib/uulib/uustring.h
new file mode 100644
index 0000000..bca363e
--- /dev/null
+++ b/goldlib/uulib/uustring.h
@@ -0,0 +1,34 @@
+/* extracted from Id: uustring.c,v 1.1 2000/01/27 18:44:38 asa Exp  */
+#define S_NOT_OPEN_SOURCE      1
+#define S_NOT_OPEN_TARGET      2
+#define S_NOT_OPEN_FILE        3
+#define S_NOT_STAT_FILE        4
+#define S_SOURCE_READ_ERR      5
+#define S_READ_ERROR           6
+#define S_IO_ERR_TARGET        7
+#define S_WR_ERR_TARGET        8
+#define S_WR_ERR_TEMP          9
+#define S_TMP_NOT_REMOVED     10
+#define S_OUT_OF_MEMORY       11
+#define S_TARGET_EXISTS       12
+#define S_NOT_RENAME          13
+#define S_ERR_ENCODING        14
+#define S_STAT_ONE_PART       15
+#define S_PARM_CHECK          16
+#define S_SHORT_BINHEX        17
+#define S_DECODE_CANCEL       18
+#define S_ENCODE_CANCEL       19
+#define S_SCAN_CANCEL         20
+#define S_LOADED_PART         21
+#define S_NO_DATA_FOUND       22
+#define S_NO_BIN_FILE         23
+#define S_STRIPPED_SETUID     24
+#define S_DATA_SUSPICIOUS     25
+#define S_NO_TEMP_NAME        26
+#define S_BINHEX_SIZES        27
+#define S_BINHEX_BOTH         28
+#define S_SMERGE_MERGED       29
+#define S_MIME_NO_BOUNDARY    30
+#define S_MIME_B_NOT_FOUND    31
+#define S_MIME_MULTI_DEPTH    32
+#define S_MIME_PART_MULTI     33
diff --git a/goldlib/uulib/uuutil.c b/goldlib/uulib/uuutil.c
new file mode 100644
index 0000000..547cb27
--- /dev/null
+++ b/goldlib/uulib/uuutil.c
@@ -0,0 +1,485 @@
+/*
+ * This file is part of uudeview, the simple and friendly multi-part multi-
+ * file uudecoder  program  (c)  1994 by Frank Pilhofer. The author may be
+ * contacted by his email address,          fp@informatik.uni-frankfurt.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * certain utilitarian functions that didn't fit anywhere else
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef SYSTEM_WINDLL
+#include 
+#endif
+#ifdef SYSTEM_OS2
+#include 
+#endif
+
+#include 
+#include 
+
+#ifdef STDC_HEADERS
+#include 
+#include 
+#endif
+#ifdef HAVE_MALLOC_H
+#include 
+#endif
+#ifdef HAVE_UNISTD_H
+#include 
+#endif
+#ifdef HAVE_MEMORY_H
+#include 
+#endif
+#ifdef HAVE_ERRNO_H
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+
+char * uuutil_id = "$Id$";
+
+/*
+ * Parts with different known extensions will not be merged by SPMS.
+ * if first character is '@', it is synonymous to the previous one.
+ */
+
+static char *knownexts[] = {
+  "mpg", "@mpeg", "avi", "mov",
+  "gif", "jpg", "@jpeg", "tif",
+  "voc", "wav", "@wave", "au",
+  "zip", "arj", "tar",
+  NULL
+};
+
+/*
+ * forward declarations of local functions
+ */
+
+static int	UUSMPKnownExt		_ANSI_ARGS_((char *filename));
+static uulist *	UU_smparts_r		_ANSI_ARGS_((uulist *, int));
+
+/*
+ * mallocable areas
+ */
+
+char *uuutil_bhwtmp;
+
+/*
+ * free some memory
+ **/
+
+void
+UUkillfread (fileread *data)
+{
+  if (data != NULL) {
+    _FP_free (data->subject);
+    _FP_free (data->filename);
+    _FP_free (data->origin);
+    _FP_free (data->mimeid);
+    _FP_free (data->mimetype);
+    _FP_free (data->sfname);
+    _FP_free (data);
+  }
+}
+
+void
+UUkillfile (uufile *data)
+{
+  uufile *next;
+
+  while (data) {
+    _FP_free    (data->filename);
+    _FP_free    (data->subfname);
+    _FP_free    (data->mimeid);
+    _FP_free    (data->mimetype);
+    UUkillfread (data->data);
+
+    next = data->NEXT;
+    _FP_free  (data);
+    data = next;
+  }
+}
+
+void
+UUkilllist (uulist *data)
+{
+  uulist *next;
+
+  while (data) {
+    if (data->binfile != NULL)
+      if (unlink (data->binfile))
+	UUMessage (uuutil_id, __LINE__, UUMSG_WARNING,
+		   uustring (S_TMP_NOT_REMOVED),
+		   data->binfile, strerror (errno));
+
+    _FP_free   (data->filename);
+    _FP_free   (data->subfname);
+    _FP_free   (data->mimeid);
+    _FP_free   (data->mimetype);
+    _FP_free   (data->binfile);
+    UUkillfile (data->thisfile);
+    _FP_free   (data->haveparts);
+    _FP_free   (data->misparts);
+
+    next = data->NEXT;
+    _FP_free (data);
+    data = next;
+  }
+}
+
+/*
+ * this kill function is an exception in that it doesn't kill data itself
+ */
+
+void
+UUkillheaders (headers *data)
+{
+  if (data != NULL) {
+    _FP_free (data->from);
+    _FP_free (data->subject);
+    _FP_free (data->rcpt);
+    _FP_free (data->date);
+    _FP_free (data->mimevers);
+    _FP_free (data->ctype);
+    _FP_free (data->ctenc);
+    _FP_free (data->fname);
+    _FP_free (data->boundary);
+    _FP_free (data->mimeid);
+    memset   (data, 0, sizeof (headers));
+  }
+}
+
+/*
+ * checks for various well-known extensions. if two parts have different
+ * known extensions, we won't merge them.
+ */
+
+static int
+UUSMPKnownExt (char *filename)
+{
+  char **eiter = knownexts, *ptr=_FP_strrchr(filename, '.');
+  int count=0, where=0;
+
+  if (ptr == NULL)
+    return -1;
+  ptr++;
+
+  while (*eiter) {
+    if (_FP_stricmp (ptr, (**eiter=='@')?*eiter+1:*eiter) == 0)
+      return where;
+    else
+      eiter++;
+
+    if (*eiter == NULL)
+      break;
+
+    if (**eiter=='@')
+      count++;
+    else
+      where = ++count;
+  }
+  return -1;
+}
+
+/*
+ * de-compress a binhex RLE stream
+ * the data read from in is uncompressed, and at most maxcount bytes
+ * (or octets, as they say) are copied to out. Because an uncompression
+ * might not be completed because of this maximum number of bytes. There-
+ * for, the leftover character and repetition count is saved. If a marker
+ * has been read but not the repetition count, *rpc is set to -256.
+ *
+ * the function returns the number of bytes eaten from in. If opc is not
+ * NULL, the total number of characters stored in out is saved there
+ *
+ * with repetition counts, remember that we've already transferred *one*
+ * occurence
+ */
+
+int
+UUbhdecomp (char *in, char *out, char *last, int *rpc, 
+	    size_t inc, size_t max, size_t *opc)
+{
+  size_t count, used=0, dummy;
+  char marker = '\220' /* '\x90' */;
+
+  if (opc == NULL)
+    opc = &dummy;
+  else
+    *opc = 0;
+
+  if (*rpc == -256) {
+    if (inc == 0)
+      return 0;
+    *rpc = (int) (unsigned char) *in++; used++;
+
+    if (*rpc == 0) {
+      *last = *out++ = marker;
+      max--; *opc+=1;
+    }
+    else
+      *rpc-=1;
+  }
+
+  if (*rpc) {
+    count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
+
+    memset (out, *last, count);
+
+    out  += count;
+    *opc += count;
+    max  -= count;
+    *rpc -= count;
+  }
+
+  while (used < inc && max) {
+    if (*in == marker) {
+      used++; in++;
+      if (used == inc) {
+	*rpc = -256;
+	return used;
+      }
+      *rpc = (int) (unsigned char) *in++; used++;
+
+      if (*rpc == 0) {
+	*last = *out++ = marker;
+	max--; *opc+=1;
+	continue;
+      }
+      else
+	*rpc -= 1;
+
+      count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
+      memset (out, *last, count);
+
+      out  += count;
+      *opc += count;
+      max  -= count;
+      *rpc -= count;
+    }
+    else {
+      *last = *out++ = *in++;
+      used++; *opc+=1; max--;
+    }
+  }
+
+  return used;
+}
+
+/*
+ * write to binhex file
+ */
+
+size_t
+UUbhwrite (char *ptr, size_t sel, size_t nel, FILE *file)
+{
+  char *tmpstring=uuutil_bhwtmp;
+  static int rpc = 0;
+  static char lc;
+  int count, tc=0;
+  size_t opc;
+
+  if (ptr == NULL) { /* init */
+    rpc = 0;
+    return 0;
+  }
+
+  while (nel || (rpc != 0 && rpc != -256)) {
+    count = UUbhdecomp (ptr, tmpstring, &lc, &rpc,
+			nel, 256, &opc);
+    if (fwrite (tmpstring, 1, opc, file) != opc)
+      return 0;
+    if (ferror (file))
+      return 0;
+    nel -= count;
+    ptr += count;
+    tc  += count;
+  }
+
+  return tc;
+}
+
+static uulist *
+UU_smparts_r (uulist *addit, int pass)
+{
+  uulist *iter = UUGlobalFileList;
+  uufile *fiter, *dest, *temp;
+  int count, flag, a, b;
+
+  while (iter) {
+    if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
+      iter = iter->NEXT;
+      continue;
+    }
+    if (iter == addit) {
+      iter = iter->NEXT;
+      continue;
+    }
+    if ((iter->begin && addit->begin) || (iter->end && addit->end) ||
+	(iter->uudet != addit->uudet)) {
+      iter = iter->NEXT;
+      continue;
+    }
+    if ((a = UUSMPKnownExt (addit->subfname)) != -1 &&
+        (b = UUSMPKnownExt (iter->subfname))  != -1)
+      if (a != b) {
+        iter = iter->NEXT;
+        continue;
+      }
+
+    flag  = count = 0;
+    fiter = iter->thisfile;
+    temp  = addit->thisfile;
+    dest  = NULL;
+
+    while (temp) {
+      if (!(temp->data->uudet)) {
+	temp = temp->NEXT;
+	continue;
+      }
+
+      while (fiter && fiter->partno < temp->partno) {
+        dest  = fiter;
+        fiter = fiter->NEXT;
+      }
+      if (fiter && fiter->partno == temp->partno) {
+        flag = 0;
+        break;
+      }
+      else {
+	flag   = 1;
+        count += ((dest)  ? temp->partno - dest->partno - 1 : 0) +
+                 ((fiter) ? fiter->partno - temp->partno - 1 : 0);
+      }
+
+      temp = temp->NEXT;
+    }
+    if (flag == 0 ||
+        (pass == 0 && count > 0) ||
+        (pass == 1 && count > 5)) {
+      iter = iter->NEXT;
+      continue;
+    }
+
+    dest  = iter->thisfile;
+    fiter = addit->thisfile;
+
+    if (iter->filename == NULL && addit->filename != NULL)
+      iter->filename = _FP_strdup (addit->filename);
+
+    if (addit->begin) iter->begin = 1;
+    if (addit->end)   iter->end   = 1;
+
+    if (addit->mode != 0 && iter->mode == 0)
+      iter->mode = addit->mode;
+
+    while (fiter) {
+      flag = 0;
+
+      if (fiter->partno == iter->thisfile->partno ||
+	  (dest->NEXT != NULL && fiter->partno == dest->NEXT->partno)) {
+	temp           = fiter->NEXT;
+	fiter->NEXT    = NULL;
+
+	UUkillfile (fiter);
+
+	addit->thisfile= temp;
+	fiter          = temp;
+	continue;
+      }
+      if (fiter->partno < iter->thisfile->partno) {
+	temp           = fiter->NEXT;
+	fiter->NEXT    = iter->thisfile;
+	iter->thisfile = fiter;
+	dest           = fiter;
+	addit->thisfile= temp;
+	fiter          = temp;
+      }
+      else if (dest->NEXT == NULL || fiter->partno < dest->NEXT->partno) {
+	temp           = fiter->NEXT;
+	fiter->NEXT    = dest->NEXT;
+	dest->NEXT     = fiter;
+	addit->thisfile= temp;
+	fiter          = temp;
+      }
+      else {
+	dest = dest->NEXT;
+      }
+    }
+    break;
+  }
+  return iter;
+}
+
+int UUEXPORT
+UUSmerge (int pass)
+{
+  uulist *iter = UUGlobalFileList, *last=NULL, *res, *temp;
+  int flag = 0;
+
+  while (iter) {
+    if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
+      last = iter;
+      iter = iter->NEXT;
+      continue;
+    }
+    if ((res = UU_smparts_r (iter, pass)) != NULL) {
+      UUMessage (uuutil_id, __LINE__, UUMSG_MESSAGE,
+		 uustring (S_SMERGE_MERGED),
+		 (iter->subfname) ? iter->subfname : "",
+		 (res->subfname)  ? res->subfname  : "", pass);
+ 
+      temp       = iter->NEXT;
+      iter->NEXT = NULL;
+      UUkilllist (iter);
+
+      flag++;
+
+      if (last == NULL) {
+	UUGlobalFileList = temp;
+	iter             = temp;
+      }
+      else {
+	last->NEXT       = temp;
+	iter             = temp;
+      }
+
+      continue;
+    }
+    last = iter;
+    iter = iter->NEXT;
+  }
+
+  /*
+   * check again
+   */
+
+  UUCheckGlobalList ();
+
+  return flag;
+}
+
+
+/*****************************************************************************
+ + Frank Pilhofer                             fp@informatik.uni-frankfurt.de +
+ +---------------------------------------------------------------------------+
+ | Department of Computer Sciences * University of Frankfurt / Main, Germany |
+ *****************************************************************************/
diff --git a/goldnode/Makefile b/goldnode/Makefile
new file mode 100644
index 0000000..3365327
--- /dev/null
+++ b/goldnode/Makefile
@@ -0,0 +1,17 @@
+# -*- makefile -*-
+
+TOP=..
+SHORTTARGET=gn
+TARGET=goldnode
+INCS=-I$(TOP)/goldlib/gall -I$(TOP)/goldlib/gcfg -I$(TOP)/golded3/
+ifeq ($(findstring EMX, $(PATH)), EMX)
+STDLIBS=-lstdcpp
+endif
+ifeq ($(TERM),cygwin)
+STDLIBS=-luser32
+endif
+GLIBS=gall
+CLEANS=
+
+include $(TOP)/GNUmakef.inc
+include $(TOP)/GNUmakef.prg
diff --git a/goldnode/goldnode.all b/goldnode/goldnode.all
new file mode 100644
index 0000000..7f80c65
--- /dev/null
+++ b/goldnode/goldnode.all
@@ -0,0 +1,40 @@
+
+##  ------------------------------------------------------------------
+##  The Goldware Utilities. Copyright (C) Odinn Sorensen.
+##  ------------------------------------------------------------------
+##  This program is free software; you can redistribute it and/or
+##  modify it under the terms of the GNU General Public License as
+##  published by the Free Software Foundation; either version 2 of the
+##  License, or (at your option) any later version.
+##
+##  This program is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+##  General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+##  ------------------------------------------------------------------
+##  $Id$
+##  ------------------------------------------------------------------
+##  Master build file.
+##  ------------------------------------------------------------------
+
+goldnode cpp all nov bcd bco bcx djg emx lnx rsx wcn wco wcx cyg
+
+##  ------------------------------------------------------------------
+
+gnbco    def all
+gnbcx    def all
+
+##  ------------------------------------------------------------------
+
+Makefile .   all
+bldbcc   mak all
+bldgnu   mak all
+bldwcc   mak all
+goldnode all all
+
+##  ------------------------------------------------------------------
+
diff --git a/goldnode/goldnode.cpp b/goldnode/goldnode.cpp
new file mode 100644
index 0000000..102f51e
--- /dev/null
+++ b/goldnode/goldnode.cpp
@@ -0,0 +1,1539 @@
+
+//  ------------------------------------------------------------------
+//  The Goldware Utilities.
+//  Copyright (C) 1990-1999 Odinn Sorensen
+//  Copyright (C) 1999-2000 Alexander S. Aganichev
+//  ------------------------------------------------------------------
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License as
+//  published by the Free Software Foundation; either version 2 of the
+//  License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//  ------------------------------------------------------------------
+//  $Id$
+//  ------------------------------------------------------------------
+//  GoldNODE - A nodelist compiler for GoldED.
+//  ------------------------------------------------------------------
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+//#define GOLDNODE_STATS 1
+
+#ifdef GOLDNODE_STATS
+#include 
+#endif
+
+
+//  ------------------------------------------------------------------
+//  Config versions
+
+#if defined(__OS2__)
+#define __GPID__ "GoldNode+/2"
+#elif defined(__WIN32__)
+#define __GPID__ "GoldNode+/W32"
+#elif defined(__MSDOS__)
+#define __GPID__ "GoldNode+/386"
+#elif defined(__linux__)
+#define __GPID__ "GoldNODE+/LNX"
+#elif defined(__FreeBSD__) or defined(__OpenBSD__)
+#define __GPID__ "GoldNODE+/BSD"
+#else
+#define __GPID__ "GoldNODE+"
+#endif
+
+#define __GVER__ "1.1.4.1"         // Visible version
+
+
+//  ------------------------------------------------------------------
+// 32-bit versions
+
+const size_t maxnodes = 262000;
+
+
+//  ------------------------------------------------------------------
+
+typedef vector::iterator addr_iter;
+typedef vector::iterator stamp_iter;
+typedef list<_GEIdx> geidxlist;
+
+// Nodelists
+vector nodelist; // nodelist files,stamps,update marker
+vector nodezone;  // nodelist zones
+vector userlist; // Userlist files,stamps,update marker
+vector userzone;  // Userlist zones
+
+// Exclude/Include nodes
+vector excludenode;
+vector includenode;
+
+// Index files
+string  addrindex;
+string  nodeindex;
+string  listindex;
+
+//  ------------------------------------------------------------------
+
+const word _POINT = 0x0001;
+const word _NODE  = 0x0002;
+const word _NET   = 0x0003;
+const word _ZONE  = 0x0004;
+const word _TEST  = 777;
+
+static string nodepath;                // Path to the nodelist files
+
+static time_t runtime = 0;
+static int    sh_mod = SH_DENYWR;
+static bool   fidouser = false;
+static Path   fidouserlst;
+static bool   ignoredups = false;
+static size_t dups = 0;
+static bool   quiet = false;
+
+#ifdef GOLDNODE_STATS
+bool make_stats = false;
+Path statfilename = "goldnode.stt";
+
+struct nl_stat {
+  int nodename[100];
+  int location[100];
+  int sysopname[100];
+};
+
+nl_stat statistic;
+#endif
+
+//  ------------------------------------------------------------------
+
+#define fast_printf    if(not quiet) printf
+#define fast_putchar   if(not quiet) putchar
+
+//  ------------------------------------------------------------------
+//  Display a "twirly"
+
+#define TWIRLY_FACTOR 511
+#define ISTWIRLY(n) (((n)&TWIRLY_FACTOR)==0)
+
+static void twirly() {
+
+  static int n=0;
+
+  n = (++n)%4;
+  switch(n) {
+    case 0:   fast_putchar('|');   break;
+    case 1:   fast_putchar('/');   break;
+    case 2:   fast_putchar('-');   break;
+    case 3:   fast_putchar('\\');  break;
+  }
+
+  fast_putchar('\b');
+  fflush(stdout);
+}
+
+
+//  ------------------------------------------------------------------
+
+static bool match_addr_mask(Addr* mask, Addr* addr) {
+
+  if(mask->zone == GFTN_ALL or mask->zone == addr->zone)
+    if(mask->net == GFTN_ALL or mask->net == addr->net)
+      if(mask->node == GFTN_ALL or mask->node == addr->node)
+        if(mask->point == GFTN_ALL or mask->point == addr->point)
+          return true;
+
+  return false;
+}
+
+
+//  ------------------------------------------------------------------
+
+static bool macro_addr(char* str, int ap, Addr* addr) {
+
+  word part = 0xFFFD;
+
+  if(*str == NUL)
+    part = 0;
+  else if(isdigit(*str))
+    part = atow(str);
+  else if(*str == '?' or *str == '*')
+    part = GFTN_ALL;
+
+  if(ap == _TEST) {
+    if(part == 0xFFFD)
+      return false;
+    else
+      return true;
+  }
+
+  switch(ap) {
+    case _ZONE:
+      addr->zone = part;
+      break;
+    case _NET:
+      addr->net = part;
+      break;
+    case _NODE:
+      addr->node = part;
+      break;
+    case _POINT:
+      addr->point = part;
+      break;
+    default:
+      return false;
+  }
+  return true;
+}
+
+
+//  ------------------------------------------------------------------
+
+static char* fast_parse_addr(char* str, Addr* addr) {
+
+  char* net;
+  char* node;
+  char* point;
+  char* domain;
+  char* space;
+
+  space = strchr(str, ' ');
+  if(space)
+    *space = NUL;
+
+  net = strchr(str, ':');
+  node = strchr(str, '/');
+  point = strchr(str, '.');
+  domain = strchr(str, '@');
+  if(domain and point)
+    if((dword)point > (dword)domain)
+      point = NULL;
+
+  if(space)
+    *space = ' ';
+
+  if(net) {
+    addr->zone = atow(str);
+    addr->net = atow(net+1);
+    if(node)
+      addr->node = atow(node+1);
+  }
+  else {
+    if(node) {
+      if(*str != '/')
+        addr->net = atow(str);
+      addr->node = atow(node+1);
+    }
+    else {
+      if(point != str)
+        addr->node = atow(str);
+    }
+  }
+  if(point)
+    addr->point = atow(point+1);
+
+  return domain;
+}
+
+
+//  ------------------------------------------------------------------
+
+static char* parse_address(char* str, Addr* addr, Addr* mainaka) {
+
+  char* domain = NULL;
+
+  str = strskip_wht(str);
+
+  if(isdigit(*str) or *str == '.' or macro_addr(str, _TEST, addr)) {
+
+    char* net = strchr(str, ':');
+    char* node = strchr(str, '/');
+    char* point = strchr(str, '.');
+    domain = strchr(str, '@');
+    if(domain and point)
+      if((dword)point > (dword)domain)
+        point = NULL;
+
+    if(net) {
+      macro_addr(str, _ZONE, addr);
+      macro_addr(net+1, _NET, addr);
+      if(node)
+        macro_addr(node+1, _NODE, addr);  // zone:net/node
+      else
+        addr->node = mainaka->node;                // zone:net
+    }
+    else {
+      addr->zone = mainaka->zone;
+      if(node) {
+        if(*str != '/')
+          macro_addr(str, _NET, addr);      // net/node
+        else
+          addr->net = mainaka->net;                  // /node
+        macro_addr(node+1, _NODE, addr);
+      }
+      else {
+        if(point == str)
+          addr->node = mainaka->node;                // .point
+        else
+          macro_addr(str, _NODE, addr);     // node.point
+        addr->net = mainaka->net;
+      }
+    }
+    if(point)
+      macro_addr(point+1, _POINT, addr);
+  }
+  if(domain == NULL)
+    domain = str+strlen(str);   // point at NUL char
+
+  return(domain);
+}
+
+
+//  ------------------------------------------------------------------
+
+static char* make_addr_str(char* str, Addr* addr, char* domain) {
+
+  char* ptr = str;
+  static char buf[20];
+
+  *ptr = NUL;
+
+  if(addr->zone) {
+    if(addr->zone == GFTN_ALL)
+      ptr = stpcpy(ptr, "*");
+    else {
+      sprintf(buf, "%u", addr->zone);
+      ptr = stpcpy(ptr, buf);
+    }
+    *ptr++ = ':';
+  }
+
+  if(addr->net == GFTN_ALL)
+    ptr = stpcpy(ptr, "*");
+  else {
+    sprintf(buf, "%u", addr->net);
+    ptr = stpcpy(ptr, buf);
+  }
+  *ptr++ = '/';
+
+  if(addr->node == GFTN_ALL)
+    ptr = stpcpy(ptr, "*");
+  else {
+    sprintf(buf, "%u", addr->node);
+    ptr = stpcpy(ptr, buf);
+  }
+
+  if(addr->point) {
+    *ptr++ = '.';
+    if(addr->point == GFTN_ALL)
+      ptr = stpcpy(ptr, "*");
+    else {
+      sprintf(buf, "%u", addr->point);
+      ptr = stpcpy(ptr, buf);
+    }
+  }
+
+  if(domain and *domain) {
+    *ptr++ = '@';
+    ptr = stpcpy(ptr, domain);
+  }
+
+  *ptr = NUL;
+
+  return(str);
+}
+
+
+//  ------------------------------------------------------------------
+//  Compare two nodes by name/address/file/pos
+
+static bool cmp_nnlsts(_GEIdx A, _GEIdx B) {
+
+  int cmp;
+
+  if((cmp = stricmp(A.name, B.name)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.zone, B.addr.zone)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.net, B.addr.net)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.node, B.addr.node)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.point, B.addr.point)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.pos, B.pos)) != 0)
+    return(cmp < 0);
+  return false;
+}
+
+
+//  ------------------------------------------------------------------
+//  Compare two nodes by address/name/file/pos
+
+static bool cmp_anlsts(_GEIdx A, _GEIdx B) {
+
+  int cmp;
+
+  if((cmp = CmpV(A.addr.zone, B.addr.zone)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.net, B.addr.net)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.node, B.addr.node)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.addr.point, B.addr.point)) != 0)
+    return(cmp < 0);
+  if((cmp = stricmp(A.name, B.name)) != 0)
+    return(cmp < 0);
+  if((cmp = CmpV(A.pos, B.pos)) != 0)
+    return(cmp < 0);
+  return false;
+}
+
+
+//  ------------------------------------------------------------------
+
+static char* CvtName(char* inp) {
+
+  char buf[300];
+  char* p;
+  char* q;
+
+  // Convert underlines to spaces
+
+  p = inp;
+  while(*p)
+    if(*(p++) == '_')
+      *(p-1) = ' ';
+
+  // Strip leading spaces
+
+  p = inp;
+  while(isspace(*p))
+    p++;
+  q = &inp[strlen(p)-1];
+
+  // Strip trailing spaces
+
+  while(isspace(*q))
+    *q-- = NUL;
+
+  // Search for last space or point
+
+  while(*q != ' ' and *q != '.' and q > p)
+    q--;
+
+  // If last char is a point, find last space instead
+
+  if(*(q+1) == 0)
+    while(*q != ' ' and q > p)
+      q--;
+
+  // Exchange last name and first name(s)
+
+  if(p != q) {
+    strcpy(stpcpy(buf, q+1), ", ");
+    *(q+(*q == '.' ? 1 : 0)) = 0;
+    strcat(buf, p);
+    strcpy(inp, buf);
+  }
+  struplow(inp);
+  return inp;
+}
+
+
+//  ------------------------------------------------------------------
+
+#ifdef GOLDNODE_STATS
+void calc_statistic(FILE* ofp, int* observation, float N) {
+
+  int i;
+  float mean = 0.0;
+  float sumfrekvens = 0.0;
+  float varians = 0.0;
+
+  //              12   12345   12345   123456   123456789012
+  fprintf(ofp, ".---------------------------------------------.\n");
+  fprintf(ofp, "|   x |  h(x) |  f(x) | x*f(x) | (x-m)^2*f(x) |\n");
+  fprintf(ofp, "|-----+-------+-------+--------+--------------|\n");
+
+  for(i=0; i<100; i++) {
+    float x = i;
+    if(observation[i]) {
+      float hyppighed = observation[i];
+      float frekvens = hyppighed / N;
+      mean += x * frekvens;
+      sumfrekvens += frekvens;
+    }
+  }
+
+  for(i=0; i<100; i++) {
+    float x = i;
+    if(observation[i]) {
+      float hyppighed = observation[i];
+      float frekvens = hyppighed / N;
+      float vartmp =  (x-mean)*(x-mean)*frekvens;
+      varians += vartmp;
+      fprintf(ofp, "| %3i | %5i | %5.3f | %6.3f | %12.3f | \n", i, observation[i], frekvens, x*frekvens, vartmp);
+    }
+  }
+
+  fprintf(ofp, "|-----+-------+-------+--------+--------------|\n");
+  fprintf(ofp, "| sum | %5.0f | %5.3f | %5.3f | %12.3f |\n", N, sumfrekvens, mean, varians);
+  fprintf(ofp, "`---------------------------------------------'\n");
+  fprintf(ofp, "\n");
+  fprintf(ofp, "Mean: %.1f\n", mean);
+  fprintf(ofp, "Variance = %.1f\n", varians);
+  fprintf(ofp, "Standard deviation = %.1f\n", sqrt(varians));
+  fprintf(ofp, "\n");
+}
+#endif
+
+
+//  ------------------------------------------------------------------
+//  some useful string operations
+
+inline void index_line(char* p, char* ptrs[5]) {
+
+  for(int i=0; i<5; i++) {
+    char* q = p;
+    while(*q != ',' and *q) {
+      if(*q == '_')
+        *q = ' ';
+      q++;
+    }
+    if(*q) {
+      ptrs[i] = p;
+      *q++ = NUL;
+      p = q;
+    }
+  }
+}
+
+
+//  ------------------------------------------------------------------
+//  Read the nodelists and userlists
+
+static void read_nodelists() {
+
+  long pos;
+  FILE* lfp;
+  char* ptr;
+  _GEIdx nlst;
+  Addr nlstz;
+  char buf[512], buf2[100];
+  int point;
+  uint line, realfno;
+  size_t no, nodes;
+  const char* name;
+  char* lp[5];
+  geidxlist nodeidx;
+  stamp_iter fno;
+  addr_iter zno;
+
+  nodes = 0;
+
+  fast_printf("\n* Compiling nodelists:\n");
+
+  // Delete the current indexfiles so they don't take up space
+  remove(addrindex.c_str());
+  remove(nodeindex.c_str());
+
+  // Compile nodelists
+  for(realfno=0, fno=nodelist.begin(), zno=nodezone.begin(); fno != nodelist.end(); fno++, zno++) {
+
+    if(nodes < maxnodes) {
+
+      lfp = fsopen(fno->fn, "rb", sh_mod);
+      if(lfp) {
+
+        setvbuf(lfp, NULL, _IOFBF, 32000);
+        fno->ft = GetFiletime(fno->fn);
+
+        // Initialize for each nodelist file
+        no = 0;
+        pos = 0;
+        line = 0;
+        point = YES;
+        nlst.reset();
+        nlstz = nlst.addr = *zno;
+        name = CleanFilename(fno->fn);
+
+        // Read all nodes
+        while(fgets(buf, sizeof(buf), lfp)) {
+          line++;
+
+          // Break out if eof-marker is found
+          if(*buf == '\x1A')
+            break;
+
+          // Note file position
+          nlst.pos = pos;
+
+          // Get line length and fix possible errors
+          uint llen = strlen(buf);
+          ptr = buf+llen-1;
+          while(llen and not (*ptr == '\r' or *ptr == '\n' or *ptr == '\x1A')) {
+            buf[llen] = ' ';
+            fast_printf("\r* |-%-12s     Warning line %u - Invalid NUL char encountered.\n", name, line);
+            llen = strlen(buf);
+            ptr = buf+llen-1;
+          }
+          pos += llen;
+
+          // Skip whitespace
+          ptr = buf;
+          while(isspace(*ptr))
+            ptr++;
+
+          if(*ptr != ';' and *ptr) {
+
+            // First test for FD pvt extension
+            if(toupper(*ptr) == 'B') {   // Boss
+              nlst.addr.reset();
+              parse_address(ptr+5, &nlst.addr, &nlstz);
+              point = YES;
+              continue;
+            }
+
+            // Test for Goldware extension
+            if(isdigit(*ptr)) {
+              nlst.addr.reset();
+              parse_address(ptr+5, &nlst.addr, &nlstz);
+              point = YES;
+            }
+
+            // Hold,32,TriCom,Hornbaek,Lars_Joergensen,45-12345678,2400,XX
+
+            // Form the full node address
+            index_line(ptr, lp);
+
+            // NOTE: I use the fact that the third letter in lp[0] is unique
+            //       for all valid attrs to speed up processing
+
+            switch(*lp[0] ? toupper(lp[0][2]) : 0) {
+              case 'N':   // zone
+                nlst.addr.zone = nlst.addr.net = atow(lp[1]);
+                nlst.addr.node = nlst.addr.point = 0;
+                point = NO;
+                break;
+
+              case 'G':   // Region
+                nlst.addr.net = atow(lp[1]);
+                nlst.addr.node = nlst.addr.point = 0;
+                point = NO;
+                if(nlst.addr.net >= 10000)
+                  continue;
+                break;
+
+              case 'S':   // Host
+                {
+                  nlst.addr.net = atow(lp[1]);
+                  nlst.addr.node = nlst.addr.point = 0;
+                  point = NO;
+                  Addr a;
+                  fast_parse_addr(lp[2],&a);
+                  if(a.net) {                   // Is POINTS24 format ?
+                    nlst.addr.net = a.net;
+                    nlst.addr.node = a.node;
+                    nlst.addr.point = 0;
+                    point = YES;
+                  }
+                }
+                break;
+
+              case 'B':   // Hub
+                nlst.addr.node = atow(lp[1]);
+                nlst.addr.point = 0;
+                point = NO;
+                break;
+
+              case 'I':   // point
+                nlst.addr.point = atow(lp[1]);
+                break;
+
+              case 'T':   // Pvt
+              case 'W':   // Down
+              case 'L':   // Hold
+              default:
+                if(point)
+                  nlst.addr.point = atow(lp[1]);
+                else {
+                  nlst.addr.node = atow(lp[1]);
+                  nlst.addr.point = 0;
+                }
+                break;
+            }
+
+            if(ISTWIRLY(no)) {
+              fast_printf("\r* \\--%-12s     Zone %-5u  Net %-5u  Nodes %6lu", name, nlst.addr.zone, nlst.addr.net, (ulong)no);
+            }
+
+            bool include = true;
+
+            // Check address against the exclude masks
+            for(addr_iter n=excludenode.begin(); n != excludenode.end(); n++) {
+              if(match_addr_mask(&(*n), &nlst.addr)) {
+                include = false;
+                break;
+              }
+            }
+
+            // Check address against the include masks
+            if(not include) {
+              for(addr_iter n=includenode.begin(); n != includenode.end(); n++) {
+                if(match_addr_mask(&(*n), &nlst.addr)) {
+                  include = true;
+                  break;
+                }
+              }
+            }
+
+            if(include) {   // Address was okay
+
+              // Convert name to Goldware standard
+              strxcpy(nlst.name, CvtName(lp[4]), sizeof(nlst.name));
+
+              // Prepare the rest
+              nlst.pos |= ((((dword)realfno) << 24) & 0xFF000000L);
+
+              // Append to end of list
+              nodeidx.push_back(nlst);
+              ++nodes;
+
+              // Count the node
+              no++;
+
+              // Stop if limit is reached
+              if(nodes >= maxnodes)
+                break;
+            }
+          }
+        }
+
+        fast_printf("\r* %c--%-12s   Nodes read: %6lu    Total read: %6lu", fno==nodelist.end()-1?'\\':'|', name, (ulong)no, (ulong)nodes);
+
+        if(nodes >= maxnodes) {
+          fast_printf("  (Limit reached)\n");
+        }
+        else {
+          fast_printf("         \n");
+        }
+
+        fclose(lfp);
+        ++realfno;
+      }
+      else {
+        fast_printf("Error Opening nodelist %s!\n", fno->fn);
+        *(fno->fn) = NUL;
+      }
+    }
+  }
+
+  // Compile userlists
+  if(userlist.size()) {
+    fast_printf("\n* Compiling userlists:\n");
+  }
+
+  for(fno=userlist.begin(), zno=userzone.begin(); fno != userlist.end() and nodes < maxnodes; fno++, zno++) {
+
+    no = 0;
+
+    lfp = fsopen(fno->fn, "rt", sh_mod);
+    if(lfp) {
+
+      setvbuf(lfp, NULL, _IOFBF, 32000);
+
+      name = CleanFilename(fno->fn);
+
+      if(nodes < maxnodes) {
+
+        while(fgets(buf, sizeof(buf), lfp)) {
+
+          // Get node data
+          strbtrim(buf);
+          ptr = buf + strlen(buf) - 1;
+          while(*ptr != ' ')
+            ptr--;
+          nlst.reset();
+          nlst.addr = *zno;
+          fast_parse_addr(ptr+1, &nlst.addr);
+          *ptr = NUL;
+          strbtrim(buf);
+
+          // Convert "lastname, firstname" to "firstname lastname"
+          ptr = strchr(buf, ',');
+          if(ptr) {
+            *ptr++ = NUL;
+            strxmerge(buf2, 100, strskip_wht(ptr), " ", buf, NULL);
+            ptr = buf2;
+          }
+          else {
+            ptr = buf;
+          }
+
+          // Convert name to Goldware standard
+          strxcpy(nlst.name, CvtName(ptr), sizeof(nlst.name));
+
+          bool include = true;
+
+          // Check address against the exclude masks
+          for(addr_iter n=excludenode.begin(); n != excludenode.end(); n++) {
+            if(match_addr_mask(&(*n), &nlst.addr)) {
+              include = false;
+              break;
+            }
+          }
+
+          // Check address against the include masks
+          if(not include) {
+            for(addr_iter n=includenode.begin(); n != includenode.end(); n++) {
+              if(match_addr_mask(&(*n), &nlst.addr)) {
+                include = true;
+                break;
+              }
+            }
+          }
+
+          if(include) {   // Address was okay
+
+            if(ISTWIRLY(nodes))
+              fast_printf("\r* \\--%s: %6lu", name, (ulong)nodes);
+
+            // Indicate userlist
+            nlst.pos = (long)0xFFFFFFFFL;
+
+            // Append to end of list
+            nodeidx.push_back(nlst);
+            ++nodes;
+
+            // Count the node
+            no++;
+
+            // Stop if limit is reached
+            if(nodes >= maxnodes)
+              break;
+          }
+        }
+      }
+
+      fast_printf("\r* %c--%-12s     Nodes read: %6lu    Total read: %6lu", fno==userlist.end()-1?'\\':'|', name, (ulong)no, (ulong)nodes);
+
+      if(nodes >= maxnodes) {
+        fast_printf("  (Limit reached)\n");
+      }
+      else {
+        fast_printf("         \n");
+      }
+
+      fclose(lfp);
+    }
+    else {
+      fast_printf("Error Opening Userlist %s!\n", fno->fn);
+    }
+  }
+
+  #ifdef GOLDNODE_STATS
+  if(make_stats) {
+
+    fast_printf("* Writing statistics to %s\n", statfilename);
+
+    FILE *ofp = fopen(statfilename, "wt");
+    if(ofp) {
+
+      fprintf(ofp, "Nodename size statistics:\n");
+      calc_statistic(ofp, statistic.nodename, nodes);
+
+      fprintf(ofp, "\nLocation size statistics:\n");
+      calc_statistic(ofp, statistic.location, nodes);
+
+      fprintf(ofp, "\nSysopname size statistics:\n");
+      calc_statistic(ofp, statistic.sysopname, nodes);
+
+      fclose(ofp);
+    }
+  }
+  else {
+  #endif
+    // At last, sort the nodes
+    FILE *fp, *fido;
+    geidxlist::iterator curr, prev;
+    map namepos;
+
+    // Sort by name
+    fast_printf("\n* Sorting by name ");
+    nodeidx.sort(cmp_nnlsts);
+
+    // Write the name-sorted .GXN
+    fp = fsopen(nodeindex.c_str(), "wb", sh_mod);
+    if(fp) {
+      name = CleanFilename(nodeindex.c_str());
+      fido = NULL;
+      if(fidouser)
+        fido = fsopen(fidouserlst, "wt", sh_mod);
+      if(fido == NULL) {
+        fast_printf("\b, writing %s ", name);
+        fidouser = false;
+      }
+      else {
+        fast_printf("\b, writing %s and %s ", name, fidouserlst);
+      }
+
+      int nn = 0;
+      dword nodenum = 0;
+      for(prev = nodeidx.end(), curr = nodeidx.begin(); curr != nodeidx.end(); prev = curr++) {
+
+        if(ISTWIRLY(nn++))
+          twirly();
+
+        if(ignoredups) {
+          if(prev != nodeidx.end() && match_addr_mask(&curr->addr, &prev->addr)) {
+            if(strieql(curr->name, prev->name)) {
+              #ifdef DEBUG
+              fast_printf("* Dupe: %d:%d/%d.%d %s\n",curr->addr.zone,curr->addr.net,curr->addr.node,curr->addr.point,curr->name);
+              #endif
+              nodeidx.erase(curr);
+              curr = prev;
+              ++dups;
+              continue;
+            }
+          }
+          fwrite(&(*curr), sizeof(_GEIdx), 1, fp);
+        }
+        else
+          fwrite(&(*curr), sizeof(_GEIdx), 1, fp);
+        namepos[curr->pos] = nodenum++;
+        if(fidouser) {
+          char buf[256];
+          fprintf(fido, "%-36.36s%24.24s\n", curr->name, make_addr_str(buf, &curr->addr, ""));
+        }
+      }
+      if(fido)
+        fclose(fido);
+      fclose(fp);
+    }
+
+    // Sort by address
+    fast_printf(" \n* Sorting by node ");
+    nodeidx.sort(cmp_anlsts);
+
+    // Write the address-sorted .GXA
+    fp = fsopen(addrindex.c_str(), "wb", sh_mod);
+    if(fp) {
+      name = CleanFilename(addrindex.c_str());
+      fast_printf("\b, writing %s ", name);
+      int nn = 0;
+      for(curr = nodeidx.begin(); curr != nodeidx.end(); curr++) {
+        if(ISTWIRLY(nn++))
+          twirly();
+        fwrite(&namepos[curr->pos], sizeof(dword), 1, fp);
+      }
+      fclose(fp);
+    }
+
+    // Write the list index in .GXL
+    fp = fsopen(listindex.c_str(), "wt", sh_mod);
+    if(fp) {
+      name = CleanFilename(listindex.c_str());
+      fast_printf(" \n* Writing %s\n", name);
+      for(fno=nodelist.begin(); fno != nodelist.end(); fno++) {
+        if(*(fno->fn))
+          fprintf(fp, "%s %lu\n", fno->fn, fno->ft);
+      }
+      fclose(fp);
+    }
+
+    // Note compile time
+    runtime = time(NULL) - runtime;
+
+    if(dups) {
+      fast_printf("\n* Total duplicate nodes: %6lu.\n", (ulong)dups);
+    }
+    fast_printf("\n* Nodelist compile completed. Compile time: %lu min, %lu sec.\n", (ulong)(runtime/60), (ulong)(runtime%60));
+  #ifdef GOLDNODE_STATS
+  }
+  #endif
+}
+
+
+//  ------------------------------------------------------------------
+
+static void check_nodelists(bool force) {
+
+  FILE *fp;
+  uint n;
+  int compilen, compileu;
+  static Path buf, newpath;
+
+  // Find newest nodelists
+  for(n=0,compilen=0; nname.c_str()+extpos)) {
+          if(not listdefined or (de->stat_info.st_mtime-listtime > 0)) {
+            listtime = de->stat_info.st_mtime;
+            listdefined = true;
+            strxmerge(nodelist[n].fn, sizeof(Path), f.fullpath(), "/", de->name.c_str(), NULL);
+          }
+        }
+    }
+  }
+
+  // Get timestamps from .GXL file
+  fp = fsopen(listindex.c_str(), "rt", sh_mod);
+  if(fp) {
+    while(fgets(buf, sizeof(buf), fp)) {
+      char* key;
+      char* val=buf;
+      getkeyval(&key, &val);
+      key = strxcpy(newpath, strbtrim(key), sizeof(Path));
+      for(n=0; n 1) {
+      nodelist[n].fc = YES;
+      compilen++;
+    }
+  }
+
+  if(compilen) {
+    fast_printf("* %u new nodelist file%s found.\n", compilen, compilen==1?"":"s");
+  }
+  else if(nodelist.size()) {
+    fast_printf("* The nodelist file%s up-to-date.\n", nodelist.size()==1?" is":"s are");
+  }
+
+  // Check userlists
+  for(n=0,compileu=0; n 1) {
+      userlist[n].fc = YES;
+      compileu++;
+    }
+  }
+
+  if(compileu) {
+    fast_printf("* %u new userlist file%s found.\n", compileu, compileu==1?"":"s");
+  }
+  else if(userlist.size()) {
+    fast_printf("* The userlist file%s up-to-date.\n", userlist.size()==1?" is":"s are");
+  }
+
+  if(force or compilen or compileu)
+    read_nodelists();
+}
+
+
+//  ------------------------------------------------------------------
+
+static void fatal_error(const char* what) {
+
+  fast_printf(what);
+  fast_printf("\n");
+  exit(5);
+}
+
+
+//  ------------------------------------------------------------------
+
+static int do_if(char* val) {
+
+  if(strieql(val, "OS/2") OR strieql(val, "OS2")) {
+    #ifdef __OS2__
+    return true;
+    #else
+    return false;
+    #endif
+  }
+  else if(strieql(val, "NT") OR strieql(val, "W32") OR strieql(val, "WIN32")) {
+    #ifdef __WIN32__
+    return true;
+    #else
+    return false;
+    #endif
+  }
+  else if(strieql(val, "386")) {
+    #if defined(__MSDOS__)
+    return true;
+    #else
+    return false;
+    #endif
+  }
+  else if(strieql(val, "DOS")) {
+    #ifdef __MSDOS__
+    return true;
+    #else
+    return false;
+    #endif
+  }
+  else if(strieql(val, "LINUX") or strieql(val, "UNIX")) {
+    #ifdef __UNIX__
+    return true;
+    #else
+    return false;
+    #endif
+  }
+  else if(strieql(val, "INOS2")) {
+    #if defined(__OS2__)
+    return true;
+    #elif defined(__GNUC__)
+    return false;
+    #else
+    return _osmajor >= 10;
+    #endif
+  }
+  else if(strieql(val, "FIREBIRD")) {
+    return true;
+  }
+  else if(strieql(val, "YES") OR strieql(val, "TRUE") OR strieql(val, "ON"))
+    return true;
+  return atoi(val) != 0;
+}
+
+
+//  ------------------------------------------------------------------
+
+static int parse_config(const char *__configfile, Addr& zoneaddr) {
+
+  FILE* fp;
+  char buf[512];
+  char* ptr;
+  char* key;
+  word crc;
+  char* value;
+  char* value2;
+  int _gotcond,line = 0;
+  static int in_if = NO;
+  static int in_else = NO;
+  static int cond_status = YES;
+
+  fp = fsopen(__configfile, "rt", sh_mod);
+  if(fp) {
+    while(fgets((ptr=buf), sizeof(buf), fp)) {
+      line++;
+      // Replace TABs with SPACEs
+      ptr = strskip_wht(ptr);
+      if(*ptr != ';' and *ptr) {
+        crc=getkeyvalcrc(&key, &ptr);
+        getkeyval(&value, &ptr);
+        getkeyval(&value2, &ptr);
+
+        _gotcond = YES;
+        switch(crc) {
+          case CRC_IF:
+            if(in_if) {
+              fast_printf("* %s: Misplaced IF at line %u. IF's cannot be nested.\n", __configfile, line);
+            }
+            in_if = YES;
+            cond_status = do_if(value);
+            break;
+          case CRC_ELIF:
+          case CRC_ELSEIF:
+            if((not in_if) or in_else) {
+              fast_printf("* %s: Misplaced ELIF/ELSEIF at line %u.\n", __configfile, line);
+            }
+            cond_status = do_if(value);
+            break;
+          case CRC_ELSE:
+            if((not in_if) or in_else) {
+              fast_printf("* %s: Misplaced ELSE at line %u.\n", __configfile, line);
+            }
+            in_else = YES;
+            cond_status ^= YES;
+            break;
+          case CRC_ENDIF:
+            if(not in_if) {
+              fast_printf("* %s: Misplaced ENDIF at line %u.\n", __configfile, line);
+            }
+            in_if = in_else = NO;
+            cond_status = YES;
+            break;
+	  default:
+            _gotcond = NO;
+            break;
+        }
+
+        if((not _gotcond) and cond_status) {
+          switch(crc) {
+            case CRC_NODEPATH:
+              nodepath = value;
+              break;
+            case CRC_ADDRESS:
+            case CRC_AKA:
+              if(not zoneaddr.net) {
+                parse_address(value, &zoneaddr, &zoneaddr);
+                zoneaddr.point = 0;
+              }
+              break;
+            case CRC_NODELIST:
+              {
+                Stamp ndl;
+                Addr ndz;
+
+                if(atoi(value2)) {
+                  parse_address(value2, &ndz, &ndz);
+                  if(ndz.zone == 0) {
+                    ndz.zone  = ndz.node;
+                    ndz.net   = 0;
+                    ndz.node  = 0;
+                  }
+                }
+                else
+                  ndz = zoneaddr;
+                ndz.point = 0;
+                ndl.ft = (dword)-1;
+                ndl.fc = NO;
+                strcpy(ndl.fn, value);
+                nodelist.push_back(ndl);
+                nodezone.push_back(ndz);
+              }
+              break;
+            case CRC_USERLIST:
+              {
+                Stamp ndl;
+                Addr ndz;
+
+                if(atoi(value2)) {
+                  parse_address(value2, &ndz, &ndz);
+                  if(ndz.zone == 0) {
+                    ndz.zone  = ndz.node;
+                    ndz.net   = 0;
+                    ndz.node  = 0;
+                  }
+                }
+                else
+                  ndz = zoneaddr;
+                ndz.point = 0;
+                ndl.ft = (dword)-1;
+                ndl.fc = NO;
+                strcpy(ndl.fn, value);
+                userlist.push_back(ndl);
+                userzone.push_back(ndz);
+              }
+              break;
+            case CRC_EXCLUDENODES:
+              {
+                Addr exn;
+                parse_address(value, &exn, &zoneaddr);
+                excludenode.push_back(exn);
+              }
+              break;
+            case CRC_INCLUDENODES:
+              {
+                Addr inn;
+                parse_address(value, &inn, &zoneaddr);
+                includenode.push_back(inn);
+              }
+              break;
+            case CRC_SHAREMODE:
+              if(atoi(value))
+                sh_mod = atoi(value);
+              else if(striinc("NO", value))
+                sh_mod = 0;
+              break;
+            case CRC_INCLUDE:
+              if(not parse_config(value,zoneaddr))     // NOTE! This is a recursive call!
+                fast_printf("* Could not read configuration file '%s' !\n",value);
+              break;
+	  default:
+              break;
+          }
+        }
+      }
+    }
+
+    fclose(fp);
+    return(YES);
+  }
+  else {
+    return(NO);
+  }
+}
+
+
+//  ------------------------------------------------------------------
+
+static bool ExistCfg(char* path, char* file) {
+
+  bool found = fexist(AddPath(path, file));
+  if(found)
+    strcat(path, file);
+  return found;
+}
+
+
+//  ------------------------------------------------------------------
+
+static bool FindCfg(char* path) {
+
+  bool found = false;
+  
+  if(!is_dir(path)) {
+    if(fexist(path))
+      return true;
+    else
+      return false;
+  }
+  AddBackslash(path);
+  #if defined(__OS2__)
+  found = ExistCfg(path, "ged2.cfg");
+  #elif defined(__WIN32__)
+  found = ExistCfg(path, "gedw32.cfg");
+  #endif
+  if(not found)
+    found = ExistCfg(path, "golded.cfg");
+  return found;
+}
+
+
+//  ------------------------------------------------------------------
+
+static bool read_config(const char *cfg, const char *argv_0) {
+
+  Addr zoneaddr;
+  Path buf;
+
+  bool found = (*cfg != NUL) ? true : false;
+  if(not found) {
+    // Look for configfilename in the environment
+    const char *ptr = getenv("GOLDNODE");
+    #if defined(__OS2__)
+    if(not(ptr and *ptr))
+      ptr = getenv("GED2");
+    #elif defined(__WIN32__)
+    if(not(ptr and *ptr))
+      ptr = getenv("GEDW32");
+    #endif
+    if(not(ptr and *ptr))
+      ptr = getenv("GOLDED");
+    if(not(ptr and *ptr))
+      ptr = getenv("GED");
+    if(ptr and *ptr) {
+      strxcpy(buf, ptr, sizeof(buf));
+      found = FindCfg(buf);
+    }
+
+    // Get it in current directory
+    if(not found) {
+      getcwd(buf, sizeof(buf));
+      found = FindCfg(buf);
+    }
+
+    // Get it where the the .EXE file is
+    if(not found) {
+      extractdirname(buf, argv_0);
+      found = FindCfg(buf);
+
+      // If we still could not find config name...
+      if(not found)
+        strcat(buf, "golded.cfg");
+    }
+  }
+  else
+    strxcpy(buf, cfg, sizeof(Path));
+
+  nodelist.clear();
+  nodezone.clear();
+  userlist.clear();
+  userzone.clear();
+  if(not parse_config(buf, zoneaddr)) {
+    errorlevel = 1;
+    return false;
+  }
+
+  if(nodelist.empty() and userlist.empty() == 0)
+    fatal_error("* Error: No NODELISTs or USERLISTs defined!");
+
+  if(zoneaddr.net == 0)
+    fatal_error("* Error: No ADDRESS or AKAs defined!");
+
+  if(nodepath.empty())
+    nodepath = getcwd(buf, sizeof(buf));
+
+  AddBackslash(nodepath);
+  MakePathname(listindex, nodepath, "goldnode.gxl");
+  MakePathname(nodeindex, nodepath, "goldnode.gxn");
+  MakePathname(addrindex, nodepath, "goldnode.gxa");
+  size_t n;
+  for(n=0; n  Set max size of a name in the index.\n"
+      "               -U  Create sorted FIDOUSER.LST userlist file.\n"
+      #ifdef GOLDNODE_STATS
+      "               -T        Make statistics.\n"
+      #endif
+      ""
+      "[configfile] =           The path AND filename of GOLDED.CFG\n"
+      "                         configuration file to read.\n"
+      "\n",
+      CleanFilename(argv[0])
+    );
+  }
+  else {
+
+    if(force)
+      fast_printf("* Forced compile.\n");
+
+    if(read_config(cfg, argv[0])) {
+      if(force or conditional)
+        check_nodelists(force);
+    }
+    else {
+      fast_printf("\nCould not find the configuration file!\n");
+    }
+  }
+}
+
+
+//  ------------------------------------------------------------------
+
+int main(int argc, char *argv[]) {
+
+  throw_init();
+
+  // set locale
+  setlocale(LC_CTYPE, "");
+  #if defined(GUTLOS_FUNCS)
+  g_init_os(0);
+  #endif
+
+  #ifdef GOLDNODE_STATS
+  memset(&statistic, 0, sizeof(nl_stat));
+  #endif
+
+  run_gn(argc, argv);
+
+  #if defined(GUTLOS_FUNCS)
+  g_deinit_os();
+  #endif
+
+  THROW_CHECK();
+
+  return errorlevel;
+}
+
+
+//  ------------------------------------------------------------------
diff --git a/manuals/gold_ref.tei b/manuals/gold_ref.tei
new file mode 100644
index 0000000..271cd19
--- /dev/null
+++ b/manuals/gold_ref.tei
@@ -0,0 +1,10418 @@
+
+
+
+
+  
+    
+      
+        
+          GoldED+ Reference Manual
+        
+      
+      
+        

+ Created in electronic form. +

+
+
+ + + + English + + + +
+ + + + + + + + GoldED+ + + + Reference Manual + + + + Odinn Sorensen, Dirk A. Mueller, Alexander S. Aganichev and others + + + 1990-1999 + + + + + + + + + + Commandline Reference + + + + Commandline syntax + +

+ Invocation: GoldED [options] [keystacking] + +

+

+ Depending on used platform GoldED+ could be called + geddjg, gedcyg, gedemx, or + gedlnx. Available options are: + + + + Displays a help screen with all available commandline options. + + + + Specifies another configuration file than the default + GOLDED.CFG. + + + + Disable old configuration keywords. For backward compatibility, + GoldED+ still supports a number of old names for + some configuration keywords. I recommend that you use + -D sometimes and rename the keywords that are + reported as unknown. + + + + If specified, GoldED+ starts directly in the + specified echo, bypassing the arealist screen. See the + AREASTART configuration + keyword for more info. + + + + Calls the SOUP packet export feature during the + startup phase. This is the same as starting it from the + areascan SOUP Packet->Export menu item. The + SOUP export happens immediately after the regular + startup area scanning (if that is enabled) and after + SOUP import. + + + + Force recompile of most configuration files, but not all. Does not + recompile the *.CHS files. + + + + Force complete recompile of all configuration files, regardless of + whether they are up-to-date or not. This is equivalent to deleting + all the *.GE? files. + + + + Same as option -?. + + + + Start the quick install procedure. You should give a path to your + other mail software if it cannot be found using environment + variables or in current directory. + + + + Calls the SOUP packet import feature during the + startup phase. This is the same as starting it from the areascan + SOUP Packet->Import menu item. The + SOUP import happens immediately after the regular + startup area scanning (if that is enabled). + + + + Mute. Disables all sounds in GoldED+. + + + + No share. If used, this prevents GoldED+ from using + SHARE compatible file-open calls, which are used by + default. Works only until the + SHAREMODE keyword is used in + GOLDED.CFG. This keyword is normally not useful, but + may be used to debug your setup or something. + + + + Disable the automatic startup area scanning (if that is enabled). + This is useful for automated SOUP import/export in a + batch file. For example, -noscan -importsoup @x + y imports SOUP then exits. + + + + Since it seems that increasing the thread priority for the + Win32 version is a mixed blessing, the default is now + to not increase the priority. From other side + OS/2 version runned with reduced priority by default. + This option increases the priority (Win32 and + OS/2 only). + + + + Quiet. Turns off verbose config compile. On by default. This could + be used on the commandline to disable a -V option in + the GEDCMD environment variable. + + + + Sort all areas according to <sortspec>. See + the AREALISTSORT config + keyword for details. + + + + Set the timeout value. A value of zero (0) means never timeout. + See the TIMEOUT config keyword + for details. + + + + Turns on verbose config compile. When used, GoldED+ + will display the full filename of each main config file it + compiles. It also displays the name of the detected multitasker, if + any. This can be useful for debugging your setup, and see if + GoldED+ accesses the files (especially the + AREAFILE's) it is + supposed to. + + + + Same as -V, but also displays all the active lines + while compiling. This could be used to find the exact spot if it + crashes or stops while compiling. + + + + If used, GoldED+ will create (and overwrite if + existing) the file GOLDAREA.INC, which will then + contain all areas in the AREADEF form, sorted by your + AREALISTSORT specification. This is very useful for + converting your AREAFILE's to a form you can edit with + your favorite text editor and use in GoldED+. It is + also useful if you have used the new AREADESC keyword or + the AREAFILE EchoList reader. The + GOLDAREA.INC file (created in the + GOLDPATH) can be used by adding INCLUDE + GOLDAREA.INC to your GOLDED.CFG or + GOLDAREA.CFG. When creating the file, + GoldED+ will use . if an aka is the same as + the main aka, and leave out the optional origin if it's the same + as the first ORIGIN in your GOLDED.CFG. + This makes it easier to share the same GOLDAREA.INC + between different setups. + + + + Reserved for debugging purposes. + + + + Reserved for debugging purposes. + + + + Reserved for debugging purposes. + + +

+
+ + + Commandline keystacking + +

+ Any non-option characters on the commandline are stuffed into the + keyboard buffer. See the chapter on keyboard definition and the + KEYBSTACK keyword for more info. +

+

+ Example: +GOLDED @S A +

+

+ Makes GoldED+ go to the area scanning menu <Alt-S>, + and select scanning of <A> all areas. +

+

+ See the chapter for more info. +

+
+
+ + + + Environment Variables + +

+ These are the GoldED+ specific environment variables: + + + + Path to the GOLDED.CFG file. It is recommended to set + this variable, but don't forget to change it if you move your + GoldED+ setup to a different directory! + + + + Specifies additional commandline options. Use this if you want to + specify options, but need to run GoldED without them + (for example when renaming GOLDED.EXE to + DBEDIT.EXE in older versions of D'Bridge). + You can override the environment options with commandline options. + + + + The path where GoldNODE can find a + GOLDED.CFG to use. + + +

+

+ When the using AREAFILE feature to read external area + configuration from other programs, the individual AREAFILE's + may use specific environment variables to find the files. Please read + the chapter for specific details of each + supported AREAFILE. +

+
+ + + + Batchfile Errorlevels + +

+ For operation in batch files, GoldED+ has a set of + errorlevel values: + + + + 032 or higher + + + Error exit (check the logfile for details). + + + + + 004 + + + Echomail entered. + + + + + 002 + + + Netmail entered. + + + + + 001 + + + Local mail entered. + + + + + 000 + + + No errors. No mail entered. + + +
+

+

+ Add values together to find the combined error levels. For example, error + level 6 is returned if netmail and echomail (2+4) was entered. +

+

+ Example of RUNGOLD.BAT or RUNGOLD.CMD file: +@echo off +golded.exe +rem ged386.exe +rem ged2.exe +if errorlevel 008 goto error +if errorlevel 007 goto e_n_l +if errorlevel 006 goto e_n__ +if errorlevel 005 goto e___l +if errorlevel 004 goto e____ +if errorlevel 003 goto __n_l +if errorlevel 002 goto __n__ +if errorlevel 001 goto ____l +goto nomail +:error + echo GoldED+ error exit! + goto end +:e_n_l + echo **** New echo, net and local mail entered. + goto end +:e_n__ + echo **** New echo and netmail entered. + goto end +:e___l + echo **** New echo and local mail entered. + goto end +:e____ + echo **** New echomail entered. + goto end +:__n_l + echo **** New net and local mail entered. + goto end +:__n__ + echo **** New netmail entered. + goto end +:____l + echo **** New local mail entered. + goto end +:nomail + echo **** No new mail entered. +:end + echo. + echo Thank you for using GoldED+! :-) +

+
+ + + + Nodelist and Userlist Support + +

+ GoldED+ supports the FrontDoor, + Version 7(+) nodelist indexes as well as a plain + FIDOUSER.LST. However, if you run software that doesn't use + any of these formats, you may want to use GoldED+'s own + nodelist index. This chapter describes how to do that. +

+

+ In order to enable nodelist/userlist lookup and browsing, + GoldED+ needs to use a set of special nodelist index files, + created by the GoldNODE nodelist compiler. +

+

+ GoldED+ normally uses and displays information from the + nodelist when browsing, but it doesn't really need the nodelist for + anything. The index files contains sufficient information for lookup and + browsing of names or addresses. This means that you can delete or pack + away the nodelists and/or userlists after compiling with + GoldNODE, if you want to save space and you don't need them + for anything else. +

+ + + GoldNODE commandline syntax + +

+ Invocation: GoldNODE [-options] + [configfile] +

+

+ Depending on used platform GoldNODE could be called + gndjg, gncyg, gnemx, or + gnlnx. Available options: + + + + Conditional compile. + + + + Remove duplicate nodes from index. + + + + Forced compile. + + + + Quite compiled. No screen output improves speed. + + + + Set the max size of names. Normally not used. + + + + Create sorted FIDOUSER.LST userlist file. + + +

+

+ The [configfile] is the path and filename of the + GOLDED.CFG configuration file to read. If no filename is + given, the path specified with the GOLDNODE or + GOLDED environment variables are used. +

+

+ The nodelist index files are named GOLDNODE.GX? are are + placed in the path pointed to by the NODEPATH keyword. +

+

+ The V7+ is automatically used if your NODEPATHV7 + is set correctly. If GoldED+ shows xxxx / + NODEX.DTP at the bottom of the browser window, the displayed + information is taken from the raw nodelist entry, taken from the + V7+ index. +

+

+ GoldNODE can handle up to 45 nodelists and 10 userlists. + GoldNODE can read the german POINTS24-format + directly! +

+

+ NOTE: If you use the EXCLUDENODES and + INCLUDENODES keywords, please note that the + <addressmask> does not accept ALL or WORLD + etc. You must use wildcard * instead. +

+
+
+ + + + Routing Diagram Drawing Tool + +

+ Routing diagram drawing tool intended to analyse files created by + pressing key defined for READmakepathreport action. + RDDT builds routing tree and display it on the screen if + requested. +

+

+ Invocation: RDDT <routefile> [-options] + [address or name] +

+

+ Depending on used platform RDDT could be called + rddtdjg, rddtcyg, rddtemx, or + rddtlnx. Available options: + + + + Reserved for debugging purposes. + + + + Sets indent to <n>. + + + + This option used to specify yours link address. Requires option + -N. + + + + Use this option to specify your address. + + + + Decode path. + + +

+

+ Example: +RDDT path.rpt -n2:5020/604.19 -l2:5020/604 2:5020/604.19 -p +

+
+ + + + Configuration Control + +

+ The GOLDED.CFG configuration reader can be directed in + several ways with special keywords: +

+ + + Conditionals + +

+ + IF <condition> + ELIF <condition> + ELSEIF <condition> + ELSE + ENDIF + +

+

+ These control keywords can be used to setup sections of configuration + which enable different sets of keywords depending on which version + that is used. +

+

+ The following conditions can be used: + + + + DOS, 386 + + + true, if DPMI32 version is used + + + + + OS2 + + + true, if OS/2 version is used + + + + + W32 + + + true, if Win32 version is used + + + + + Linux, UNIX + + + true, if Linux version is used + + + + + Firebird + + + true, if GoldED 3.xx or GoldED+ is used + + + + + ASA + + + true, if GoldED-asa or GoldED+ is used + + + + + Yes, True, On + + + always true + + +
+

+

+ Example: +IF OS2 + EDITOR c:\qedit\os2\q.exe @file -n@line + EDITSPELLCHECK c:\os2\cmd.exe /c c:\ss\ss.exe @file +ELIF DOS + EDITOR c:\qedit\dos\q.exe @file -n@line + EDITSPELLCHECK c:\ss\ss.exe @file +ENDIF +

+
+ + + IGNORE + +

+ This tells the configuration file reader to ignore all subsequent lines + until another IGNORE keyword is encountered. Useful for + testing and quickly switching portions of configuration. +

+

+ However it is probably more useful to use the + IF/ELIF/ENDIF control keywords. +

+
+ + + INCLUDE <file> + +

+ This tells the configuration file reader to stop reading the current + .CFG file, and start reading the + <file> as an extra configuration file, then + resume reading the previous .CFG. The INCLUDE + filenames are stored and their timestamps are checked when + GoldED+ is started. INCLUDE files can be nested + without limit. +

+
+ + + REM + +

+ Signifies a remark (comment) line. The line is ignored. +

+

+ Any non-alphabetic non-whitespace character at the beginning of a line + makes the line a comment. Example: +; This is a comment +% This is a comment +* This is a comment +// This is a comment +/* This is a comment */ +

+

+ By tradition, the semicolon is the standard comment character. The + semicolon (and only that) can also be used to add a comment at the end + of a configuration line. Example: +ADDRESS 2:236/77 ; Main address. +AKA 2:236/77.1 ; SysOp point. +

+
+
+ + + + Configuration Keyword Reference + +

+ This is an alphabetical list of all the configuration keywords that can + be used in the main GoldED+ configuration file + (GOLDED.CFG and any file included from it). It also lists + and documents the keywords that are specific to the Random System groups. +

+

+ The following special symbols are used in the keyword parameter lists: + + + + () + + + Default value. + + + + + [] + + + Optional parameter. + + + + + <> + + + Required parameter, not optional. + + + + + + + + Parameter must be inclosed in quotes. + + + + + / + + + Separates mutually exclusive values. + + + + + , + + + Separates possible values for the keyword. + + +
+

+

+ Here is the complete keyword list: +

+ + + ADDRESS <zone:net/node[.point][@domain][, + pointnet]> + +

+ Your network address, FidoNet-style. More than one + address can be specified if you are member of more than one network. + The keywords ADDRESS and AKA can be used + interchangeably. +

+

+ If a pointnet is specified with a point address, GoldED+ + will use the so-called 3D addressing method in netmail + msgs, otherwise the 4D method is used. The + 3D method works by putting the address + zone:pointnet/point.0 in the msg header, instead of the + 4D format zone:net/node.point. Most modern + mailers and mail processors now supports the 4D format, + but if you are a point, you should always consult your boss about + which format to use. +

+

+ The optional @domain part can be used to specify a + fifth dimension to the 4D address. It is + normally not necessary to specify a domain. Domains are never shown in + the header and are not put in the origin line. The only place the + domain is used/added by GoldED+ is in the MSGID + kludge. +

+

+ Examples: +ADDRESS 2:236/77 ; Node address +ADDRESS 2:236/77.1 ; Point address (4D) +ADDRESS 2:236/77.1, 16077 ; Point address (3D) +ADDRESS 2:236/77@fidonet ; Node address with domain +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + ADDRESSBOOKADD <(yes)/no/always> + +

+ Setting this keyword to always means that + GoldED+ will always add unknown addressees to the + addressbook when writing new or quoted mails automatically. If you set + the value to yes, GoldED+ will add them + only if it's a netmail/email. ADDRESSBOOKADD NO disables + this feature entirely. +

+

+ NOTE that GoldED+ won't add unknown users if their name match + one of the following criteria: + + + it's a USERNAME + + + it's a ROBOTNAME + + + it's the WHOTO + + + it's the mailinglist's sender address + + + it's already an email address + + + address/aka is unknown + + +

+
+ + + ADDRESSLOOKUPFIRST <MsgID/(Origin)> + +

+ By default address of sender taken from Origin line. If this + keyword set to MsgID then GoldED+ looks + for correct FTN address in MSGID kludge first. +

+
+ + + ADDRESSMACRO <macro>, <name>, <address> + [,subject] [,attribs] + +

+ Defines a short name for often used addresses. Typical uses are for + AreaFix/AreaMgr, your uplink, boss, points + or others you write to often. To use a defined address macro, you just + type it in the To: name field. +

+

+ If (and only if) the subject is enclosed in quotes ( + or ''), GoldED+ will look for message attributes after + the subject. See the for a valid attribute. + You cannot have quotes within quotes (not the same type anyway). +

+

+ The attribues are added to the ones already there, they do + not replace them. +

+

+ Examples: +

+

+ A special format is supported for UUCP or + Internet gateways. The special format is indicated with a + @ as the first character in the <name>: +ADDRESSMACRO jfu,@fallesen@diku.dk,2:310/33 +ADDRESSMACRO dn,@INTERNET/david@csource.oz.au,2:241/999 +

+

+ In the first example, GoldED+ will put UUCP (the + default gateway name) in the To: message header field and + To: fallesen@diku.dk on the first line of the message text. +

+

+ In the second example, GoldED+ will put INTERNET + in the To: field, and To: david@csource.oz.au in the + message. The forward slash (/) separates the gateway name from + the addressee. Any gateway name may be used. +

+

+ The address macros can also be specified in an external file, like the + NAMES.FD file supported by the FrontDoor + mailer/editor and Maximus BBS. See the + keyword NAMESFILE for details. However, you should not use + the syntax with the attributes in the NAMES.FD file, + because FrontDoor and Maximus do not know + this syntax. +

+
+ + + ADEPTXBBSPATH <path> + +

+ The path where you keep your AdeptXBBS. +

+
+ + + ADEPTXBBSUSERNO <userno> + +

+ By default GoldED+ will use the first record in the + userfile and lastreads. If you are not the first user in the userfile, + or are sharing the messagebase with other GoldED+ users, + you must either set this keyword to -1, or use a different number for + each user. Each user must be defined in the userbase. +

+
+ + + AKA <zone:net/node[.point][@domain][, + pointnet]> + +

+ AKA (Also Known As) is an alias for the + ADDRESS keyword. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + AKAMATCH <match> <aka> + +

+ This is an enhancement of the existing aka matching logic, which in + some circumstances fails to find the correct aka. +

+

+ Example: Lets say that zone 21, 22 and 23 are part of the same + network, and that you have an aka in zone 22. You would put something + like this in your setup: +ADDRESS 2:236/77 +AKA 22:33/44 +

+

+ In this case, if a mail comes in from zone 23, the normal aka matching + logic would fail, because it does not try to guess the correct zone. + To the rescue comes this keyword. You can add this to your setup: +AKAMATCH 21:*/*.* 22:33/44 +AKAMATCH 23:*/*.* 22:33/44 +

+

+ It tells GoldED+ that any mail from zone 21 or 23 matches + your zone 22 aka. Note the use of wildcards here. Wildcards are not + strictly necessary, you could also have just written 23: or + 23:*. +

+

+ When an address does not match any AKAMATCH definition, the + normal aka matching logic takes over. +

+
+ + + AKAMATCHECHO <yes/(no)> + +

+ If enabled, GoldED+ will attempt to match one of your akas to the + address of the person you are replying to in echomail areas. +

+

+ Normally it is not desirable to enable aka matching in echomail, + because some echoes may be restricted to members of one particular + network, and an accidental wrong aka matching may attract unwanted + attention from the moderator or the compulsive flamers :-) +

+
+ + + AKAMATCHING <yes/no> + +

+ This keyword is only valid in the Random System groups. When used, it + overrides any global AKAMATCHNET, AKAMATCHECHO or + AKAMATCHLOCAL you may have. +

+
+ + + AKAMATCHLOCAL <yes/(no)> + +

+ If enabled, GoldED+ will attempt to match one of your akas + to the address of the person you are replying to in local areas. +

+

+ It doesn't really make sense to do aka matching in local areas. The + keyword is just there for completeness. +

+
+ + + AKAMATCHNET <(yes)/no> + +

+ If enabled, GoldED+ will attempt to match one of your akas + to the address of the person you are replying to in netmail areas. This + is especially useful if you are a member in more than one network, and + therefore have more than one address. +

+
+ + + APP <programname> [keyword and/or parameters] + +

+ This is a way for other programs to place configuration data in + GoldED+'s configuration file. +

+

+ For example, if a program named OtherProg wants to read + its configuration from GOLDED.CFG, here is how it might + look: +APP OtherProg REGKEY xyaxajlsaduoiweqeq +APP OtherProg IRQ 5 +

+

+ GoldED+ itself will ignore APP lines just like + REM lines. +

+
+ + + AREA <echoid> <desc> <msgbase>[type] + <location> [akano] [attrs] + +

+ This keyword defines a mail area in GoldED+. You need to + define at least one mail area to run GoldED+, or use the + AREAFILE keyword to read the area setup of your mailer, mail + processor or BBS. +

+

+ + + + echoid + + + Mail area identifier. + + + + + desc + + + Area description in () quotes. + + + + + msgbase + + + O(Opus *.MSG), + S(FTS-0001 *.MSG), + Q(QuickBBS), R(RemoteAccess), + H(Hudson), M(Squish), + J(JAM), E(Ezycom), + G(Goldbase), P(PCBoard), + X(AdeptXBBS), W(WildCat!). + + + + + type + + + N(Netmail), E(Echomail), L(Local). + + + + + location + + + Directory path/file or Hudson board number. + + + + + akano + + + AKA number (starting from 0) + + + + + attrs + + + R/O(Read-Only), and/or other attributes. + + +
+ O(Opus) are *.MSG files with binary + date/time stamps. S(FTS-0001) are + *.MSG files, but with zone/point header fields. + Q(QuickBBS), R(RemoteAccess) + and H(Hudson) are synonyms. + M(Squish) is the Squish format. + E(Ezycom) is the Ezycom format. + J(JAM) is the JAM format. + G(Goldbase) is the Goldbase format. + P(PCBoard) is the PCBoard format. + X(AdeptXBBS) is the AdeptXBBS format. + W(WildCat!) is the WildCat! 4.x + format. +

+

+ GoldED+ can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path is + defined as %MAIL%\path\name, and + SET MAIL=C:\POINT is in AUTOEXEC.BAT (or + whatever), then GoldED+ translates the path to + C:\POINT\path\name. +

+

+ NOTE that the translation is done at config compile time, so + if you change the environment variable and haven't changed anything + else that would cause GoldED+ to recompile it's config, + you must force it with the -F or -FF command + parameter. +

+

+ It is recommended to use the newer AREADEF + keyword, which allows more detailed mail area setup. +

+
+ + + AREAAUTOID <(verbose)/long/short> + +

+ Defines how an automatically created echoid should look, when + AREAFILE finds an area without an echoid. +

+

+ When the verbose option is used, the echoid is given a + name similar to the function of the area, such as NETMAIL, + NET_SENT, ECHO_BAD, ECHO_DUPES and so on. +

+

+ When the long option is used, the echoids are numbered + sequentially like this: NETMAILxxx, ECHOMAILxxx and + LOCALxxx. This is how it worked in older versions of + GoldED (including 2.42.gamma). +

+

+ When the short option is used, the echoids are numbered + sequentially like this: NETxxx, ECHOxxx and + LOCALxxx. This is how it worked in GoldED + 2.50.beta until B1016. +

+
+ + + AREAAUTONEXT <(yes)/no> + +

+ If enabled, GoldED+ will automatically jump to the first + marked area in the arealist on startup, and the next marked area after + exiting from an area you have been reading. +

+
+ + + AREACATCHUPREAD <(yes)/no> + +

+ If enabled, GoldED+ will set all skipped messages to + read when using AREAcatchup in the arealist-screen. + This implies that HIGHLIGHTUNREAD YES is used, otherwise + it has no function. +

+
+ + + AREACOPYADDID <yes/(no)> + +

+ If enabled, GoldED+ will insert the control line + AREA:<OriginalEchoID> at the top of each message that is + copied or moved. This can be a help when regularly copying messages to + a THE_SAFE type area. +

+

+ This keyword can and should only be used in the Random System groups. +

+

+ It is useful if you copy echomails to some local archive areas. In this + case GoldED+ can add the + AREA:<OriginalEchoID>-kludge to inform you from where you + copied the mail to. +

+
+ + + AREACOPYDIRECT <yes/(no)> + +

+ If enabled, the destination area selection list is bypassed, thereby + making possible a seamless copy/move to the default destination + area. The destination area should be set with AREACOPYTO. +

+

+ This keyword can be used globally and in a Random System group. +

+

+ NOTE: It is probably not a good idea to enable this keyword + globally. +

+
+ + + AREACOPYTO <echoid> + +

+ Sets the default area for the Copy/Move functions. Typically you could + set it to a safe/permanent storage type of area, for example a + JOKES2KEEP or THE_SAFE area. Note that the Forward + function uses the AREAREPLYTO area instead. +

+

+ This keyword can be used globally and in a Random System Group. +

+

+ Related keywords: AREAFREQTO, + AREAREPLYTO. +

+
+ + + AREADEF <setup> + +

+ This is newer version of the AREA keyword, with more detailed + parameters. +

+

+ The full syntax is (must be all on one line): +

+

+ AREADEF <echoid> <> <group> + <type> <msgbase> <path/board> <aka> + <(attrs)> [] + + + + echoid + + + Mail area identifier. + + + + + + + + Area description in quotes. + + + + + group + + + Groupid uppercase letter (A-Z) or 0 if not in a group. Use + #groupnumber to specify group numbers in the 1-999 range, + for example: #117. + + + + + type + + + Net, Echo, Local, EMail or News. + + + + + msgbase + + + Opus, FTS1, Hudson, + Squish, Ezycom, JAM, + Goldbase or PCBoard. + + + + + path/board + + + Area path, boardnumber or base filename. + + + + + aka + + + AKA address for the area, or . for main + AKA. + + + + + (attrs) + + + Default attributes in brackets. + + + + + + + + Optional default origin in quotes. + + +
+

+

+ This looks a lot like the AREA keyword. Additional parameters are + the group, the verbose type and + msgbase, the fully specified aka + address, the brackets for the attributes and the optional + origin. +

+

+ Note the possibility of using . to specify the main + AKA. This, and the optional default origin, makes it + simpler to create a common INCLUDE'able area configuration + for several setups with different addresses, for example two people + sharing the same msgbase. +

+

+ GoldED+ can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path is + defined as %MAIL%\path\name, and + SET MAIL=C:\POINT is in AUTOEXEC.BAT (or + whatever), then GoldED+ translates the path to + C:\POINT\path\name. +

+

+ NOTE that the translation is done at config compile time, so + if you change the environment variable and haven't changed anything + else that would cause GoldED+ to recompile it's config, + you must force it with the -F or -FF command + parameter. +

+
+ + + AREADESC <echoid> <desc> [group] + [aka] [(attrs)] [origin] + +

+ Adds a description and optionally a group letter, AKA, + attributes and origin to an existing (previously defined) + area. This is useful if you use an AREAFILE that does not + contain descriptions, groups, akas, attributes or origins. +

+

+ + + + echoid + + + Mail area identifier. + + + + + + + + Area description in quotes. + + + + + group + + + Optional groupid uppercase letter (A-Z) or 0 if not in a group. + Use #groupnumber to specify group numbers in the 1-999 range + or - to keep the existing groupid. + + + + + aka + + + Optional AKA address for the area, or . for + main AKA, or - to keep the existing + AKA. + + + + + (attrs) + + + Optional default attributes in brackets, - to keep the + existing attributes. Note that if they are specified, they are + added to the default net/echo/local attributes. + + + + + + + + Optional default origin in quotes. + + +
+

+

+ NOTE that you cannot skip any of the optional parts in the + middle, even if you only want to set, say, an origin. Use - to + keep the existing value for the parts you skip. +

+
+ + + AREAEXCL <echoid mask> + +

+ With this keyword, you can define the echoids of areas which should be + ignored by GoldED+ (thereby leaving them out of the + arealist). This is normally used in connection with AREAFILE, + to exclude areas you are not interested in reading. + DOS/4DOS-style wildcards (* and ?) can be + used in the echoid mask. +

+

+ Examples: +AREAEXCL * ; Excludes all areas. +AREAEXCL *INTER* ; Excludes all areas containing INTER anywhere in the + ; echoid. +AREAEXCL INT*.* ; Excludes all areas beginning with INT and + ; containing a dot anywhere in the echoid. +

+

+ You can use the AREAINCL keyword to reinclude areas which have + been excluded with AREAEXCL. +

+

+ NOTE that this keyword must be placed before any of + AREA, AREADEF or AREAFILE keywords. +

+
+ + + AREAFILE <type> [path/file] [switches] + +

+ GoldED+ can read the area setup of many popular mailers, + mail processors and BBS'es, thereby making it much easier + and simpler to configure GoldED+ for the mail areas you + receive, by eliminating the need to write AREA lines for all + or most of your areas. +

+

+ + + + type + + + Name of the program. + + + + + path/file + + + Filename or path to the area setup files. + + + + + switches + + + Msgbase specific switches. + + +
+

+

+ For most programs, GoldED+ can automatically find the path + or filename using environment variables. By default, + GoldED+ will look for the area setup files in the + AREAPATH. +

+

+ There are switches for sorting the areas, and for turning off an + update-check when GoldED+ starts up. +

+

+ GoldED+ can handle enviroment variables correctly in paths + specified in connection with this keyword. +

+

+ This keyword is explained in greater detail in the + chapter. +

+
+ + + AREAFILEGROUPS <(yes)/no> + +

+ In some AREAFILE setups, you can groups the areas using single + letters (A-Z) or numbers (#1-999). If this keyword is enabled, + GoldED+ will use the area groupid instead of the area + echoid when gathering area specific information from the Random System. +

+

+ See chapter for details. +

+
+ + + AREAFREQDIRECT <yes/(no)> + +

+ If enabled, the destination area selection list is bypassed, thereby + making possible a seamless file request in the default + destination area. The destination area should be set with + AREAFREQTO. +

+

+ TIP: If you (like most) only have one mailer netmail area, + you should enable the AREAFREQDIRECT keyword globally for + simpler file requests. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + AREAFREQTO <echoid(first netmail area)> + +

+ Sets the default area for the filerequest function. You should set + this to the netmail area where you normally put the filerequest + messages. +

+

+ Note that if AREAFREQTO is not specified, it defaults to the + first netmail area found. +

+

+ This keyword can be used globally and in a Random System group. +

+

+ Related keywords: AREACOPYTO, + AREAREPLYTO. +

+
+ + + AREAINCL <echoid mask> + +

+ With this keyword, you can define the echoids of areas which should be + reincluded by GoldED+, if they have been excluded with the + AREAEXCL keyword. DOS/4DOS-style + wildcards (* and ?) can be used in the echoid mask. +

+

+ Examples: +AREAINCL * ; Includes all areas. +AREAINCL *INTER* ; Includes all areas containing INTER anywhere in the + ; echoid. +AREAINCL INT*.* ; Includes all areas beginning with INT and + ; containing a dot anywhere in the echoid. +

+

+ You can use the AREAINCL keyword to reinclude areas which have + been excluded with AREAEXCL. +

+

+ NOTE that this keyword must be placed before any of + AREA, AREADEF or AREAFILE keywords. +

+
+ + + AREAISEMAIL <echoid> + +

+ Wildcards * and ? are allowed. These keyword is designed to mark areas + which are read from an AREAFILE as Internet + e-mail. This may be necessary in some cases to enable the + Internet specific features without having to manually + define all Internet areas. +

+

+ Examples: +AREAISEMAIL alt.*, rec.*, sci.* +

+
+ + + AREAISNEWS <echoid> + +

+ For Internet news areas. See + AREAISEMAIL for details. +

+
+ + + AREAKEEPLAST <(yes)/no> + +

+ If enabled, GoldED+ will write the file + GOLDLAST.LST in the GOLDPATH at exit and read + it back when run next time. The contents of the file is a list of + lastread information for each area as it was at last scan. +

+

+ This feature is helpful when you know that there have not been tossed + new mail and don't want to wait for a full msgbase scan. Now you can + just hit ESC at the startup screen to abort the area scan and + GoldED+ will put up the lastread info from the previous + session. +

+

+ It also makes the new mail since last scan feature even better, + because the new mail marker now shows which areas that have new mail + since last session even when scanning areas at startup. +

+

+ GoldED+ only writes the GOLDLAST.LST file at + exit if it survived the initial startup scan. +

+
+ + + AREALISTECHOMAX <size=0> + +

+ Allows you to specify a fixed or dynamically sized width of the + EchoID column in the arealist. +

+

+ If a negative value is specified, the width will be the that of the + widest echoid in the arealist plus the negative value. This might be + useful if some long-name echoes have uninteresting ends, such as + VERYLONGECHOID_R23.PUB (could benefit from a size + of -7). There is currently no provision for long echoids with common + beginning. +

+

+ The arealist can dynamically resize the EchoID and + Description columns, so that long echoids are not cut off. The + sizing of the EchoID column is done against the + Description column, which thereby looses or gains width. +

+
+ + + AREALISTFORMAT <string=AM D CPUN E G > + +

+ The arealist column layout is configurable. This keyword allows you to + change the layout to whatever you like. +

+

+ The default is: +

+

+ This produces the usual layout. Here is another: +

+

+ This one puts the echoid in front and eliminates the area numbers. +

+

+ The letters stand for the following: + + + + Letter + + + Meaning + + + Default width + + + + + A + + + Area number + + + 4 + + + + + M + + + Marked + + + 1 + + + + + D + + + Description + + + Dynamic + + + + + C + + + Number of messages + + + 6 + + + + + P + + + Personal mail mark ('+') + + + 1 + + + + + U + + + Number of unread/new messages + + + 6 + + + + + N + + + Changed since last scan mark (*) + + + 1 + + + + + E + + + Echoid + + + AREALISTECHOMAX + + + + + G + + + Groupid + + + Dynamic: 0, 1 or 3 + + +
+

+

+ You can also specify widths if you don't like the defaults: + + In this example, the Msgs and New columns are put back + to the size they had in old days. +

+

+ If you leave out a letter, that column will not be shown. +

+

+ Use only the defined letters. Use spaces to specify required space + between columns. Use only positive numbers for widths. Failure to + obey these rules may cause undocumented behaviour. +

+
+ + + AREALISTGROUPID <(yes)/no> + +

+ If enabled, the arealist screen will display the groupid letters, if + any, in a column to the right of the EchoID column. If a groupid + is not a letter in the range A-Z (a value in the range + #65-#90), the groupid is not shown. +

+
+ + + AREALISTNOS <yes/(no)> + +

+ If enabled, GoldED+ will display the board numbers of + Hudson areas in the arealist instead of the default + sequential numbers. +

+
+ + + AREALISTPAGEBAR <(yes)/no> + +

+ Enables or disables a pagebar (scrollbar) in the arealist. +

+
+ + + AREALISTSCAN <L menu text> + [path]<filename> [-delete]] + +

+ This keyword allows you to define additional menu items for the + arealist scanning menus (<Alt-S> or <Alt-P>). +

+

+ The first two characters of the menu text are the hotkey letter + that will be highlighted in the menu text, plus a space. +

+

+ The filename specifies a plain text file, with the echoids (wildcards + allowed) of the areas you want to scan when the menu item is selected. + There can be several echoids on each line in the file. If no path is + given, the file is loaded from the GOLDPATH. +

+

+ The -delete option will cause GoldED+ to + delete the list file after scanning the areas in it. For example, if + your mail processor generates a list of the areas that it tossed new + mail to, you could add the list as a menu item on the scanning menu and + use it to scan only those areas with new mail. Note that some mail + processors automatically delete their list after using it for + replylinking. You may want to do some creative stuff with batchfiles to + grab a copy. +

+

+ Examples: +

+

+ +=== Cut, NEWSGRPS.LST === +ALT.*, COMP.*, MISC.*, NEWS.* +REC.*, SOC.*, SCI.*, TALK.* +=== Cut === +

+

+ +=== Cut from an import batchfile === +gecho mgr toss pack -tossbad +if exist import.jam type import.jam >>import.all +if exist import.hmb type import.hmb >>import.all +if exist import.sdm type import.sdm >>import.all +mbutil link -clean +=== Cut === +

+
+ + + AREALISTSORT <sortspec=FYTUE> + +

+ This keyword defines how the area list should be sorted. You can + override the default setting from the commandline with the + -S switch. +

+

+ The <sortspec> can be composed of the following types: + + + + A + + + Sort by aka. + + + + + B + + + Sort by board number. + + + + + D + + + Sort by description. + + + + + E + + + Sort by echoid. + + + + + F + + + Sorts all "fuzzy search" matches first. + + + + + G + + + Sort by group (if any). + + + + + M + + + Sorts all marked areas first. + + + + + O + + + Sort by original order. + + + + + P + + + Sort by personal mail. + + + + + T + + + Sort by type (in the order net, echo, local). + + + + + U + + + Sort by unread messages (try it!). + + + + + X + + + Sort by msgbase type. + + + + + Y + + + Sorts all areas with "new" mail first. + + + + + Z + + + Sort by msgbase path. + + + + + - + + + Descending sort (largest first). + + + + + + + + + Ascending sort (smallest first) (default). + + +
+

+

+ In practice M and Y will usually give the same result, + because GoldED+ automatically marks scanned areas if they + contain new mail. +

+

+ Example: +AREALISTSORT T-U+E +

+

+ This sorts ascending by type, descending by unread (that is, areas with + the most unread messages comes first) and ascending by echoid (in case + two areas have the same number of unread msgs). +

+

+ By default no sorting is done, and all areas are listed in the order + they were found (unless sorting was specified with an AREAFILE + keyword). However, the configuration examples all make use of the + unread sorting type. This is a very useful way of sorting areas, + because it keeps all the areas with mail together. +

+

+ Personally I now sort my areas like this: AREALISTSORT FYTUE. + This puts all areas with new mail first, then sorts these into type + (net/echo/local), then into number of new msgs and finally into echoid. + The F at the start enables fuzzy match sorting, which is very + handy when looking for an echoid containing a particular word. Let's + say I want a list of all GOLDED echoes. I can now simply type + GOLDED and then the arealist automatically sorts itself so that + all echoes with an echoid containing GOLDED comes first :-) +

+

+ The X sort type sorts areas according to msgbase type, in the + following order: Hudson, Goldbase, + JAM, Squish, OPUS + *.MSG, FTS-1 *.MSG, + Ezycom, PCBoard. +

+

+ The X and Z sort types were implemented for internal use, + to optimize area scanning speed. When scanning areas, + GoldED+ starts by sorting the arealist using the sortspec + defined with the AREASCANSORT keyword. +

+
+ + + AREALISTTYPE <(new)/last> + +

+ Defines the contents of the 4th column (the one after the Total + column). + + + + New + + + Displays the amount of new (unread) msgs. + + + + + Last + + + Displays the number of the last msg read. + + +
+

+
+ + + AREAPATH <path> + +

+ If you use the AREAFILE keyword, GoldED+ might + need to know where the area setup files are located. This keyword + specifies where they are found, if not current directory. +

+

+ NOTE: Most AREAFILE types can find the path using the + environment variable(s) specific for the program(s). Such environment + variables (or a path specified with the AREAFILE definition) + always overrides the AREAPATH. +

+
+ + + AREAPMSCAN <echoid mask> + +

+ This keyword defines areas which will be automatically scanned for + personal mail when starting GoldED+. + DOS/4DOS-style wildcards (* and ?) can be + used in the echoid mask. +

+

+ Examples: +AREAPMSCAN * ; Scan all areas. +AREAPMSCAN *INTER* ; Scan all areas containing INTER anywhere in the + ; echoid +AREAPMSCAN INT*.* ; Scan all areas beginning with INT and + ; containing a dot anywhere in the echoid +

+

+ It is recommended to have an AREAPMSCAN * to scan all areas at + startup. If you don't want to wait for the scan to complete, you can + abort the scan by pressing <ESC> during startup. +

+
+ + + AREAPMSCANEXCL <echoid or wildcards> + +

+ With this keyword you can prevent areas from being scanned with + AREAPMSCAN on startup. This is good if you use + AREAPMSCAN *, but have some big areas which slows it down. +

+
+ + + AREAPMSCANINCL <echoid or wildcards> + +

+ Here you can specify areas to be scanned with AREAPMSCAN even + if they were excluded with AREAPMSCANEXCL. Useful for partial + reversal of wildcard specs in the excludes. +

+
+ + + AREAREADONLY <(soft)/hard> + +

+ If this keyword is set to hard, it is no longer possible + to enter/reply/change messages in areas marked read-only with the R/O + area attribute. The soft setting uses a menu to ask + permission as in the previous versions. This option is designed for + those who setup a system for new computer users who might be confused + enough to enter a message in a read-only area despite the warning menu. +

+
+ + + AREARENAME <from echoid> <to echoid> + +

+ Renames one echoid to another. The feature is meant to be used in + connection with AREAFILE, where some types do not store + echoids with the areas (and GoldED+ then automatically + gives them unique echoids). +

+

+ Examples: +AREARENAME NET001 NETMAIL +AREARENAME ECHO001 BAD_MSGS +AREARENAME LOCAL001 BBS.USERS +

+
+ + + AREAREPLYDIRECT <yes/(no)> + +

+ If enabled, the destination area selection list is bypassed, thereby + making possible a seamless reply/forward to the default + destination area. The destination area should be set with + AREAREPLYTO. +

+

+ TIP: If you run a utility or have a mail processor which + copies personal mail to a separate area and puts an AREA: line + at the top of the messages, you should create a random system group for + the area and enable AREAREPLYDIRECT in it: +Group ECHO_PERSONAL + AreaReplyDirect yes +

+

+ With such a setup, GoldED+ replies directly to the area + found in the AREA: line, so that you do not have to explicitly + use the <Alt-N> command to reply in the original area, because + GoldED+ automatically stores the reply in the appropiate + area. However, if you use <ALT-N>, you can select a diffrent area + (i.e. Netmail). +

+

+ This keyword can be used globally and in a Random System group. +

+

+ NOTE: It is probably not a good idea to enable this keyword + globally. +

+
+ + + AREAREPLYTO <echoid=first netmail area> + +

+ Sets the default area for the READmovequotemsg, + READmovecommentmsg and Forward functions. The default area is + the first netmail area found in your setup. You should check if + GoldED+ found the correct one if you have more than one. + If you find yourself often forwarding or quoting from one area to + another, it might be a good idea to setup a Random System group and put + in this keyword. +

+

+ Example: +Group GOLDED + AreaReplyto GOLDED.BETA +EndGroup +

+

+ This keyword can be used globally and in a Random System group. +

+

+ Related keywords: AREACOPYTO, AREAFREQTO. +

+
+ + + AREASCAN <echoid mask> + +

+ This keyword defines areas which will be automatically scanned when + starting GoldED+. DOS/4DOS-style + wildcards (* and ?) can be used in the echoid mask. +

+

+ Examples: +AREASCAN * ; Scan all areas. +AREASCAN *INTER* ; Scan all areas containing INTER anywhere in + ; the echoid. +AREASCAN INT*.* ; Scan all areas beginning with INT and + ; containing a dot anywhere in the echoid. +

+

+ It is recommended to have an AREASCAN * to scan all areas at + startup. If you don't want to wait for the scan to complete, you can + abort the scan by pressing <ESC> during startup. +

+
+ + + AREASCANEXCL <echoid or wildcards> + +

+ With this keyword you can prevent areas from being scanned with + AREASCAN on startup. This is good if you use + AREASCAN *, but have some big areas which slows it down. +

+
+ + + AREASCANINCL <echoid or wildcards> + +

+ Here you can specify areas to be scanned with AREASCAN even if + they were excluded with AREASCANEXCL. Useful for partial + reversal of wildcard specs in the excludes. +

+
+ + + AREASCANSORT <sortspec=XZBE> + +

+ When scanning areas, GoldED+ can optimize area scanning + speed if it first sorts the arealist in an order so that each msgbase + format is scanned in sequence rather than on semi-random order. +

+

+ If you don't like this or don't need it, you can define your own sort + order. +

+

+ See the AREALISTSORT keyword for the definition of the + sortspecs. +

+
+ + + AREASEP <echoid> <"desc"> <group> <type> + +

+ You can define area separation lines between groups or areatypes. The + syntax is nearly the same as the AREADEF keyword except for + the fields after <type>. +

+

+ Examples: +

+

+ These five are area separation lines that are designed to list before + each type of area. This works well when AREALISTSORT has + T (for type) as one of the primary sort orders. +

+

Example: +

+

+ These can be used to separate areas with group letters (it will also + work with group numbers like #117). Areas should then be sorted + primarily on the group. +

+

Example: +

+

+ In these examples, I put a ! in front of the echoid to make + sure it is sorted ahead of the areas. This may not be necessary in all + cases, depending on the sort order in effect. If you do put + ! in front of the echoid, have fuzzy sorting as the primary + sort order, and type ! in the fuzzy search, you'll get the + interesting effect that all area separation lines collect themselves at + the top :-) +

+

+ The area separation lines are implemented like a special kind of area, + and are therefore sorted in the arealist just as if they were actual + areas. This is also the reason why you can place the cursor bar on the + separation lines. Originally I wanted to make the cursor skip the + separation lines, but I think I'll leave it as it is, because it can be + useful sometimes, especially when using the fuzzy feature to quickly go + to an area, for example, type !C to quickly move down to + the group C areas (using the group sorted example). +

+

+ When configuring area separation lines, be careful to consider the + AREALISTSORT, so that the lines are sorted into the positions + you want. If you don't sort areas, you must make sure that the + AREASEP definitions are placed correctly in your + GOLDED.CFG or GOLDAREA.CFG, that is, + between/before AREADEF lines. +

+

+ You will note that the separation lines are not fully connected into + the left and right edges. This is both by design and for practical + reasons (easier to implement), not a bug. +

+

+ Currently the descriptions are hardcoded to the natural location in the + description column. +

+
+ + + AREASTART <echoid> + +

+ Normally GoldED+ starts by displaying the arealist, to let + you select which area you want to read. If this keyword is defined, the + arealist is bypassed and GoldED+ starts directly in the + configured area. You can override AREASTART with the + -E commandline switch. +

+
+ + + AREATYPEORDER <type1=Net> <type2=EMail> <type3=Echo> + <type4=News> <type5=Local> + +

+ This keyword allows you to change the ordering of the + Net, Echo, Local, + EMail and News types when sorted by + AREALISTSORT. +

+

+ This keyword was added to give greater flexibility to the + AREASEP feature. +

+
+ + + AREAYOUWROTETO <echoid> + +

+ GoldED+ automatically copies mails written by yourself to + the given area when saving a new mail. GoldED+ will also + add an AREA kludge so you can see from which area the mail + originally is copied from. +

+

+ This keyword can be used globally and in Random System group. +

+
+ + + ASKDELORIG <(yes)/no> + +

+ If enabled, you will be asked if the message you just replied to should + be deleted. Otherwise it is left untouched. +

+

+ This keyword is only functional in netmail and local areas. +

+
+ + + ATTACHPATH <path> + +

+ Defines the default <path> when selecting files for attachement. +

+
+ + + ATTRIBSATTACH <attributes> + +

+ Defines the attributes that are added to the existing + attributes of a message when the file attach attribute is toggled on. +

+
+ + + ATTRIBSCC <attributes> + +

+ Defines the default attributes of Carbon Copy messages. CC + attributes are added to the existing attributes of the + original message. Usually used to add the Kill/Sent attribute. +

+
+ + + ATTRIBSCFM <attributes> + +

+ Defines the default attributes of the Confirmation Receipt message. +

+
+ + + ATTRIBSECHO <attributes> + +

+ Defines the default attributes of messages entered in echomail areas. +

+
+ + + ATTRIBSEMAIL <attributes> + +

+ Defines the default attributes of messages entered in e-mail areas. +

+
+ + + ATTRIBSFRQ <attributes> + +

+ Defines the attributes to use for messages generated with the file + request function. Suggested attributes are: PVT K/S + CRA. The FRQ and LOC attributes are added + automatically. +

+
+ + + ATTRIBSLOCAL <attributes> + +

+ Defines the default attributes of messages entered in local areas. +

+
+ + + ATTRIBSNET <attributes> + +

+ Defines the default attributes of messages entered in netmail areas. +

+
+ + + ATTRIBSNEWS <attributes> + +

+ Defines the default attributes of messages entered in news groups. +

+
+ + + ATTRIBUTES <attributes> + +

+ Defines the default attributes for area members of the current Random + System group. +

+
+ + + BEEPCOMMENT <(yes)/no> + +

+ If enabled, GoldED+ will make a noise when the cursor in + the internal editor is moved across a word defined with the + EDITCOMMENT keyword. +

+
+ + + BEEPLOCALMSG <yes/(no)> + +

+ If enabled, GoldED+ will make a noise if it finds a msg + with the Local (LOC) attributes set. This can be useful + for the sysop who wants to monitor the msgs entered by users on his/her + BBS. +

+

+ A related keyword is DISPLOCALHIGH. +

+
+ + + BEEPNOISES <(yes)/no> + +

+ If enabled, GoldED+ makes noises when it wants attention. +

+

+ NOTE: This is the master switch for all noises in + GoldED+. +

+
+ + + BEEPYOURMAIL <(yes)/no/always> + +

+ If set to Yes, GoldED+ will make a noise if + it finds a non-received message to one of your USERNAME's. If + set to Always, GoldED+ will make the noise + even if it has already been marked as received. +

+
+ + + CARBONCOPYLIST <listspec=Names> + +

+ This specifies the format of the Carbon Copy list, as it will look + after processing. You can also change the format in the CC + menu before processing. +

+

+ The <listspec> can be one of the following: +

+

+ Keep Keep the list as entered. + Names Convert list to "CC: Name, Name, Name.." format. + Visible Convert list to "CC: Name Address" format. + Hidden Convert list to "^aCC: Name Address" format. + Remove Remove the list completely. +

+

+ More details can be found in the Carbon Copy and Crossposting chapter. +

+
+ + + COLOR <colorspec> + +

+ Using this keyword you can define or redefine all the colors used + in GoldED+. See the Color Configuration chapter for details. +

+

+ A complete color setup consists of a quite a lot of COLOR + keywords, and it is normal practice to put them in a separate .CFG + file and use the INCLUDE keyword to let GoldED+ read it. The COLORS + archive contains a number of example color/mono setups. Try them + out if you think the default colors stink :-) +

+
+ + + COLORSET <Normal/Intense/Mono> + +

+ (Normal or Mono) +

+

+ Three color setups are built-in, and can be selected with this + keyword. +

+

+ The Normal set is the default when a color display adapter is + detected. The Normal set has all black background, with bright + neon-like colors for the window frames. Some hate it, some love + it. :-) +

+

+ The Intense set switches off the "blink" attribute, thereby + enabling the use of intense (bright) colors for the background + ("paper") colors as well as the foreground ("ink") colors. This is + used in the Intense set to make a bright white background, sort of + like the standard Windows 3.0 setup. +

+

+ The Mono set is the default when a monochrome adapter is detected. +

+
+ + + CONFIRMFILE <filename> + +

+ (GOLDED.CFM) +

+

+ GoldED+ supports the Confirmation Receipt attribute, as used in + FrontDoor 2.xx with the FLAGS CFM kludge. If GoldED+ finds an + unreceived message to one of your USERNAME's with the CFM (or the + RRQ Return Receipt Request) attribute set, it generates an + automatic response message from the content of the CONFIRMFILE. In + the file you can use many of the template tokens to personalize + the automatic message. You can specify the default attributes for + the message with the ATTRIBSCFM keyword. +

+

+ Template tokens are explained in the Message Template chapter. +

+
+ + + CONFIRMRESPONSE <yes/no/ask> + +

+ (ask) +

+

+ An unreceived message to you with the CFM attribute set tells + GoldED+ that the sender has requested a receipt that you have read + the message. With this keyword you tell GoldED+ what to do when + such a message is found. Either always automatically generate the + receipt ("yes"), always ignore the requests ("no") or ask you in + each case. Older versions always generated receipts. +

+
+ + + COOKIEPATH <path> + +

+ (defaults to the GOLDPATH) +

+

+ Defines the default path for the @random template token. +

+
+ + + CROSSPOSTLIST <listspec> + +

+ (Verbose) +

+

+ This specifies the format of the Crosspost list, as it will look + after processing. +

+

+ The <listspec> can be one of the following: +

+

+ None Crosspost without a list in the msgs. + Verbose Change the list to lines of "* Crossposted in ..." + Yes Also adds "* Crossposted in ...", but expands echolist + in line rather than in column. + Raw Keep the crosspost list as you entered it. +

+

+ More details can be found in the Carbon Copy and Crossposting + chapter. +

+
+ + + CTRLINFO <Tearline,Origin,yes/no> + +

+ Specifies if you want a tearline and/or origin in your messages. +

+

+ This keyword can ONLY be used in Random System groups. +

+

+ This may be helpful for QWK users, who can now create a group for + the QWK areas and put "CTRLINFO No" in it. +

+
+ + + CTRLINFOECHO <Tearline,Origin,yes/no> + +

+ (Tearline Origin) +

+

+ Specifies if you want a tearline and/or origin in your echomail + messages. They will be added by your echomail processor if you + disable them here. +

+

+ Examples: +

+

+ CTRLINFOECHO Tearline Origin ; Add both tearline and origin. + CTRLINFOECHO Tearline ; Add only a tearline. + CTRLINFOECHO Origin ; Add only an origin. +

+

+ NOTE: If you use the last example, your mail processor may get + confused. However, most modern mail processors *can* handle msgs + without a tearline. +

+
+ + + CTRLINFOEMAIL <Tearline,Origin,yes/no> + +

+ (No) +

+

+ Specifies if you want a tearline and/or origin in your Internet + e-mail messages. This is not recommended. +

+
+ + + CTRLINFOLOCAL <Tearline,Origin,yes/no> + +

+ (No) +

+

+ Specifies if you want tearline and origin in your messages in + local areas. In local areas, the tearline and origin is normally + never required but can be used for cosmetic purposes. +

+

+ Examples: +

+

+ CTRLINFOLOCAL Tearline Origin ; Add both tearline and origin. + CTRLINFOLOCAL Tearline ; Add only a tearline. + CTRLINFOLOCAL Origin ; Add only an origin. +

+
+ + + CTRLINFONET <Tearline,Origin,yes/no> + +

+ (Tearline) +

+

+ Specifies if you want tearline and origin in your netmail + messages. In netmail areas, the tearline and origin is normally + never required but can be used for cosmetic purposes. +

+

+ Examples: +

+

+ CTRLINFONET Tearline Origin ; Add both tearline and origin. + CTRLINFONET Tearline ; Add only a tearline. + CTRLINFONET Origin ; Add only an origin. +

+
+ + + CTRLINFONEWS <Tearline,Origin,yes/no> + +

+ (No) +

+

+ Specifies if you want a tearline and/or origin in your Internet + news articles. This is not recommended. +

+
+ + + DISPAREANO <yes/no/always> + +

+ (yes) +

+

+ This keyword specifies if GoldED+ should display the area number on + the top line in the reader. +

+

+ Yes Display it only if non-zero. + No Never display it. + Always Always display the area number. +

+

+ The area number is the same as that displayed in the leftmost + column in the arealist. This also means that the number displayed + can be either the "real" area number (Hudson/Goldbase/Ezycom + board) or the standard sequential number (toggleable with Alt-B in + the arealist). +

+

+ The number is displayed in square brackets to the left of the area + description. I am not sure that is the best place for it - things + are getting kinda crowded up there... Suggestions are welcome. +

+
+ + + DISPATTACHSIZE <bytes/kbytes/no> + +

+ (kbytes) +

+

+ Controls how the size of attached files is displayed in the + header. Either the exact byte size, the rounded kbyte size, or not + displayed at all. If the kbytes setting is chosen, the value is + rounded according to the following formula: kbytes = (bytes + 512) + / 1024. So a 600 bytes file is rounded up to "1k", but a 500 bytes + file is rounded down to "0k". +

+
+ + + DISPAUTONEXT <yes/no> + +

+ (yes) +

+

+ If enabled, GoldED+ will automatically jump to the next message + when entering an area. +

+
+ + + DISPHDRDATESET <pos> <len> + +

+ (-20 20) +

+

+ Specifies the position and length of the date field in the header + display. If a negative value is specified, that value is added to + the current display width. +

+
+ + + DISPHDRNAMESET <pos> <len> + +

+ (8 36) +

+

+ Specifies the position and length of the from/to name field in the + header display. If a negative value is specified, that value is + added to the current display width. +

+
+ + + DISPHDRNODESET <pos> <len> + +

+ (44 16) +

+

+ Specfies the position and length of the from/to node address field + in the header display. If a negative value is specified, that + value is added to the current display width. +

+

+ NOTE: The attributes display moves along with the DISPHDRNODESET + values. +

+
+ + + DISPLISTCURSOR <top/neartop/middle/nearbottom/bottom> + +

+ (middle) +

+

+ Selects the starting position of selection bar in the message list + and nodelist browsers. +

+

+ Top At the top if possible. + NearTop At top + 1/3 if possible. + Middle At middle of possible. + NearBottom At bottom - 1/3. + Bottom At bottom. +

+
+ + + DISPLISTWRAP <yes/no> + +

+ (no) +

+

+ Enables/disables wrap-around when the selection bar in the main + list/browser windows reaches the top or bottom. +

+
+ + + DISPLOCALHIGH <yes/no> + +

+ (yes) +

+

+ If enabled, GoldED+ will display the FROM name with the highlight + color, if a message has the Local (LOC) attribute set. +

+

+ A related keyword is BEEPLOCALMSG. +

+
+ + + DISPMARGIN <width> + +

+ (0) +

+

+ This is the right margin (display width) used for message display. + If the value is 0 (zero), GoldED+ will default to the current + screen width. If a negative value is specified, that value will be + added to the current screen width (thereby decreasing the display + width relative to the screen width). +

+

+ If the DISPPAGEBAR keyword is enabled, the right margin is + automatically decreased by one char. +

+
+ + + DISPMSGSIZE <bytes/kbytes/lines/no> + +

+ (bytes) +

+

+ When enabled, this keyword displays the msgbody size in bytes, + kbytes or lines in the lower left side of the header. The size + displayed is for the message body text only, the header and + nul-terminator (and anything that may lurk beyond it) is excluded + from the calculation. +

+

+ NOTE: This feature currently only works when _reading_ msgs. While + editing a msg in the internal editor, this feature is disabled - + however, the size will be displayed when you are in the Save msg + menu (if EDITSAVEMENU is enabled). +

+
+ + + DISPPAGEBAR <yes/no> + +

+ (yes) +

+

+ If enabled, a "pagebar" (similar to the scrollbar in GUI's) will + appear on the right margin, telling you about the relative size + and position in the message you are reading. It is only displayed + if a message is longer than a screenful. +

+

+ The pagebar automatically decreases the DISPMARGIN by one char. +

+
+ + + DISPREALMSGNO <yes/no> + +

+ (no) +

+

+ GoldED+ can display the message numbers in two ways: +

+

+ 1. As the actual (real) msg numbers. + 2. As "relative" numbers, which are always sequential from msg + number 1. +

+

+ Normally the relative numbers are best, because they reflect the + actual number of msgs in the system. +

+
+ + + DISPSOFTCR <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will treat the so-called Soft-CR character + (ASCII 141, HEX 8D) just like any other displayable character, + instead of ignoring it like linefeed chars (LF). Note that by + enabling this feature, you _disable_ the character translation + feature that uses the Soft-CR as an escape character. This feature + was added to help users in countries which use the Soft-CR + character for other purposes like 2-byte characters in Japan. +

+

+ NOTE: The Ezycom msgbase format requires the Soft-CR to terminate + each line. Therefore this feature is unlikely to be useful to + Ezycom sysops. +

+
+ + + DISPSTATUSLINE <yes/no> + +

+ (yes) +

+

+ If set to NO, the statusline with memory meter, clock etc. will be + disabled. This option has been implemented as a temporary help for + visually impaired users. More extensive help may be implemented in + future versions. +

+
+ + + DISPTABSIZE <chars> + +

+ (4) +

+

+ The tab size (number of spaces) used when displaying the tab + (ASCII 9) character, and when pressing <Tab> in the internal + editor. +

+

+ If you use an external editor, you should switch it to create + spaces instead of tabs, because tabs are technically not allowed + in FidoNet technology messages. +

+
+ + + DOSPROMPT (yes/no) + +

+ (yes) +

+

+ If enabled, GoldED+ will add a message about itself to the DOS + prompt when shelling out. +

+
+ + + EDITAUTOATTACH <yes/no> + +

+ (yes) +

+

+ If enabled, and you use drivespec (C:, D:, etc.) in the subject in + a netmail message, GoldED+ will automatically turn on the file + attach attribute. Autoattaching only works if the subject has been + edited, so that subject files will not automatically be + re-attached in replies. +

+
+ + + EDITAUTOSAVE <seconds> + +

+ (30) +

+

+ If a non-zero value is given, the internal editor will + automatically execute the EDITsavefile function with intervals of + <seconds>. Good for keeping automatic backup of the message you + are writing. The saved file can be restored with the EDITloadfile + command. The name of the saved file is defined with the EDITORFILE + keyword. +

+

+ If disaster strikes (crash, lockup, power blackout, etc.) while + you are writing a message in the internal editor, this feature + lets you continue from the last autosaved message, which will + popup automatically when you enter the internal editor again. +

+

+ NOTE: This feature only works 100% if KEYBMODE is set to "poll". + If KEYBMODE is set to "block", autosave won't happen until you + press a key after the interval has passed. +

+
+ + + EDITCHANGEDATE <always/yes/no> + +

+ (yes) +

+

+ If set to "always", GoldED+ will always "touch" the message date in + the header, if you change a message after saving it. +

+

+ If set to "yes", GoldED+ will only "touch" the message date in the + header, if you change a message written by yourself. This is + useful in cases such as when you need to edit messages written by + other people (in-transit netmails for example) which may be + mis-addressed or something without messing up the date. +

+

+ If set to "no", the message date is not changed when changing a + message. +

+
+ + + EDITCHARPARA [']<char>['] + +

+ (' ') +

+

+ This keyword defines the character GoldED+ displays at the end of + paragraphs in the internal editor. This is where the CR character + will be placed once the msg is saved. +

+
+ + + EDITCHARSPACE [']<char>['] + +

+ (' ') +

+

+ This keyword defines the character GoldED+ displays when it should + display a space character in the internal editor. See also the + description of the EDITCHARPARA keyword. +

+

+ The keywords EDITCHARPARA and EDITCHARSPACE were added to aid me + while rewriting and debugging the new internal editor. By + redefining them to visible characters instead of spaces, I could + see if strange things were happening while inserting or deleting + characters. This was a great help. Personally I now always use + redefinitions to ASCII 20 (a paragraph sign) and CP437 250 (a + small dot). +

+
+ + + EDITCOMMENT <"word"> <"comment"> + +

+ This feature is mostly for fun :-) +

+

+ It allows you to define words which causes GoldED+ to display a + comment in the statusline, when you place the cursor on the word + in the internal editor. +

+

+ Example: +

+

+ EDITCOMMENT ":-(" "Don't worry, be happy!" + EDITCOMMENT ":-)" "Are we having fun yet?" + EDITCOMMENT ";-)" "Wink wink, nudge nugde..." + EDITCOMMENT "!!!" "Flame Warning!" + EDITCOMMENT "GoldED" "Great program, isn't it?" + EDITCOMMENT "Odin" "One more 'n' please." + EDITCOMMENT "Odinn" "That's right :-)" +

+

+ Have fun with it! +

+
+ + + EDITCOMPLETION <"abbreviation"> <"completion"> + +

+ This feature allows you to define abbreviations which will be + automatically expanded to full words or sentences when typed in + the internal editor. Examples: +

+

+ EDITCOMPLETION "/Odin" "Odinn" + EDITCOMPLETION "/GED" "GoldED" + EDITCOMPLETION "/V7" "Version 7" + EDITCOMPLETION "/FD" "FrontDoor" + EDITCOMPLETION "/WfW" "Windows for Workgroups" +

+

+ NOTE! The abbreviation is case-sensitive. If "XX" is defined as + an abbreviation, completion will NOT be triggered if "xx" is + typed. +

+
+ + + EDITCRLFTERM <yes/no> + +

+ (no) +

+

+ If enabled, all text paragraphs in your messages will be + terminated with a CR/LF combination. If disabled, only a single CR + is used. This option was created to fix a problem with an older + version of the Dutchie mail processor, that apparently needed the + CR/LF termination of kludge lines. +

+
+ + + EDITFIELDCLEAR <yes/no> + +

+ (yes) +

+

+ If enabled, the input-fields will be automatically cleared for new + entry, if a non-edit key is the first key pressed. +

+
+ + + EDITHARDLINE <string> + +

+ ("<<") +

+

+ The string is needed if you use an external editor that terminates + all lines with a CR or CR/LF. The hardline string acts as a text + paragraph terminator, and the normal CR's are ignored. +

+

+ The concept of "hardlines" is explained in the Hardline Feature + chapter. +

+
+ + + EDITHARDLINES <yes/no> + +

+ (yes) +

+

+ This keyword enables the "hardline" feature. If disabled, the + EDITHARDLINE string is never written to the editor message file, + and the editor message file is read back exactly as entered, + including terminating CR's on all lines. +

+
+ + + EDITHARDTERM <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will hard-terminate all lines in your messages + at the editor margin. It is recommended to enable this keyword for + Internet e-mail and newsgroups, because some user-unfriendly + Internet software does not wrap long lines properly. But DON'T + enable it in normal FidoNet echomail. +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + EDITHDRNAMESET <pos> <len> + +

+ (8 36) +

+

+ Specfies the position and length of the from/to name field in the + header edit display. If a negative value is specified, that value + is added to the current display width. +

+
+ + + EDITHDRNODESET <pos> <len> + +

+ (44 36) +

+

+ Specfies the position and length of the from/to node address field + in the header edit display. If a negative value is specified, that + value is added to the current display width. +

+
+ + + EDITHEADERATTRS <yes/no> + +

+ (yes) +

+

+ This keyword allows you to turn off the large attributes window + that is shown during header edit. Even if the window is turned + off, the Alt-keys are still active for toggling attributes. +

+
+ + + EDITHEADERFIRST <new,changes,replies,forwards,yes/no> + +

+ (yes) +

+

+ This keyword controls the circumstances that will present you with + the header editor first of all. +

+

+ New When entering a new message. + Changes When changing a message + Replies When making a reply. + Forwards When forwarding a message. + Yes Always (all of the above). + No Never. +

+

+ The New, Changes, Replies and Forwards values can be combined. YES + is equivalent to enabling all four of these. +

+

+ For example, we want to edit the header only when entering a new + message or when changing a message: +

+

+ EDITHEADERFIRST New, Changes +

+

+ If the circumstances match the setup of this keyword, the header + edit will be bypassed and you will start directly in the EDITMENU + (if enabled) or in the internal or external editor. A new menu + item has been added in the EDITSAVEMENU, "Edit Header", which + allows you to edit the header after you have written your message, + but before it is finally saved. +

+

+ If you set EDITHEADERFIRST to NO, you must either have the + EDITSAVEMENU enabled, or use the internal editor, because + otherwise it is not possible to edit the header at all. +

+
+ + + EDITINTERNAL <yes/no> + +

+ (yes) +

+

+ Specifies if the internal editor should be the default, even if an + external editor is defined. You can always change the setting in + the editor menu (if EDITMENU is enabled) before you start writing + your message. +

+
+ + + EDITMENU <yes/no> + +

+ (yes) +

+

+ This keyword enables or disables the "Edit menu" that pops up + right after you have edited the message header. If you disable the + menu, you will go to the internal or external editor immediately + and save a keystroke, but you will of course lose the features + available from the menu, such as selection of template etc. +

+
+ + + EDITMIXCASE <yes/no> + +

+ (no) +

+

+ If this keyword is enabled, GoldED+ will automatically format the + name with uppercase the first letter in words and lowercase the + rest, when entering names in the header. +

+

+ Examples: +

+

+ "odinn sorensen" or "ODINN SORENSEN" +

+

+ These would be re-cased to "Odinn Sorensen". +

+
+ + + EDITMSGSIZE <bytes> + +

+ (64000 in DOS, 512000 in all others) +

+

+ This lets you limit the size of loaded msgs. GoldED+ currently + cannot handle msgs larger than 64k in the DOS version (all other + platforms do not have this limit). This keyword ensures that the + system will not get confused and possibly crash or exit, if a + message was encountered that was larger than 64k. +

+
+ + + EDITOR <commandline> [@file] [@line] + +

+ With GoldED+ it is possible to use your favorite text editor or + even word processor to write messages. With this keyword you + specify the commandline for the editor. +

+

+ If you use a word processor, be sure to make it export clean ASCII + text files without control codes. You may also need to enable the + DOSSWAP keyword, if the editor or word processor requires a lot of + free memory to run. +

+

+ <commandline> Program commandline. + @file Token which is replaced by the editor message + filename. + @line Token which is replaced by the @Position + template line number. +

+
+ + + EDITORFILE <file> + +

+ (GOLDED.MSG) +

+

+ Defines the name of the temporary editor message file. This file + is written by GoldED+ when swapping to the external editor, or when + using the EDITsavefile command in the internal editor. +

+

+ The file is written in the GOLDPATH if there is no explicit path. +

+
+ + + EDITQUOTEMARGIN <margin> + +

+ (75) +

+

+ Sets the right margin for editing quoted lines in the internal + editor. This should be set to the same or wider than the + QUOTEMARGIN. +

+
+ + + EDITREPLYRE <yes/no/numeric> + +

+ (no) +

+

+ If enabled, GoldED+ inserts the "Re:" string in front of the + subject when you reply to a message. If not enabled, GoldED+ will + strip any leading "Re:" when you reply to a msg. +

+

+ The "Re:" string in subjects is an obsolete practice, and today it + only slows down modern replylinking software. Do yourself and + others a favor and let GoldED+ strip the Re: in your replies. +

+

+ The "numeric" option makes GoldED+ use numeric Re:'s, of the form + "Re^n:". +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + EDITSAVEMENU <yes/no> + +

+ (yes) +

+

+ This keyword enables or disables the "Save menu" that pops up + after you have edited your message in the internal or external + editor. If you disable the menu, your message will be saved (or + discarded if not edited) immediately and save you a keystroke, but + you will also lose the features available from the menu. +

+
+ + + EDITSAVEUTIL <utilno> <"L menu text"> + +

+ Defines the external utilities that will be added to the + EDITSAVEMENU (if enabled). The menu text is inserted in the menu. + The first two characters of the menu text are the "hotkey" letter + that will be highlighted in the menu text, plus a space. Example: +

+

+ EDITSAVEUTIL 1 "S PGP Sign the msg" + EDITSAVEUTIL 2 "l PGP Clear-Sign the msg" + EDITSAVEUTIL 3 "E PGP Encrypt the msg" + EDITSAVEUTIL 4 "p PGP Encrypt & Sign the msg" +

+

+ If you have changed the default language in this menu (in + GOLDLANG.CFG), then make sure the highlight letters don't clash. +

+

+ With EDITSAVEUTIL definitions and EDITSAVEMENU enabled, you can + directly call an external utility to do things like encoding or + encrypting msgs before saving them. +

+
+ + + EDITSOFTCRXLAT <char> + +

+ If a translation char is defined, GoldED+ will translate the + soft-cr character (ASCII 141, HEX 8D) while saving message to base. + The following example translates the soft-cr to an 'H' (for use in Russia): +

+

+ EDITSOFTCRXLAT H +

+

+ You also have to enable the DISPSOFTCR keyword. +

+
+ + + EDITSPELLCHECK <commandline> [@file] + +

+ While in the internal editor, you can use the EDITspellcheck + command to save your message to a file and shell to external + spellchecking software. When the check is completed, the corrected + file is read back and you can continue editing your message. The + EDITspellcheck command internally uses the EDITsavefile and + EDITloadfile commands. +

+

+ <commandline> Spellchecker program commandline. + [@file] Token which is replaced by the message filename + (defined by the EDITORFILE keyword). +

+
+ + + EDITUNDELETE <lines> + +

+ (50) +

+

+ This keyword defines the number of lines to keep in the undelete + buffer between messages. +

+
+ + + EMPTYTEARLINE <yes/no> + +

+ (no) +

+

+ With this keyword enabled, GoldED+ will always strip the tearline + down to just the three dashes, "---", and instead inserts the PID + (Product IDentification) kludge line, which contains the same + information, but in a safer form in a safer place. The PID kludge + is proposed in FidoNet document FSC-0046. +

+
+ + + ENCODEEMAILHEADERS <yes/no> + +

+ (yes) +

+

+ By default headers in e-mails MIME-encoded according to RFC. In + Russia it is general practice not to encode headers, so you + probably want to say No here if you're in Russia ;-) This keyword + supported only in -asa versions. +

+
+ + + ENDGROUP + +

+ Ends a Random System GROUP definition. +

+
+ + + EVENT <eventtype> <eventcommand [parameters]> + +

+ This keyword allows you to specify which soundfile to play when a + specfic event occurs. The following <eventtype>'s are defined: +

+

+ EVENTTYPE TRIGGER: +

+

+ Arealist When the arealist shows. + AskYesNo Any Yes/No type prompt. + Attention Warnings or information popup messages. + DosShell When entering a DOS or OS/2 shell. + EditComment When an editcomment is found. + EndOfMsgs When there are no more msgs in the area. + ErrorFatal Fatal error exit. + Exit Exit from GoldED+. + JobDone Successful completion of a job. + JobFailed Unsuccessful completion of a job. + MsgDeleting When deleting a msg. + MsgFromYou When a msg from you is found. + MsgIsLocal When a msg marked Local is found. + MsgIsTwit When a msg from a Twit is found. + MsgToYou When a msg to you is found. + SearchFailed Search operation failed. + SearchSuccess Search operation was successful. + Startup When the GoldED+ startup screen shows. +

+

+ There is currently only one <eventcommand> defined: +

+

+ PLAY <filename.ext/beepnoise>. +

+

+ The parameter to PLAY can be either a sound file or one of the + following standard beepnoises: +

+

+ TheEnd A high and a low note. + GotIt Two sets of low-high notes. + TooBad A falling note. + ToYou A rising and falling note. + SayBiBi A single beep. + SOS Morse S O S (...---...). +

+

+ If a sound file is specified, the sound driver must support the + format. +

+

+ The DOS and 386 versions need a Goldware Sound API compatible TSR + or program loader which installs an interrupt service function on + the multiplex interrupt 2Dh. See the chapter about the Goldware + Sound API for more details. The GCTVSAPI program loader (released + separately) currently only supports the CT-VOICE.DRV driver for + .VOC files. +

+

+ The OS/2 version relies on MMPM/2 (using the mciSendString API + call) to play the sound files. On my system with a Sound Blaster + Pro, MMPM/2 plays both .WAV and (to my surprise) .VOC files. It + even plays .MID files :-) +

+

+ The Win32 version uses the Win32 API to play the sound files. It + should be able to play any multimedia file that Windows knows how + to handle. +

+

+ Example usages: +

+

+ EVENT MsgToYou PLAY HIMAN.VOC + EVENT MsgIsTwit PLAY SHOTGUN.VOC +

+

+ You have to select the sounds carefully and probably with a lot of + experimentation, unless you want to turn your mailreader into a + honking, wailing and farting monster and drive your poor family or + yourself nuts with a cacophony of noises... +

+
+ + + EXCLUDENODES <addressmask> + +

+ You can define up to 50 different addressmasks to be excluded from + the compiled nodelists. Use this if you are short of space, or the + nodelist compile takes very long on your system. This keyword is + used by GoldNODE. +

+

+ Excluded nodes can be re-included with the INCLUDENODES keyword. +

+
+ + + EXTERNOPTIONS <-options> + +

+ Defines the default options for the EXTERNUTIL's. Valid options: +

+

+ -Cls * Clear screen. + -Cursor * Cursor in shell. + -KeepCtrl * Keep control lines in the message. + -Pause Pause for keypress before returning to GoldED+. + -PauseOnError * Pause only if utility errorlevel is nonzero. + -Reload * Reload the message file (@file). + -Swap * Swap GoldED+ out of memory before shelling. + -Wipe Wipe editorfile and temporary file after use. +

+

+ Plus the reverse options with a "No" prefix, for example -NoCls. + The default options are marked with an asterisk (*). +

+

+ Use -NoKeepCtrl when you want to clearsign a message. This will + strip the control lines (kludges, tearline and origin) from the + message before passing it to the external utility. The tearline + and origin is appended to the message when reloading it. The + default is to keep control lines in the message. +

+

+ Use -Wipe when you want the temporary unencrypted message files to + be wiped and removed from the disk after they have been read into + memory. GoldED+ wipes a file by writing a block of 512 random bytes + over the entire length of the file, then truncating it to zero + bytes and finally deleting it. The default is not to wipe files. +

+
+ + + EXTERNUTIL <utilno> [-options] <commandline> + +

+ This new feature can be used to "filter" msgs, for example calling + PGP or other encryption utilities. +

+

+ The <utilno> must be in the range 1 to 24 for utilities that will + be called with key definitions (see below). Higher numbers can be + used for utilities that are called from the EDITSAVEMENU (if + enabled). See the EDITSAVEUTIL keyword for details. +

+

+ The default options are those specified with the EXTERNOPTIONS + keyword. With [-options], you can change the those options locally + for specific utils. See the EXTERNOPTIONS keyword for a list of + valid options. +

+

+ The <commandline> specfies the DOS or OS/2 commandline you want to + execute. This works in the same way as for the external editor and + spellchecker. See the manual for details about this, especially if + you want to execute batchfiles. In the <commandline> you can use + @tokens to transfer information from the msg to the commandline. + The @tokens are the same as for templates, and in addition you can + use two other @tokens: +

+

+ @path The GOLDPATH, including a trailing backslash. + @file The full filename of the message file (GOLDED.MSG) + that will be written to disk before the utility is + called. + @tmpfile The full filename of a temporary message file + (GEDTMPxx.xxx) that will be written to disk before the + utility is called. +

+

+ Examples: +

+

+ EXTERNUTIL 1 c:\4dos\4dos.com /c c:\crypt\encrypt.bat @file + EXTERNUTIL 2 c:\4dos\4dos.com /c c:\crypt\decrypt.bat @file +

+

+ To call a defined external utility, you must assign a key to it. + There are 24 new keyboard commands you can use in GOLDKEYS.CFG for + this purpose: +

+

+ ExternUtilNN +

+

+ Where NN is in the range 01 to 24 _with_ leading zero. Examples: +

+

+ F11 ExternUtil01 + F12 ExternUtil02 +

+

+ Then if you press F11, you would call external utility number 1 + and so on. The ExternUtilNN keywords ONLY work in reader mode, not + in the internal editor or any other place. +

+

+ HOW IT WORKS: +

+

+ 1. Just before the external utility is called, GoldED+ writes the + current message text to the GOLDED.MSG file in the GOLDPATH. + The file is written as a textfile with each line CR-LF + terminated. The content is exactly as you see it on the + screen, which means that kludges are only included if you have + enabled kludge viewing. If the -NoKeepCtrl option is used, + kludges, tearline and origin are stripped before the file is + written. If the token @tmpfile is used, a temporary file named + GEDTMPxx.xxx (where xx.xxx is something unique) is created + with exactly the same content as @file. +

+

+ 2. GoldED+ clears the screen and then calls the utility after + swapping itself out of memory (if swapping is enabled or + relevant for the version). +

+

+ 3. The utility can now load and process the @file and/or + @tmpfile, or do anything else you want. It doesn't have to + have anything to do with the current msg. You could call a + spreadsheet, a game, whatever. But I think this feature will + mainly be used for utilities that process the @file. If the + utility processes the @file, it could write the changes back + to the @file. +

+

+ 4. After returning from the utility, GoldED+ reloads the @file and + displays it just as if it was the current message. For + example, if your utility was a decrypter and the msg was + encrypted, you would now see the decrypted msg. Neat eh? :-) +

+

+ 5. If you want to make the reloaded text permanent (save it in + the msg), you can use the Change Msg function and immediately + choose "Save Message" from the Editing menu (if enabled with + EDITMENU Yes). This is in fact the method you could use if you + wanted to EN-crypt a msg (however, it is easier to use the + method which involves the EDITSAVEUTIL keyword). +

+

+ The QUOTESPACING feature can interfere with encoded msgs that + include the '>' character at the beginning of lines (often seen in + uuencoded msgs), by automatically inserting blank lines before and + after the lines with '>'. I have therefore changed the + quotespacing default from YES to NO. Be sure to check if you have + a different setting if you are using an older edition of the + advanced configuration files. +

+

+ If the string "-----BEGIN PGP MESSAGE-----" is found as the first + 27 characters in a reloaded message, GoldED+ will automatically add + the FSC-0073 kludge "^aENC: PGP" to indicate that the message is + encrypted. This kludge may be used by some software to set up + alternative routing for encrypted mail which would otherwise be + bounced if sent through normal channels. +

+

+ See the "Using PGP as an External Utility" chapter for batchfile + examples and instructions on how to use this new feature with PGP. +

+

+ !!! IMPORTANT !!! From FidoNet Policy 4.07 (chapter 2.1.4): +

+

+ "[..] Therefore, encrypted and/or commercial traffic that is + routed without the express permission of all the links in the + delivery system constitutes annoying behavior." +

+

+ So be careful with this feature! +

+

+ TIP: You can use the EXTERNUTIL feature to setup keys to view or + print an attached fax. Use something like this in GOLDED.CFG: +

+

+ EXTERNUTIL 11 c:\zfax\zfax.com pf @subject ; print fax + EXTERNUTIL 12 c:\zfax\zfax.com vf @subject ; view fax +

+

+ And this in GOLDKEYS.CFG: +

+

+ @F11 ExternUtil11 ; Press Alt-F11 to print the fax + @F12 ExternUtil12 ; Press Alt-F12 to view the fax +

+

+ Or choose your own key assignments and fax view/print utils. +

+

+ Note that this assumes that the fax file is listed in the subject + line like an attached file. +

+

+ NOTE: If you're running GoldED+/386 and try to use a Win32 program + as an EXTERNUTIL, you might get the error "This program cannot be + run in DOS mode". You can work around this by calling the Win32 + program via the shell. For example if this call fails: +

+

+ EXTERNUTIL 1 c:\utl\mywin32.exe @file +

+

+ Replace it with: +

+

+ EXTERNUTIL 1 command.com /c c:\utl\mywin32.exe @file +

+

+ Then it should work. If not, try using full path to command.com. +

+
+ + + EZYCOMMSGBASE <path> + +

+ Defines the base path for the Ezycom msgbase. If not set, AREAFILE + Ezycom will set it. +

+
+ + + EZYCOMUSERBASE <path> + +

+ Defines the base path for the Ezycom userbase. If not set, + AREAFILE Ezycom will set it. +

+
+ + + EZYCOMUSERNO <userno> + +

+ (0) +

+

+ Defines the lastread set used in the Ezycom message base. +

+
+ + + FIDOHWMARKS <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will use the echomail "highwater mark" (1.MSG) + to determine if a message is "sent" or "unsent" in *.MSG areas. +

+

+ NOTE: Some older echomail processors do not update the highwater + mark in a way that GoldED+ can recognize. If all messages appear to + marked "Uns", even after the mail has been scanned out, try + turning off this keyword. +

+
+ + + FIDOLASTREAD <file> + +

+ (LASTREAD) +

+

+ Defines the filename of the *.MSG lastread files. DO NOT specify a + path. +

+
+ + + FIDOMSGTYPE <Opus/FTS1> + +

+ (Opus) +

+

+ This keyword defines the default format of Fido *.MSG files. It is + only used by some AREAFILE's when reading external area + configuration files, where the preferred format is unknown. +

+

+ The FTS1 (FTS-0001.012 and later) format uses zone/point fields, + where the Opus format uses date/time stamps. When set to Opus + format, GoldED+ interprets the date/time stamps as DOS-style + bitmapped date/time. +

+
+ + + FIDONULLFIX <yes/no> + +

+ (no) +

+

+ If set to YES, GoldED+ will replace NUL chars with LF chars in the + msg body when reading a Fido *.MSG file. This is slower of course, + but not noticably on fast machines. +

+

+ This option was created to enable GoldED+ users to read msgs that + were created/handled by brain-dead programs (I don't have names, + sorry) which are not obeying our primary technical standard: + FTS-0001. FTS-1 states that a NUL terminates the msg body. But + sometimes msgs are encountered which have a NUL as the first char + in the msg body or perhaps in other places, thereby causing GoldED+ + to show a blank or cut-off msg. In some Pascal-based readers, such + as FM, these msgs can be read anyway, because in Pascal a NUL does + not terminate a string like in C/C++. +

+

+ NOTE: Even if the new FIDONULLFIX keyword is disabled, GoldED+ will + still fix a NUL if it is the _first_ character in the msg body. + This probably fixes most of these buggy msgs without the overhead + of checking the entire msg. +

+
+ + + FIDOUSERLIST <file> + +

+ Path and filename of a FIDOUSER.LST file. +

+

+ This file is expected to be sorted in ascending alphabetical order + using plain ASCII case-insensitive sort. Each line in the list is + expected to be 60 characters plus a CR and a LF, or in other words + records of 62 bytes each. If the list is produced by a nodelist + compiler, everything should be okay, but be careful if you have + edited the file manually. Note that a FIDOUSER.LST file only + supports a name lookup (to get the address). +

+
+ + + FIDOUSERNO <userno> + +

+ (0) +

+

+ This is an index into the FIDOLASTREAD file. Each user occupies 2 + bytes in the lastread file. +

+
+ + + FILEALIAS <alias> <filename> + +

+ Used to define short alias names for filenames. If you regularly + write msgs to different files in different paths, this feature is + very useful, and reduces the risk of typing wrong. +

+

+ Example: +

+

+ FILEALIAS DKB R:\DKBBS\DKBBS +

+

+ With this file alias, you can simply write "DKB" at the filename + prompt, and the long filename will be used. +

+
+ + + FILELISTPAGEBAR <yes/no> + +

+ (yes) +

+

+ Enables or disables a pagebar (scrollbar) in the file attach list + function. +

+
+ + + FORCETEMPLATE <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will popup a template selection menu when you + start writing a new msg or reply. If you have both TEMPLATE(s) and + FORCETEMPLATE in a Random System group, you can tell GoldED+ to use + the random template(s) by hitting ESC instead of selecting from + the menu. +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + FORMFEEDSEPARATOR <yes/no> + +

+ (no) +

+

+ Used when saving messages to file. If enabled, it inserts a Form + Feed (12d) character after each message. +

+
+ + + FRQEXT <.ext> + +

+ With this keyword you can add extra known filename extensions for + the filerequest function. The following extensions are already + known by default, and need not be defined (duplicate definitions + are ignored): +

+

+ .ARC .ARJ .DOC .EXE .GIF .LHA .LZH .JPG .PAK .PNG .RAR .RUN .SDA + .SDN .TXT .ZIP .ZOO +

+

+ Each extension _must_ have the leading dot. +

+

+ Example: FRQEXT .XYZ +

+
+ + + FRQNODEMAP <to-node> <from-node> + +

+ This keyword is used for the file request feature (Ctrl-F). It + allows you to define mappings from a nodenumber used in a file + announcement to another nodenumber. This is useful in the cases + where a multi-line system announces files using their primary + nodenumber, which may be a regular V34 modem number, but they also + have an ISDN number, which you would prefer to use instead. + Examples: +

+

+ // change-to: from: + FRQNODEMAP 2:236/99 2:236/100 + FRQNODEMAP 2:236/1043 2:236/43 +

+

+ So, if I saw a file announcement from 2:236/100, and requested + some files, the request would automatically be addressed to + 2:236/99. +

+
+ + + FRQOPTIONS <options> + +

+ (FromTop) +

+

+ Defines options for the file request function: +

+

+ Sort Sort the list of files alphabetically. + FromTop Scan the message from the top of the message. + NotFromTop Scan the message from the top of the screen. + NoFiles Don't list the file FILES if no files were found. + NoWazooMsg Don't save the request message. + Fast Bypass the header edit and save the msg immediately. +

+

+ By default, the "FromTop" option is enabled. If you often request + files from very long announcement messages, you might find it very + useful to set the "NotFromTop" option. +

+

+ The "NoFiles" option was added because if no filenames are found + in a message, the file request function defaults to listing the + magic name FILES instead of complaining that no files were found. +

+

+ If the FRQWAZOO keyword is enabled, the default behaviour is to + save the request message with the FRQ attribute stripped. Use the + "NoWazooMsg" option if you don't want the request message. +

+

+ Use the "Fast" option if you find that you almost never change the + destination of the file request message anyway. If you enable this + option, remember that you can always go over to the netmail area + and change the file request message before it is sent. +

+

+ The UseFlowFile option enables a feature which was default in + 2.50, but which I have been informed is problematic for modern + mailers in some setups. The default is now to ONLY create/update + the .REQ file and NOT also touch/create a .?LO flowfile. +

+
+ + + FRQWAZOO <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will create WaZOO .REQ files instead of file + request messages. You must define an OUTBOUNDPATH if you enable + this feature. +

+
+ + + GEDHANDSHAKE <yes/no> + +

+ (yes) +

+

+ If this switch set to yes GoldEd displays handshake char in + statusline. If you annoyed with this feature you could hide this + character by setting this option to no. +

+
+ + + GERMANKEYBOARD <yes/no> + +

+ (autodetect) +

+

+ This option is meanful for w32 version only. Due to right Alt key + required to enter some native characters in german version of + Windows it could be defined to yes for this. +

+
+ + + GOLDBASEPATH <path> + +

+ Specifies the directory where GoldED+ can find the Goldbase msgbase + files. +

+
+ + + GOLDBASESYSPATH <path> + +

+ Specifies the directory where GoldED+ can find the NETMAIL.DAT and + ECHOMAIL.DAT files of the Goldbase msgbase. If not specified, the + GOLDBASEPATH is used. +

+
+ + + GOLDBASEUSERNO <userno> + +

+ (0) +

+

+ Specifies the lastread set used in the Goldbase message base. +

+
+ + + GOLDPATH <path> + +

+ This is the path where GoldED+ finds all it's control files. It is + not necessary to define this, unless you have special needs. The + GOLDPATH defaults to directory where the GOLDED.CFG file was + found. +

+
+ + + GROUP <groupname> + +

+ Starts a Random System group. See the Random System chapter for + details. +

+
+ + + HAPPYBIRTHDAY <value> + +

+ The only valid value is "friend". Currently do nothing. +

+
+ + + HIGHLIGHTUNREAD <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ updates (increases) the "timesread" field in + each message that you read. If set to NO, it doesn't touch the + message. The YES setting causes a slight performance decrease, + because the header of each message has to be read, the timesread + field updated and the header written back to disk. The update + happens immediately after the message is displayed, so you may not + notice it at all. A message is only updated if the timesread field + contains the value 0 (zero). +

+

+ This keyword only works in the following msgbase formats: Fido + (*.MSG), Hudson, Goldbase, JAM, Squish, Ezycom and AdeptXBBS. In + Squish and Ezycom, there is no timesread field, but I have annexed + a reserved message attribute (in Squish, 0x00080000, now called + MSGSEEN; in Ezycom, extattr 0x80) for the purpose of marking a + message as read at least once. The other formats (PCBoard, + WildCat) have no timesread field, but they have reserved fields or + attributes which *could* be used. Let me know if you want this. +

+
+ + + HUDSONPATH <path> + +

+ Specifies the directory where GoldED+ can find the Hudson msgbase + files. +

+
+ + + HUDSONSIZEWARN <size in bytes> + +

+ (16000000) +

+

+ When the Hudson MSGTXT.BBS file exceeds this size, GoldED+ starts + to warn that the msgbase is getting dangerously close to the + structural limit (which is 16MB for the MSGTXT.BBS file). With + this keyword you can raise or lower the warning size in case you + think the default is too low or too high. +

+
+ + + HUDSONSYSPATH <path> + +

+ Specifies the directory where GoldED+ can find the NETMAIL.BBS and + ECHOMAIL.BBS files of the Hudson msgbase. If not specified, the + HUDSONPATH is used. +

+
+ + + HUDSONUSERNO <userno> + +

+ (0) +

+

+ Specifies the lastread set used in the Hudson message base. +

+
+ + + IGNORECHARSET <yes/no> + +

+ (no) +

+

+ If set to yes then GoldEd ignores CHRS kludges in messages thus + you will be able to switch codepage in messages with inappropriate + charset. +

+
+ + + IMPORTBEGIN <text> + +

+ ("=== Cut ===") +

+

+ This keyword, together with IMPORTEND, defines some text to add in + the beginning and end of an imported text file in the internal + editor. If only IMPORTBEGIN is defined, the text is also used for + the IMPORTEND. The <text> may be enclosed in quotes ("") if + leading or trailing spaces are needed. The quotes are stripped. +

+

+ The replacement token "@file" can be used in the <text>. It will + be replaced with the import filename as entered. +

+

+ Example: +

+

+ IMPORTBEGIN === Cut Begin: @file === + IMPORTEND === Cut End === +

+
+ + + IMPORTEND <text> + +

+ (same as IMPORTBEGIN) +

+

+ See IMPORTBEGIN. +

+
+ + + INBOUNDPATH <path> + +

+ (defaults to GOLDPATH) +

+

+ The inbound path is currently only used with the file request + feature (the READfilerequest command, <Ctrl-F>). If you use this + feature, GoldED+ will put the file descriptions into a FILES.BBS in + the inbound path, ready for when the requested files are moved to + the correct file areas. +

+
+ + + INCLUDENODES <addressmask> + +

+ You can define up to 50 different addressmasks to be included from + the compiled nodelists. This is only used in conjunction with the + EXCLUDENODES keyword to include otherwise EXcluded nodes. This + keyword is only used by GoldNODE. +

+
+ + + INPUTFILE <filename> + +

+ (*) +

+

+ Defines the default name in the internal editor file import + function. +

+

+ GoldED+ can automatically uuencode and apply a base64 encoding to + the files during importing them into the internal editor. +

+

+ NOTE: This is a very simple implementation of encoders. It cannot + split large files over several messages. The file mode number 644 + is hard-coded and has nothing to do with the actual file mode. +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + INTENSECOLORS <yes/no> + +

+ (no) +

+

+ GoldED+ is capable of switching off the "blink" color, and thereby + enabling the use of bright background (paper) colors. Enable this + keyword, and try out one of the intense color setup examples. +

+
+ + + INTERNETADDRESS <internet-address> + +

+ Specifies your Internet address. This must be the address only, no + name. The INTERNETADDRESS and USERNAME will be combined to a + standard "From: internetaddresss (username)" headerline when you + write e-mail or articles. +

+

+ Example: +

+

+ USERNAME Odinn Sorensen + INTERNETADDRESS odinn@ibm.net +

+

+ Produces the RFC line: +

+

+ From: odinn@ibm.net (Odinn Sorensen) +

+
+ + + INTERNETDOMAIN <domainname> + +

+ (username%domain.net) +

+

+ Defines the domain-part of outgouing Message-ID's. If you don't + know your full domain, leave it as default, which should work just + fine. +

+
+ + + INTERNETGATE [gatename<,>]<address> + +

+ Defines the local Internet gate you use when sending netmail to + Internet users. This option is activated when you write an + Internet address in the TO: field in the header display. GoldED+ + detects the Internet address by looking for the '@' character. If + detected, GoldED+ puts the gate address from INTERNETGATE in the + TO: address field. If you have defined the optional gate name + (typically UUCP), GoldED+ also replaces the typed Internet address + with the gate name and puts the Internet address in a TO: line in + the message body. Some gate software accepts the Internet address + directly in the header, while other software may need the special + (UUCP) name and a separate TO: line. Examples: +

+

+ INTERNETGATE UUCP, 1:105/42 ; Standard, with gate name + INTERNETGATE 2:230/9316 ; My uplink runs GIGO software +

+

+ This keyword can be used globally in GOLDED.CFG, if you only ever + use one gate, or in GROUP's for specific areas in GOLDRAND.CFG if + you have multiple netmail areas and regularly use more than one + gate. +

+

+ NOTE: If you enable the INTERNETRFCBODY keyword, you should always + use the gatename UUCP, because otherwise the gateway software may + send duplicate copies (carbon copies) of your e-mails. +

+
+ + + INTERNETLOOKUP <yes/no> + +

+ (no) +

+

+ If set to Yes, GoldED+ will check the systemname in the nodelist + when doing a lookup and if the systemname looks like an Internet + address (contains an '@' char), the msg will be addressed to that + Internet address using the INTERNETGATE name/address if defined. +

+

+ For example, let's say there was something like this in the + nodelist: +

+

+ ,999,somebody@somewhere,Whereever,Some_Body,... +

+

+ And this in my GOLDED.CFG: +

+

+ INTERNETLOOKUP Yes + INTERNETGATE 2:230/9316 +

+

+ Then if I did a lookup of "Some Body" and selected the entry with + the Internet address, GoldED+ would make a msg looking like this: +

+

+ -------------------------------------- + From : odinn@winboss.dk 2:236/77 + To : somebody@somewhere 2:230/9316 + Subj : whatever + -------------------------------------- +

+

+ Or if my gate was defined as "INTERNETGATE UUCP 2:230/9316": +

+

+ -------------------------------------- + From : odinn@winboss.dk 2:236/77 + To : UUCP 2:230/9316 + Subj : whatever + -------------------------------------- + To: somebody@somewhere +

+

+ So what's the use of all this? It allows you to make a + nodelist-style list of users with Internet addresses and use it + with GoldED+ so that you can do a lookup of normal names instead of + trying to remember strange Internet addresses. Of course something + similar could be done using the ADDRESSMACRO's, but with the + nodelist approach, you could build a "network" of users which have + offline Internet access via FTN-gate software and distribute the + nodelist for automatic processing. +

+
+ + + INTERNETMSGID <yes/no> + +

+ (no) +

+

+ Specifies whether the FTN MSGID kludge should contain an RFC1036 + compatible Message-ID or the normal FTS-9 format. Note that using + the RFC1036 format in MSGID breaks the FTS-9 (version 001) + specification, so please don't use this feature in FidoNet netmail + or echomail. As a safeguard, GoldED+ will only use the RFC1036 + format in areas specifically marked as e-mail or newsgroups, using + the SOUPEMAIL and SOUPNEWSRCFILE keywords or using the Email and + News area types with the AREADEF keyword, even when INTERNETMSGID + is set to YES globally. +

+
+ + + INTERNETREPLY <yes/no> + +

+ (yes) +

+

+ When INTERNETREPLY is enabled, GoldED+ always uses the FSC-35 + REPLYADDR/REPLYTO kludges to gate replies to msgs from Internet + correctly. If disabled, GoldED+ only uses the FSC-35 method if the + Internet address is too large to fit in the max-35-character TO: + header field. Some gate software requires that the FSC-35 method + is used, while other software accepts Internet addresses directly + in the header. +

+
+ + + INTERNETRFCBODY <yes/no> + +

+ (no) +

+

+ Tells GoldED+ whether to look for and process RFC headerlines at + the top of the message body, before the first empty line. Also + tells GoldED+ to insert its own RFC headerlines at the top of the + message body instead of as kludge lines. This option should only + be used when receiving Internet mail as QWK packets where the RFC + headerlines are usually found at the top of the messages, or when + sending Internet mail via FTN packet to a gateway running GIGO. + GIGO does not recognize RFC header in kludges, but it does + recognize them at the top of the messages, if it is properly + configured (with lines of "Allow_Xxx:" in GIGO's HEADERS.CFG, + where Xxx are the RFC headerlines the gate administrator wants to + allow). +

+
+ + + INTERNETSERVER <nntp/smpt> <server> + +

+ + + + INTERNETSERVER <pop3> <server> [<username>] [<password>] + +

+ No code currently associated with this keyword. +

+
+ + + INVALIDATE <type> <"findstring"> <"replacestring"> + +

+ This is used to invalidate (change) certain control strings in + quoted text. Use this in conjunction with old versions of D'Bridge + or other software that chokes on control strings in quoted text. + As an added bonus feature, if the tearline or origin is + invalidated to a null string (""), they will not be quoted at all. +

+

+ The <type> can be one of the following: +

+

+ Tearline Invalidate tearline ("---"). + Origin Invalidate origin (" * Origin: "). + Seenby Invalidate SEEN-BY's. +

+

+ By default, the following invalidations are used: +

+

+ INVALIDATE Tearline "---" "-+-" + INVALIDATE Origin " * Origin: " " + Origin: " + INVALIDATE Seenby "SEEN-BY" "SEEN+BY" +

+

+ If you want to disable invalidation entirely, use this: +

+

+ INVALIDATE Tearline "---" "---" + INVALIDATE Origin " * Origin: " " * Origin: " + INVALIDATE Seenby "SEEN-BY" "SEEN-BY" +

+

+ The defined INVALIDATEs are also used during importing a file when + editing a mail in the internal message editor. +

+
+ + + JAMHARDDELETE <yes/no> + +

+ (no) +

+

+ The default setting makes GoldED+ conform to the JAMAPI specs when + deleting msgs in JAM msgbases. This means that deleted msgs are + only marked as such in the message header, not in the index. As a + result, GoldED+ will find and display the deleted msgs until you + run a message pack utility to physically remove the deleted msgs. +

+

+ If JAMHARDDELETE is set to Yes, GoldED+ will zap the reference to + the message in the index when deleting msgs. This way the deleted + msgs will not show up again later. The drawback of this approach + is that it is hard to undelete msgs, and may break other software + which assume 100% to-the-letter conformance to the specs. Note + however, that the hard-delete method is transparent to normal use + of JAM msgbases. Probably the only software that might break are + undelete utilities. +

+

+ For the techies and programmers, the hard-delete method is simply + setting both UserCRC and HdrOffset in the index to 0xFFFFFFFF + instead of only the UserCRC. According to the JAMAPI specs, a + value of 0xFFFFFFFF in HdrOffset means that "there is no + corresponding message header". Sounds remarkably like a deleted + msg, right? :-) +

+
+ + + JAMPATH <path> + +

+ (defaults to the HUDSONPATH) +

+

+ Defines the path where GoldED+ can access the NETMAIL/ECHOMAIL.JAM + files, which are used by mail processors to find and scan out mail + written by users. +

+

+ GoldED+ can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED+ translates the path to + C:\POINT\path\name. + NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED+ to recompile it's config, you must force + it with the -F or -FF command parameter. +

+
+ + + KEYBCLEAR <yes/no> + +

+ (no) +

+

+ Tells GoldED+ whether or not to clear the keyboard buffer on + startup. This also clears KEYBSTACK or commandline key stuffing. + In older versions of GoldED+, it was necessary to enable this + keyword if you had renamed GOLDED.EXE to DBEDIT.EXE. This version + detects the .EXE renaming and automatically enables KEYBCLEAR, + regardless of the configuration setting. +

+
+ + + KEYBDEFAULTS <yes/no> + +

+ (yes) +

+

+ GoldED+ defines a default keyboard configuration setup internally. + The keys can be reconfigured in the GOLDKEYS.CFG file. By default, + the internal keyboard setup is active always, redefinable with the + definitions in GOLDKEYS.CFG. But in some cases it can be + preferrable that the internal keyboard setup is turned off, so + that only the keys in GOLDKEYS.CFG are active. If you want this, + set KEYBDEFAULTS to NO. +

+
+ + + KEYBEXT <yes/no> + +

+ (detect) +

+

+ If enabled, GoldED+ will use extended bios calls to read the + keyboard. With the extended keyboard, you can use keys like + <Alt-Left>, <Alt-Home> and other extended keys. If you don't have + an extended keyboard, don't despair - using a few neat tricks, I + have made it possible to use some of the extended keys even with a + non-extended keyboard. +

+
+ + + KEYBMODE <poll/block> + +

+ (poll) +

+

+ If this option is set to Poll, GoldED+ switches its keyboard + handling code from "blocking" to "polling" mode. This enables + GoldED+ to provide a continuously running statusline clock, + automatic internal editor autosave, timeout exit and screensaver. + If set to Block, the timeout exit and screensaver are disabled, + and the clock and autosave are dependent on key presses. +

+

+ In order to minimize waste of CPU resources in keyboard polling + mode, GoldED+ automatically detects DESQview, Windows and OS/2 and + releases timeslices during the keyboard poll. +

+
+KEYBSTACK <keystring> +

+ With this keyword, you can "stack" keys in the keyboard buffer. + The KEYBSTACK can be overridden by commandline keystacking, which + uses the same syntax. +

+

+ The <keystring> can be a mixture of the following: +

+

+ ^Char Ctrl-key (^Letter). + ~Char Ctrl-key (~Letter). (Use this with 4DOS!). + @Key Alt-key (@Number or @Letter). + Char Literal character. + "String" String, enclosed in double quotes. + 'String' String, enclosed in single quotes. + Number Keyboard scan code (decimal). + ! Clear keyboard buffer. +

+

+ Whitespace (space and tab) is ignored, except in quoted strings. +

+

+ See the chapter for more info. +

+
+ + + KLUDGE <kludge-definition> + +

+ The definition may optionally be enclosed in quotes. A definition + must be enclosed in quotes if it contains leading or trailing + spaces. The KLUDGE tells GoldED+ which kludges it should consider + as "known" in addition to the built-in known kludges. +

+

+ Here are a bunch of examples, most of which are kludges generated + by the GIGO Internet gateway software: +

+

+ KLUDGE " " ; For wrapped kludges + KLUDGE "Content-Type:" + KLUDGE "Date:" + KLUDGE "From:" + KLUDGE "In-Reply-To:" + KLUDGE "Message-Id:" + KLUDGE "Mime-Version:" + KLUDGE "Organization:" + KLUDGE "Newsgroups:" + KLUDGE "Received:" + KLUDGE "Reply-To:" + KLUDGE "Sender:" + KLUDGE "Subject:" + KLUDGE "To:" + KLUDGE "Errors-To:" + KLUDGE "X-FTN-From:" + KLUDGE "ORIGREF:" ; Gated? + KLUDGE "ORIGID:" ; Gated? + KLUDGE "RFC-" ; Seen in NET_DEV +

+

+ The kludges defined with KLUDGE are not case-sensitive, but when + GoldED+ looks for the kludges, it matches to the exact length. This + means that for example "RFC-" will match all kludges beginning + with that string. +

+

+ The ASCII 1 kludge char should not be included in the definition + string, but GoldED+ can handle it if you do. +

+
+ + + KLUDGECHRS <yes/no> + +

+ (yes) +

+

+ If set to YES, GoldED+ uses the "^aCHRS" kludge instead of the + "^aCHARSET" kludge when appropriate. +

+
+ + + LOADLANGUAGE <file> + +

+ If defined, this keyword will load a language definition file. +

+

+ This feature can be used to load a small set of national language + definitions in national areas, an english set in international + areas, etc. Typically this would be used to load the definitions + of the date/time strings for use in the template and the + Msg/From/To/Subj strings in the header display. +

+

+ In the ADVANCED archive, a set of GEDLNG*.CFG files are provided, + which are designed for use with LOADLANGUAGE. Please note that + there is also a @loadlanguage template token. This way you can + choose to load a language file from the template, or by using the + Random System. The template token takes precedence over the + LOADLANGUAGE in the Random System, but if both are defined, both + will be loaded. +

+

+ This keyword can be used globally and in Random System groups, but + it is probably not very useful when used globally. +

+
+ + + LOGFILE <file> + +

+ (GOLDED.LOG) +

+

+ Defines the name of the GoldED+ logfile. You should not change the + default. +

+
+ + + LOGFORMAT <fd,max,bink,qbbs,db> + +

+ (fd) +

+

+ Defines the log format GoldED+ should use when writing to the + logfile. +

+
+ + + LOOKUPECHO <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will use nodelist lookup when entering the TO: + name in msgs in echomail areas. +

+

+ GoldED+ *won't* lookup the name if it exactly matches the current + WHOTO - text. This is a feature, because a lookup of "All" is not + very useful. :-) +

+
+ + + LOOKUPLOCAL <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will use nodelist lookup when entering the TO: + name in msgs in local areas. +

+

+ GoldED+ *won't* lookup the name if it exactly matches the current + WHOTO - text. This is a feature, because a lookup of "All" is not + very useful. :-) +

+
+ + + LOOKUPNET <yes/no> + +

+ (yes) +

+

+ If enabled, GoldED+ will use nodelist lookup when entering the TO: + name in msgs in netmail areas. +

+
+ + + LOOKUPUSERBASE <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will attempt to find a matching username in the + user database if a to-name with wildcards is entered in echo or + local areas. +

+

+ The userbase lookup feature is not new, but a need arose for an + option to turn off the lookup. I decided to let the default be to + disable the lookup. Previously the lookup was always enabled. +

+
+ + + MAILINGLIST <echoid> <senderaddress> [contribution address] + +

+ Defines one or more mailing lists. When importing e-mail from a + SOUP packet, GoldED+ will look at the Internet address in the + "Sender" header and if it matches one of the MAILINGLIST's, the + e-mail will be tossed to the defined area. Note that GoldED+ + supports only participation in, not hosting of mailing lists. The + contribution address is the destination Internet address for mail + you write to the mailing list - the address is typically given to + you when you subscribe to a list. If the contribution address is + not specified, the senderaddress is assumed. +

+
+ + + MAILTOSS <echoid> <contribution-address> <pattern> + +

+ This is acutally the same as MAILINGLIST in disguise with the + parameters recorded and it also enables the full set of pattern + matching. The <pattern> can be written exactly as if in the prompt + for the advanced search feature. +

+

+ Any number of MAILTOSS lines can be given for a particular list, + if there is for some reason no single way to identify the list. +

+

+ When determining the contribution address, the first MAILTOSS + (or MAILINGLIST) that matches the echoid is chosen. +

+

+ MAILTOSS and MAILINGLIST can both be used at the same time and for + the same lists. MAILINGLIST is always the faster, because it looks + only at specific headerlines. MAILTOSS uses much more complex + pattern matching and can even match based on message body content. +

+
+ + + MAPPATH <server filespec> <local filespec> + +

+ This keyword is used to map paths, for example if you have + different drive letters on a server machine and a workstation. You + might have your FidoNet mailer and mail processor setup to run + with the server drive letter (C:), but run GoldED+ from a + workstation where that drive is mapped to a different letter (J:). + If you use AREAFILE's to get the area configuration for GoldED+, + you need to use MAPPATH to map the server drive letter to the + workstation equivalent. +

+

+ Another case might be that you have a setup with DOS-style paths + and want to run the Linux version with the same GoldED+ setup. You + can then use MAPPATH to map the DOS drive-based paths to Unix + style paths. +

+

+ Examples: +

+

+ MAPPATH C: J: + MAPPATH C:\ /mnt/dos/c/ +

+

+ NOTE: You don't have to worry about backslash/forwardslash in this + case - they are always mapped automatically to the correct type + for the operating system. +

+
+ + + MEMBER <echoid> + +

+ Defines Random System group members. See the Random System chapter + for details. +

+
+ + + MENUDROPMSG <yes/no> + +

+ (no) +

+

+ Defines the default selection in the "Drop This Msg?" menu. +

+
+ + + MENUMARKED <marked/current/previous/default> + +

+ (default) +

+

+ Specifies the position of the selection bar in the Marked/Current + menu. +

+

+ Marked Set selector to Marked. + Current Set selector to Current. + Previous Set selector to previously selection. + Default Set selector to Marked if there are marked msgs. +

+

+ Note that older versions (before 2.50) used the equivalent of the + "previous" setting. +

+
+ + + MOUSE <yes/no> + +

+ (no) +

+

+ The mouse support in GoldED+ is currently not functional, so this + keyword is ignored. +

+
+ + + MSGLISTDATE <written/arrived/received/no> + +

+ (written) +

+

+ Can be used globally and in groups. This keyword specifies the + default date shown in the right column in the message list. If + "no" is specified, the date column is removed and the space used + to widen the other columns. Personally I prefer to see the + "arrived" date, which is why I implemented this feature. +

+

+ The key command LISTtoggledate (Ctrl-D) toggles between them. +

+

+ Note that the "arrived" date doubles as the "processed" date for + messages that are written locally and scanned out from your + messagebase. +

+

+ Not all messagebase formats supports all three dates. The table + below shows which messagebase supports which dates: +

+

+ Written Arrived Received + JAM X X X + *.MSG X X + Squish X X + Ezycom X X + Hudson X + Goldbase X + PCBoard X +

+

+ If a date is not supported, "n/a" (for "not available") is shown + instead. +

+
+ + + MSGLISTFAST <yes/no> + +

+ (yes) +

+

+ The message lister can operate in two ways, fast or slow. In the + fast mode, only the message headers are loaded for the list + information. Depending on the msgbase format and message type, + some information may not be quite the same when presented in the + lister because information which is gathered from kludges or other + control information in the message text will be missing. Most of + the time this may not be a problem, so if you want speed, chose + the fast mode (default). +

+

+ The slow mode loads and fully interprets the content of each + message before the message list is presented. The slowness is most + noticable when entering the lister and when paging up and down. + You may want to use the slow mode for areas with Internet + newsgroups and e-mail, where GoldED+ uses the "From" kludge to get + the real name of the message writer. +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + MSGLISTFIRST <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ automatically starts the message lister when + entering an area. +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + MSGLISTHEADER <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ shows the header of the current message when + you scroll the bar up and down. This is how it worked in previous + versions. If disabled, GoldED+ does not show the header and instead + uses the screen space to show more messages. By eliminating the + header display, it is also much faster at scrolling the list. +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + MSGLISTPAGEBAR <yes/no> + +

+ (yes) +

+

+ Enables or disables a pagebar (scrollbar) in the message list. +

+
+ + + MSGLISTVIEWSUBJ <yes/no> + +

+ (yes) +

+

+ If enabled, GoldED+ will display the full subject in the bottom + border of the list window. Note that this feature slows down + scrolling a bit. +

+
+ + + MSGLISTWIDESUBJ <yes/no> + +

+ (no) +

+

+ If enabled, the Subject column is made wider by removing the To + column. This is especially useful in gated Internet newsgroups, + where the To name is always "All". +

+

+ You can toggle between wide and short subject with Ctrl-B + (keycommand LISTtogglewidesubj). +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + NAMESFILE <file> + +

+ (NAMES.FD) +

+

+ GoldED+ supports the "address macro" file supported by FrontDoor + and Maximus. If no path is specified, the file is first searched + for in the path from the "FD" environment variable and then the + GOLDPATH, if the FD variable failed. +

+

+ The address macros are added *after* those defined with the + ADDRESSMACRO keyword (if any) (see this for details on the + format). +

+
+ + + NICKNAME <your pseudo> + +

+ Defines the nick name (pseudo) for the current USERNAME. Can be + used globally and in random system groups. + +

+
+ + + NODELIST <file> [zone/addr] + +

+ Here you define the nodelists that are used by GoldED+ and the + companion nodelist compiler GoldNODE. The nodelists must generally + be in the standard "St.Louis" nodelist format, but they can also + contain FrontDoor/Version7 style Boss/Point extensions. The + default zone is defined by the first ADDRESS or AKA, but can be + overridden by adding the zone number or a full address after the + filename. GoldED+ currently needs it's own special index files to + use the nodelists. These index files are created by GoldNODE. +

+

+ <file> Nodelist file. If the extension is .999 or a + wildcard (".*"), the newest file with a numeric + extension is used. + [zone/addr] Default zone or address for the nodelist (if no + zone info is present in the list itself). +

+

+ See also the USERLIST keyword, and the Nodelist Browsing chapter. +

+

+ NOTE: If you have nodelists with duplicate some of each others + nodes, the nodelist with the newest or most correct entries should + be placed LAST, and you should use the -D (remove duplicates) + option with GoldNODE. +

+
+ + + NODELISTWARN <yes/no> + +

+ (yes) +

+

+ If set to YES, GoldED+ will warn you during startup if one or more + nodelists are missing. Use NO to disable the warning if it bothers + you or you delete/pack your nodelists when the nodelists are + compiled. +

+

+ NOTE: GoldED+ can work fine with lookups etc. without nodelists as + long as it can access its own indexes (GOLDNODE.GX?). Only the + extra details will be missing. +

+
+ + + NODEPATH <path> + +

+ This is where GoldED+ and GoldNODE finds the nodelist files and + indexes. +

+
+ + + NODEPATHFD <path> + +

+ Path where GoldED+ can find the FrontDoor nodelist index files. +

+
+ + + NODEPATHIM <path> + +

+ Path to the InterMail nodelist index files. This is actually just + an alias name of the NODEPATHFD keyword, since InterMail and + FrontDoor uses the same nodelist index files. +

+
+ + + NODEPATHV7 <path> + +

+ Path where GoldED+ can find the Version 7 nodelist index files. +

+

+ NOTE: For the Version 7 nodelist index support, GoldED+ *requires* + that the files SYSOP.NDX, NODEX.NDX and NODEX.DAT are present. + None of these files may be missing and no other filenames are + supported. Multiple sets of index files are not supported. +

+
+ + + NODEV7FLAGS <flag> <value> + +

+ The Version 7 nodelist index does not by default define any + nodelist flags except the CM flag. Unfortunately the V7 index does + not point to the actual nodelist, it only has some bits which are + marked "reserved" in the specifications. The NODEV7FLAGS keyword + allows you to define the meaning of each of these bits. +

+

+ The <value> field can be a number or a bit number. Allowed numbers + are: 32, 64, 128, 256, 512, 1024, 2048, 8192 and 16384. Allowed + bit numbers are: b5, b6, b7, b8, b9, b10, b11, b13 and b14. +

+

+ Example: +

+

+ NODEV7FLAGS MO b5 + NODEV7FLAGS LO b6 + NODEV7FLAGS MN b7 + NODEV7FLAGS NC b8 + NODEV7FLAGS ZEC b9 + NODEV7FLAGS REC b10 + NODEV7FLAGS NEC b11 + NODEV7FLAGS XA b13 + NODEV7FLAGS XX b14 +

+

+ See also the NODEV7MODEM keyword for other nodelist flags. +

+

+ The nodelist flag bits in the index files are put in by your + Version 7 nodelist compiler. You must make sure that the nodelist + flag definitions in your nodelist compiler setup match those in + your GoldED+ setup. +

+
+ + + NODEV7MODEM <type> <value> + +

+ The Version 7 nodelist index does not by default define any + nodelist modem type flags. Unfortunately the V7 index does not + point to the actual nodelist, it only has some bits which are + marked "reserved" in the specifications. The NODEV7MODEM keyword + allows you to define the meaning of each of these bits. +

+

+ The <value> field can be a number or a bit number. Allowed numbers + are: 1, 2, 4, 8, 16, 32, 64 and 128. Allowed bit numbers are: b0, + b1, b2, b3, b4, b5, b6 and b7. +

+

+ Example: +

+

+ NODEV7MODEM VFC b0 + NODEV7MODEM HST b1 + NODEV7MODEM V34T b2 + NODEV7MODEM V32B b3 + NODEV7MODEM V34 b4 + NODEV7MODEM V42B b5 + NODEV7MODEM ZYX b6 + NODEV7MODEM ISDN b7 +

+

+ See also the NODEV7FLAGS keyword for other nodelist flags. +

+

+ The modem type bits in the index files are put in by your Version + 7 nodelist compiler. You must make sure that the modem type + definitions in your nodelist compiler setup match those in your + GoldED+ setup. +

+
+ + + ORGANIZATION <text> + +

+ Specifies the content of the RFC Organization header for Internet + messages. +

+
+ + + ORIGIN <"string"> + +

+ You can define many different origins for use in GoldED+. You can + select one of the defined origins from the Origin selection menu + (the READchangeorigin keyword), which is also available from the + EDITMENU and the EDITSAVEMENU. +

+

+ Leading and/or trailing spaces can be added by enclosing the + origin string in quotes. +

+

+ This keyword can be used globally and in a Random System group. +

+

+ NOTE: Origins defined in the Random System will always override + the global origins defined with this keyword, except when they are + selected from the EDITSAVEMENU. +

+
+ + + OUTBOUNDPATH <path> + +

+ Defines a Binkley-style outbound path. Currently only used for + WaZOO .REQ file requests (see FRQWAZOO). This should be the name + of your primary outbound without extension. +

+
+ + + OUTPUTFILE <file> + +

+ This is the default name of the file written using the + READwritemsg command. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + OVERLAY <ems/ext/disk> + +

+ (ems) +

+

+ This keyword controls where GoldED+ places the overlay swap blocks. + GoldED+ (the standard DOS version) uses the Borland VROOMM dynamic + overlays to decrease the resident executable code. +

+

+ See the DOSSWAP keyword for a warning note! +

+

+ Ignored by the 386, W32 and OS/2 versions. +

+
+ + + PCBOARDPATH <path> + +

+ Defines the default path where GoldED+ should look for the PCBoard + setup files if it can't find the PCBOARD environment variable. +

+
+ + + PCBOARDUSERNO <userno> + +

+ (0) +

+

+ Specifies the lastread set used in the PCBoard message base. +

+
+ + + PERSONALMAIL <startup,allnames> + +

+ Specifies options regarding the personal mail scan feature. None + of them are enabled by default. +

+

+ If the "startup" option is used, GoldED+ scans for personal mail + while doing the startup mail scan. +

+

+ If the "allnames" option is used, GoldED+ scans for mail to all the + USERNAME's instead of only the first. The default is not to scan + for personal mail at startup and to scan only for the first name. + This is faster. +

+

+ Example: +

+

+ PERSONALMAIL Startup, AllNames +

+

+ The example makes GoldED+ scan for personal mail to all your + USERNAME's at startup. +

+
+ + + PLAY <filename.ext/beepnoise> + +

+ See the EVENT keyword for a definition of the PLAY parameters. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + PRINTDEVICE <devicename> + +

+ (PRN) +

+

+ Defines the name of the device used for printing. PRN is the + default, but LPTx can also be used. Printers on COMx ports may + also work, but this has not been tested. +

+

+ Devices are opened in Write-Only text mode. The function has been + successfully tested to work with two popular peer-to-peer network + packages. +

+

+ You should NOT use a filename as devicename. Use the filename + option in the Write menu instead. +

+
+ + + PRINTFORMFEED <yes/no> + +

+ (yes) +

+

+ Used when printing messages. If enabled, it prints a Form Feed + (12d) character after each message. +

+
+ + + PRINTINIT <printstring> + +

+ This keyword defines the command string sent to your printer to + initialize it before the actual printing. +

+

+ The <printstring> can contain items like these: +

+

+ $Hex A hexadecimal string. + #Decimal A decimal (integer) number. + "String" Text string, enclosed in double quotes. + 'String' Text string, enclosed in single quotes. + Other chars Ignored. +

+
+ + + PRINTLENGTH <lines> + +

+ (60) +

+

+ Defines the number of lines per page for printing. A formfeed is + printed when every time PRINTLENGTH lines have been printed. +

+
+ + + PRINTMARGIN <characters> + +

+ (80) +

+

+ The right margin to use in printed messages. +

+
+ + + PRINTRESET <printstring> + +

+ This keyword defines the command string sent to your printer to + reset it after printing. +

+

+ <printstring> See the PRINTINIT keyword. +

+
+ + + QUOTEBLANK <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will put the QUOTESTRING on blank lines in the + quote. Otherwise blank lines are left blank in quotes. +

+
+ + + QUOTEBUFFILE <filename> + +

+ If used, it sets the default filename for the quotebuffer. If no + path is specified, the GOLDPATH is used. +

+

+ This keyword can be used globally and in Random System groups. +

+

+ NOTE: If this keyword is used in globally (in GOLDED.CFG), it + effectively disables the automatically named quotebuffers, as + described in the chapter about the QUOTEBUFMODE keyword. +

+
+ + + QUOTEBUFMODE <ask/append/overwrite> + +

+ (ask) +

+

+ Specifies what GoldED+ should do, if the quotebuffer file exists + already. +

+

+ Ask A menu asks you to select append/overwrite/skip. + Append Always append, no asking. + Overwrite Always overwrite, no asking. +

+

+ The "always overwrite" mode is not very useful I guess, but it's + there if you need it. +

+

+ The quotebuffer feature automatically creates special filenames + for the buffer file, using these guidelines: +

+

+ FORMAT FILENAME LOCATION + Fido GOLDED.QBF In the directory with the *.MSG's. + Hudson GOLDHxxx.QBF In the HUDSONPATH. + Squish filename.QBF Where the Squish area is. + Ezycom GLDxxxxx.QBF In the EZYCOMMSGPATH. + JAM filename.QBF Where the JAM area is. + Goldbase GOLDGxxx.QBF In the GOLDBASEPATH. + PCBoard filename.QBF Where the PCBoard area is. +

+

+ Note that they all have extension .QBF so that you can easily find + them. +

+
+ + + QUOTECHARS ["]<chars>["] + +

+ Defines up to 10 chars to recognize in addition to '>' as quote + string chars. This is most useful in gated Internet newsgroups, + where chars such as '|', ':' and ';' are sometimes used instead of + the '>'. +

+

+ This keyword can be used globally and in Random System groups. +

+

+ Example: +

+

+ Group Internet: + Member alt.*, comp.*, net.email + Quotechars "|:;" + Username odinn@winboss.dk + EndGroup +

+

+ The example is similar to the one I use myself (net.email is a + local netmail area where I import my gated e-mail from + winboss.dk). The username is my actual Internet address. +

+

+ Note that using additional quotechars such as '|' and ':' may + cause odd results when quoting in the cases when they are actually + NOT used in a message as quotechars. Consider for example quoting + a smiley :-) +

+
+ + + QUOTECTRL <Tearline,Origin,yes/no> + +

+ Specifies if you want quote tearline and/or origin in your + messages. +

+

+ This keyword can be used in random system groups. +

+
+ + + QUOTEMARGIN <chars> + +

+ (70) +

+

+ The margin to which quotes are wrapped. A negative value means + that the negative value is added to the DISPMARGIN (not + recommended). +

+
+ + + QUOTESPACING <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will automatically add blank lines before and + after a block of quoted text, if none are present already. This + improves the readability of some messages. +

+
+ + + QUOTESTRING <quotespec> + +

+ (" FL> ") +

+

+ With this keyword you define how you want the quotestring to look + in your quoted replies. +

+

+ The <quotespec> can contain these characters: +

+

+ F Replaced with the first letter of the first name. + M Replaced with the letters of the middle names. + L Replaced with the first letter of the last name. + > Required quote-char. + Spaces Cosmetics. +

+

+ Other characters are allowed but *not* recommended. +

+

+ This keyword can be used globally and in Random System Groups. +

+
+ + + QUOTEWRAPHARD <yes/no> + +

+ (yes) +

+

+ This keyword controls behaviour of quoted text (wrap or reflow). +

+
+ + + QWKBADMSGS <echoid> + +

+ Specifies the area where messages in unknown conferences are put. + If you get messages tossed here by accident, you must move them + manually to the correct area. If the badmsgs area is not defined, + the messages will silently disappear. Messages tossed to the + badmsgs area will have the control line "AREA:<bbsid>_<confno>" at + the top of the message. +

+
+ + + QWKCONFMAP <bbsid> ["]<confname>["] <echoid> + +

+ Defines the mapping between the BBSID and conference names in the + QWK packets and the echoid name of the conference as required by + GoldED+. You MUST define a mapping for every conference that you + subscribe to. If you don't, the messages will be tossed to the + area defined by QWKBADMSGS or disappear. The <bbsid> is the name + listed on line 5 in CONTROL.DAT after the comma. The <confname> is + the conference names listed on line 13 and on alternate lines + onwards in CONTROL.DAT. If a conference name contains embedded + spaces, the <confname> must be enclosed in double quotes, like + this: "Main Board". The area <echoid> must be already defined + either in an AREAFILE or using the AREADEF or AREA keywords. +

+
+ + + QWKEXPORTPATH <path> + +

+ Path where outgoing QWK reply files (BBSID.MSG) can be placed. +

+
+ + + QWKIMPORTPATH <path> + +

+ Path where incoming QWK packet files (CONTROL.DAT and + MESSAGES.DAT) can be found. +

+
+ + + QWKOPTIONS <bbsid> <options> + +

+ The <bbsid> is the BBSID (same as the name of the QWK packet) for + which the options will be active. The <options> can be any or a + combination of the following, separated by commas or spaces: +

+

+ KLUDGES/NOKLUDGES: Defaults to NOKLUDGES. Specifies whether or not + to include the FidoNet-style kludges at the top of messages when + exporting to QWK. NOTE: Unless you enable this option, GoldED+ will + *not* include kludges in your QWK packets. You should check if the + BBS supports kludges in QWK packets. If it does, please enable + this option. +

+

+ MIXCASE/NOMIXCASE: Defaults to NOMIXCASE. Specifies whether or not + the BBS allows mixed upper/lower case in the QWK message headers. + The default is to uppercase the TO and FROM header fields when + exporting to QWK packets. +

+

+ RECEIPT/NORECEIPT: Defaults to NORECEIPT. Specifies whether or not + the BBS supports return receipt requests (RRQ). If the RECEIPT + option is enabled, GoldED+ will insert "RRR" at the front of the + subject field if the RRQ attribute is set on your messages, when + exporting to QWK packets. +

+
+ + + QWKREPLYLINKER <cmd> + +

+ Commandline for a replylinker program to call after QWK import. +

+
+ + + QWKTOSSLOG <file> + +

+ Name of a file where GoldED+ puts the echoids of each area where + articles have been imported. The tosslog file is intended to be + used with a replylinker. If no path is given, it defaults to the + GOLDPATH. +

+
+ + + RA2USERSBBS <yes/no> + +

+ (detect) +

+

+ GoldED+ supports the two different formats of the Hudson USERS.BBS + file. With this keyword you can tell GoldED+ which format to use. +

+

+ If set to YES, the RA2 format is used. Otherwise if the it is set + to NO, the Hudson format is used. +

+

+ If this keyword is NOT used, GoldED+ tries to detect the format by + looking at the size of the USERS.BBS file and comparing this to + the record sizes of the RA2 and Hudson formats. +

+

+ If the size matches one and not the other, the format is detected + to be of the matching type. +

+

+ If the size matches both (which is quite normal), GoldED+ looks for + the RA environment variable and if found, in the RA config files + for the RA version. +

+

+ If the size does not match either of them (indicating a possibly + damaged userfile), GoldED+ exits with an error message and writes + in the log with details of the problem and an advise to run a + userbase packing utility. +

+

+ If used, this keyword should be placed in the configuration file + _after_ any AREAFILE keyword. +

+
+ + + RCVDISABLESCFM <yes/no> + +

+ (yes) + + If this keyword defined to "no" then GoldEd will recognize RRq + (receipt request) and/or CFM (confirmation) flag on messages with + RCV (received) flag set. After that RRq and CFM flags will be + resetted. It is useful if your netmail tracker sets RCV flag + before you actually read messages. +

+
+ + + REGISTERKEY + +

+ + + + REGISTERNAME + +

+ These keywords do nothing and won't do anything in the future. + They were used when GoldED+ was a Shareware product. +

+
+ + + REM + +

+ This keyword ignores everything behind it. This is useful to + comment a single line out. +

+
+ + + REPLYLINK <chain/direct> + +

+ Defaults to "direct" for JAM and "chain" for everything else. +

+

+ If set to "direct", GoldED+ will link your reply directly to the + original message. If set to "chain", it will link to the last + message in the reply chain. The default ("chain") is how GoldED+ + has done it in all previous versions. +

+

+ The advantage of the "direct" linking method is that you can + easily find the the original message the reply was for. Unless of + course you have later re-linked using a chain-linking replylinker + utility. I can recommend the utility SQLINK by Serge Terekhov. + SQLINK links Squish areas using the MSGID/REPLY kludges and makes + direct links instead of chain-linking on the subject line like + most other replylinkers do. There are probably also similar + replylinkers for other msgbase formats, I just don't know them. +

+
+ + + REPLYLINKLIST <fast/full> + +

+ (fast) +

+

+ When there is more than one reply to a msg in a JAM or Squish + area, GoldED+ pops up a list of the replies. This keyword affects + the contents of the list. +

+

+ In the "fast" mode, the list data is based solely on what can be + found by reading the message header, which is quite fast. + Unfortunately some software does not (or cannot) fill the header + with the correct origination address. In that case, set this + keyword to "full", which makes GoldED+ read and scan each message + for control data to get the origination address. That can be very + slow. +

+
+ + + ROBOTNAME <name> + +

+ A "robot" is a program on the Boss or Uplink system which responds + automatically to netmail messages. Usually the robot links or + unlinks echomail areas or distributed files. +

+

+ The following ROBOTNAME's are defined by default: +

+

+ AreaFix, AreaMgr, FileFix, AreaLink, AllFix, Raid, GEcho. +

+

+ If you write a netmail message where the TO: name is one of the + robot names, GoldED+ will ignore any template definition, and give + you a blank msg (possibly with a tearline) to edit. +

+
+ + + SCREENBLANKER <seconds> [BLACK] + +

+ (180) +

+

+ If non-zero, GoldED+ will blank the screen after the defined number + of seconds, and put a small moving window up instead. Hitting any + key (including shiftkeys) will return the screen to normal. If + zero, no blanking is done. +

+

+ If the additional parameter "BLACK" is given, GoldED+ will switch + the screen completely black instead of showing its own animated + screenblanker. This is useful if you have a monitor with + powersaving-features. +

+

+ Example: +

+

+ SCREENBLANKER 300 BLACK +

+

+ NOTE: This feature only works if KEYBMODE is set to "poll". +

+
+ + + SCREENMAXCOL <columns> + +

+ (0) +

+

+ On some systems, GoldED+ may no detect the correct display size. + With this keyword you can force a specific size. If zero, + autodetect is used. +

+
+ + + SCREENMAXROW <rows> + +

+ (0) +

+

+ On some systems, GoldED+ may not detect the correct display size. + With this keyword you can force a specific size. If zero, + autodetect is used. +

+
+ + + SCREENPALETTE <reg> <value> OR <reg> (red green blue) + +

+ You can change the color palette used in GoldED+. The palette has + 16 color registers, corresponding to the 16 colors from black (0) + to intense white (15). By changing the values in the palette + registers, it is possible to make any of the 16 colors a + completely different color. You can even make the background + colors intense, without using the intense color feature. There are + 64 different colors to chose from. +

+

+ To configure the palette colors in GoldED+, the SCREENPALETTE + keyword is used. There are two different syntaxes: +

+

+ SCREENPALETTE <reg> <value> + SCREENPALETTE <reg> (red green blue) +

+

+ So you can either compose the color value using separate red, + green, blue components, or directly use a precalculated value. The + red/green/blue values can only be in the range 0-3. +

+

+ These are the original palette values: +

+

+ SCREENPALETTE 0 (0 0 0) + SCREENPALETTE 1 (0 0 2) + SCREENPALETTE 2 (0 2 0) + SCREENPALETTE 3 (0 2 2) + SCREENPALETTE 4 (2 0 0) + SCREENPALETTE 5 (2 0 2) + SCREENPALETTE 6 (2 2 0) + SCREENPALETTE 7 (2 2 2) + SCREENPALETTE 8 (1 1 1) + SCREENPALETTE 9 (1 1 3) + SCREENPALETTE 10 (1 3 1) + SCREENPALETTE 11 (1 3 3) + SCREENPALETTE 12 (3 1 1) + SCREENPALETTE 13 (3 1 3) + SCREENPALETTE 14 (3 3 0) + SCREENPALETTE 15 (3 3 3) +

+

+ Copy these lines into your GOLDED.CFG and start experimenting! :-) +

+

+ If you have written a program to edit the palette and write a + GoldED+ palette setup file, please don't keep it a secret! :-) +

+
+ + + SCREENSHADOWS <yes/no> + +

+ (yes) +

+

+ If enabled, all relevant windows and menus in GoldED+ will have + shadows. +

+
+ + + SCREENSIZE <mode> + +

+ (Auto) +

+

+ Use this to force GoldED+ to use either 25 lines, 43/50 lines on + EGA/VGA, or even special videomodes supported by your SuperVGA + adapter (modes like 132x44, 100x40 or 80x60). +

+

+ The <mode> can be one of the following: +

+

+ Auto Use detected size. + 25 Switch to 25 lines. + 28 Switch to 28 lines. + 4350 Switch to 43/50 lines. + Mode <NN> Switch to videomode NN (a hexadecimal value). +

+

+ Please check your video adapter manual carefully before trying out + the Mode option. SELECTING A WRONG MODE CAN DAMAGE YOUR MONITOR!!! +

+

+ The Mode option is ignored in the W32 and OS/2 version. +

+
+ + + SCREENUSEBIOS <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will use standard BIOS calls for screen + updates. This is VERY slow, and should only be used if really + needed. Normally GoldED+ uses direct screen writes. +

+

+ This feature is only interpreted in the DOS version. +

+
+ + + SEARCHFOR ["]<string|string|..>["] + +

+ Defines a set of search strings, separated by the '|' character. + The search set defined here is the default when using the Alt-F/Z + search functions or the marking system. +

+

+ The '|' character works like an OR operator. That is, the search + is successful if one OR more of the strings are matched. The '&' + character is used as the logical AND operator. +

+

+ Please refer to appropriate section in user's guide for more + information. +

+

+ Older versions used the ';' semicolon character as a separator, + but that conflicts with the config reader which treats the + semicolon in a special way. The semicolon is still accepted as + separator char like '|', but if semicolons are used, you MUST + enclose the search strings with quotes or the config reader will + treat the first semicolon as the start of a comment. +

+

+ Examples: +

+

+ SEARCHFOR string1 + SEARCHFOR string1|string2|stringx + SEARCHFOR "string1;string2;stringx" + SEARCHFOR "string 1"|string2&stringx +

+

+ This keyword can be used globally and in Random System groups. +

+
+ + + SEMAPHORE <type> <file> + +

+ This keyword defines "semaphore" files, for use with other mailer + and/or mail processing software. +

+

+ The <type> can be one of the following: +

+

+ NETSCAN Empty netmail scan file (for D'Bridge/FD). + ECHOSCAN Empty echomail scan file (for D'Bridge). + EXPORTLIST Echoid-list of your new messages. + IMPORTLIST Echoid-list of new imported messages. +

+

+ The semaphore files are placed in the AREAPATH, if no path is + specified. +

+

+ See the example .CFG files for typical semaphore filenames. +

+

+ NOTE: You should not set SEMAPHORE EXPORTLIST to + %JAMPATH%\ECHOMAIL.JAM. This is incorrect and probably may cause + your mail processor to malfunction. Use the JAMPATH keyword + instead. +

+

+ GoldED+ can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED+ translates the path to + C:\POINT\path\name. +

+

+ NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED+ to recompile it's config, you must force + it with the -F or -FF command parameter. +

+

+ In addition, GoldED+ itself can watch for some semaphore files and + execute the appropiate function if it is in the arealist screen. + This can be useful if you have a multitasking system and you want + to "tell" GoldED+ that there is new mail in some areas and GoldED+ + should update its display correctly. +

+

+ In detail, there are +

+

+ EXITNOW <file> Quit immediately. + SCANALL <file> Scan all areas + SCANNETMAIL <file> Scan all netmail areas + SCANTHIS <file> Scan the areas listed in the file + PMSCANALL <file> PM-scan all areas + PMSCANNETMAIL <file> PM-scan all netmail areas + PMSCANTHIS <file> PM-scan the areas listed in the file + QWKIMPORT <file> Import QWK packets + QWKEXPORT <file> Export to QWK + SOUPIMPORT <file> Import SOUP packets + SOUPEXPORT <file> Export to SOUP + IDLETIME <seconds> Number of seconds between checks +

+

+ If SEMAPHORE IDLETIME is defined and non-zero, then GoldED+ will + check this list of semaphore files when the user has not pressed a + key in the specified number of seconds. The semaphores are only + checked when the arealist screen is active. If a semaphore file is + found, the file is deleted and then the action is performed. If no + path is given for the files, the GOLDPATH is assumed. +

+

+ Example: +

+

+ SEMAPHORE SCANALL SCANALL.NOW + SEMAPHORE IDLETIME 30 +

+

+ This causes GoldED+ to check every 30 seconds for the SCANALL.NOW + file in the GOLDPATH, and scan all areas if it's found. +

+
+ + + SERIALNO + +

+ Everything mentioned above about REGISTERKEY and REGISTERNAME + applied to this keyword. +

+
+SHAREMODE <yes/no/mode#> +

+ (yes) +

+

+ If enabled, GoldED+ opens all files in a SHARE.EXE compatible mode. +

+

+ The default share-mode is "Share Deny None", but another may be + specified directly if you give the mode number as the keyword + parameter (decimal). +

+

+ It is normally not necessary to change the default. +

+
+ + + SOUNDPATH <path> + +

+ (defaults to the GOLDPATH) +

+

+ Tells GoldED+ where to find the sound files for the PLAY and EVENT + keywords. +

+
+ + + SOUPBADMSGS <echoid> + +

+ Specifies the area where "bad messages" from SOUP packets can be + tossed. It should be an echomail or newsgroup area. +

+
+ + + SOUPEMAIL <echoid> + +

+ Specifies the area where Internet e-mails can be tossed. It must + be a netmail or e-mail area. +

+
+ + + SOUPEXPORTMARGIN <margin> + +

+ (76) +

+

+ This is the margin that GoldED+ will hard-wrap to when exporting to + SOUP packets. If you're getting complaints that your lines are too + long, you may want to set this to 70 or 60. +

+

+ NOTE: You should NOT enable EDITHARDTERM in email and newsgroups + that are exported to SOUP. If you do, your messages will probably + be exported with short line "droppings" after the wrapping margin. +

+
+ + + SOUPEXPORTPATH <path> + +

+ Path where outgoing SOUP reply packet files (REPLIES and + GOLD*.MSG) can be placed. +

+
+ + + SOUPIMPORTPATH <path> + +

+ Path where the incoming SOUP packet files (AREAS and *.MSG) can be + found. +

+
+ + + SOUPNEWSRCFILE <file> + +

+ Name with full path of the NEWSRC file which lists the newsgroups + you are connected to. GoldED+ uses the list to mark the matching + areas as newsgroups. These will then be scanned for outgoing mail + when starting a SOUP export. +

+
+ + + SOUPREPLYLINKER <cmd> + +

+ Commandline for a replylinker program to call after SOUP import. +

+
+ + + SOUPREPLYTO <internet-address> + +

+ Internet-Address other users should use when they respond to your + mails (Reply-To Headerline). +

+
+ + + SOUPTOSSLOG <file> + +

+ Name of a file where GoldED+ puts the echoids (newsgroup names) of + each area where articles have been imported. The tosslog file is + intended to be used with a replylinker. If no path is given, it + defaults to the GOLDPATH. +

+
+ + + SQUISHDIRECT <yes/no> + +

+ (no) +

+

+ If enabled, then in Squish areas, if the DIR (direct) attribute is + set on a message, GoldED+ will automatically set both the CRA + (crash) and HLD (hold) attributes when saving the message. +

+

+ According to the Squish Developers Kit, this is the way to tell + SquishMail that a message should be routed direct, because + SquishMail does not recognize the FLAGS kludge where the DIR + attribute is normally found. This keyword should probably only be + used with SquishMail (the mail processor) and then only when used + with Binkley or other so-called "static" mailers. DON'T use it + with FrontDoor! +

+
+ + + SQUISHSCAN <api/quick> + +

+ (quick) +

+

+ Specfies whether to use a quick scanning method which only looks + in the .SQI files. This will normally work fine, but may fail + slightly in obscure cases, especially when used with Squish 1.0x + or programs using the old version of the MSGAPI. If you suspect + problems, try to set this keyword to "api", which tells GoldED+ to + look in the .SQD file for an exact count of active msgs in the + .SQI file. +

+

+ NOTE: GoldED+ does NOT use the original MSGAPI by Scott Dudley. + Since version 2.50, a completely rewritten implementation is used. +

+
+ + + SQUISHUSERNO <index> + +

+ (0) +

+

+ This sets the lastread index number for the Squish *.SQL lastread + files. Lowest number is 0 (zero), highest is (in theory) 65534. +

+

+ If used, this disables the use of USER.BBS to find the index + number, and will in effect also stop GoldED+ from creating USER.BBS + or any new entries in it (useful in a single-user point system). + If a Squish msgbase is shared between several users, and you don't + want to have a USER.BBS (recommended in such a case), each user + must have a unique SQUISHUSERNO in their GOLDED/GOLDAREA.CFG. +

+
+ + + SQUISHUSERPATH <path>[file] + +

+ This keyword defines the path where GoldED+ can find and use/create + your USER.BBS file, which is used in connection with the Squish + area lastreads. You can also specify the exact filename if not + USER.BBS. +

+

+ If this path or filename is not defined, GoldED+ will instead take + the one specified with AREAFILE Squish or AREAFILE Maximus + (whichever comes first), or failing that, use the MAXIMUS or + SQUISH environment variables. If even that fails, the AREAPATH or + GOLDPATH is used. If AREAFILE Maximus is used, GoldED+ gets the + filename from MAX.PRM. +

+
+ + + STATUSLINECLOCK <yes/no> + +

+ (yes) +

+

+ If enabled, GoldED+ will display a clock in HH:MM:SS format in the + right side of the statusline. +

+

+ You can redefine the clock format with the language keyword + ST_STATUSLINETIMEFMT in GOLDLANG.CFG. See the Language Definition + chapter to details about the date/time codes you can use. +

+

+ NOTE: The clock will only run continuously if KEYBMODE is set to + "poll". +

+
+ + + STATUSLINEHELP <yes/no/nologo> + +

+ (no) +

+

+ If set to YES, GoldED+ will replace the "logo" in the left side of + the statusline with a text saying "F1 Help". This is for use in + "point package" setups where the user may be a complete novice, + maybe even to computers, and who needs to be guided to the help + screens. The "F1 Help" text is configurable with the + ST_STATUSLINEHELP language keyword (put it in GOLDLANG.CFG). +

+

+ If set to NO, GoldED+ will display it's logo (name and version) in + the left side of the statusline. +

+

+ If set to NOLOGO, GoldED+ will not display anything in the left + side. The middle part is extended to fill the space on the left + side. +

+
+ + + STYLECODES <yes/hide/no> + +

+ (hide) +

+

+ If enabled (yes or hide), GoldED+ will highlight text surrounded by + one of the following characters in a different color: '*' for bold + text, '/' for italic text, '_' for underlined text and '#' for + reversed text. These are commonly used "stylecodes" which add + emphasis to the text, without making it harder to read. Examples: + *This* will be shown in bold color, /this/ in italic color and + _this_ in underlined color. It is also possible to combine styles, + such as */this/*, in bolditalic color. +

+

+ The differ in yes and hide is that hide strips surrounding + stylecodes. +

+

+ Described values are specific to -asa. Official vesions starting + at 3.00beta3 has bug in implementation which causes GoldEd to + ignore this keyword. Realization of this keyword in -asa versions + compatible with official versions prior to 3.00beta3. +

+

+ To define the highlight colors, use COLOR STYLECODE. See the color + chapter for details. +

+
+ + + STYLECODEPUNCT <"charlist"> + +

+ (" !\"$%&()+,.:;<=>@[\]^`{|}~") + + + + STYLECODESTOPS <"charlist"> + +

+ ("") +

+

+ The STYLECODEPUNCT keyword specifies all the characters that + punctuates words. The stylecode line parser scans forward until it + meets one of these characters and then looks back to see if it + found a word with stylecodes around it. +

+

+ The STYLECODESTOPS keyword specifies characters which, if found + within the word to be highlighted, causes the highlight to be + cancelled. +

+

+ These keywords were added to allow users to experiment with the + characters for punctuation and stop for stylecode sequences. This + is mostly to illustrate the point that it is almost impossible to + make stylecodes work in every case you want without getting a lot + of false highlights too. Please keep in mind that stylecodes are, + and always will be, a primitive and very error-prone method for + adding highlights to message text. The defaults are: +

+

+ STYLECODEPUNCT " !\"$%&()+,.:;<=>@[\]^`{|}~" + STYLECODESTOPS "" +

+

+ Note that the double-quote (") must have the backslash (\) in + front of it - the sequence (\") is translated to a single ("). +

+
+ + + SWAPPATH <path> + +

+ (defaults to TEMPPATH) +

+

+ Defines where the swap file will be placed in case of disk + swapping in DOS shells. It is recommended that this points to a + RAM disk, if available. GoldED+ needs 3-500k free disk space for + the swapfile, depending on the overlay buffer size specified with + the -O commandline switch. +

+

+ This keyword is only interpreted by the DOS platform version. +

+
+ + + TAGLINE <string or filename> + +

+ Defines one or more taglines. A tagline collection filename can be + specified if prepended with an '@' character, like this: TAGLINE + @TAGLINE.LST. If a tagline collection file is used, GoldED+ will + create an index file for it the first time it is used or any time + the file is edited. The index file has the same name, but + extension ".SDX". The index file is an array of 32-bit long + integers, containing the offset of each line in the tagline + collection file. +

+

+ This keyword can be used globally and in a Random System group. +

+

+ Taglines defined in the Random System *always* overrides the + default global taglines defined with this keyword. +

+
+ + + TAGLINECHAR <char> + +

+ ('.') +

+

+ Defines the character GoldED+ uses when putting a tagline in your + message. The default is '.'. You should not change this default. + GoldED+ itself only recognizes taglines with '.' or '_' + (underscore). +

+
+ + + TAGLINESUPPORT <yes/no> + +

+ (yes) +

+

+ Allows you to turn off the internal tagline support, in case it + turns out to be too buggy or if you want to use one of the many + good external tagline utilties out there instead. +

+
+ + + TASKTITLE <string> + +

+ (@longpid) +

+

+ Sets window title in Win32 and OS/2 versions, ignored in other. +

+
+ + + TEARLINE <string> + +

+ (@longpid @version) +

+

+ Here you can define your default tearline. The tearline can be up + to 76 chars long (excluding the leading "--- "), but beware that + policies (such as FidoNet ECHOPOL1) may set a significantly lower + limit (around 30). +

+

+ This keyword can be used globally and in a Random System group. +

+

+ Tearlines defined in the Random System *always* overrides the + default tearline defined with this keyword. +

+

+ If your tearline does not contain at least the string "GoldED" or + "GED", GoldED+ will automatically insert it's PID kludge. See also + description of USEPID keyword. +

+
+ + + TEMPLATE <file> ["desc"] [match-address] + +

+ (GOLDED.TPL) +

+

+ You can define many different template files. The templates can be + switched using the READchangetemplate (Ctrl-T) popup menu or the + EDITMENU. +

+

+ The optional "desc" can be used to give the templates more + meaningful names like "International template" instead of + non-obvious names like "GOLDED.TPL". If a description is used, it + must appear before the match-address. It must always be enclosed + in quotes, even if it is only one word. +

+

+ The match-address is an address mask (wildcards allowed) which can + be used to tell GoldED+ to select that template if the destination + address on a message you write matches the match-address. The + matching will only take place if the TEMPLATEMATCH keyword has + been enabled. +

+

+ This keyword can be used globally and in a Random System group. In + Random System groups, only the <file> parameter can be used. +

+

+ Templates defined in Random System groups always override the + globally defined templates, except when selected from the EDITMENU + or when automatic template matching is in effect. +

+

+ To override the automatic template matching, start by selecting a + template manually using the READchangetemplate (Ctrl-T) command or + the EDITMENU. +

+

+ Currently only one match-address per template can be specified, + but you can specify several TEMPLATE keywords for the same file. +

+

+ Example: +

+

+ // Use DANSK.TPL for messages to Danish nodes/points. + TEMPLATE DANSK.TPL "Danish" 2:23/* + TEMPLATE DANSK.TPL "Danish" 2:234/* + TEMPLATE DANSK.TPL "Danish" 2:235/* + TEMPLATE DANSK.TPL "Danish" 2:236/* + TEMPLATE DANSK.TPL "Danish" 2:237/* + TEMPLATE DANSK.TPL "Danish" 2:238/* +

+

+ // Use INTERNET.TPL for messages to the WinBoss gateway + TEMPLATE INTERNET.TPL "Internet" 2:230/9316 +

+

+ // Use ENGLISH.TPL for messages to everywhere else + TEMPLATE ENGLISH.TPL "English" * +

+
+ + + TEMPLATEMATCH <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will select a template which matches the + destination address on messages that you write. This keyword can + be used globally or in random system groups. +

+
+ + + TEMPLATEPATH <path> + +

+ (defaults to the GOLDPATH) +

+

+ Defines the default path for msg templates. Use this if you want + to place templates in a path separate from the GOLDPATH. +

+
+ + + TEMPPATH <path> + +

+ Defines the directory where temporary files are placed by GoldED+ + and GoldNODE. +

+

+ This path should *NOT* point to a RAM disk or other volatile + media! +

+

+ GoldNODE uses this path to store a temporary file which can become + as large as the largest index file (GOLDNODE.GXN), so again, don't + point it to a small RAM disk. If GoldNODE cannot find a TEMPPATH, + it will use the NODEPATH instead. +

+
+TIMEOUT <seconds> +

+ (0) +

+

+ Similar to the screen blanking (SCREENBLANKER) feature, GoldED+ can + auto-exit after a specified period of time. Useful if you are in a + hurry (or didn't get enough sleep last night ;-), and run GoldED+ + from your mailer shell. The timeout value can be overridden with + the -T commandline option. +

+

+ NOTE: This feature only works if KEYBMODE is set to "poll". +

+
+ + + TIMEOUTSAVEMSG <yes/no> + +

+ (yes) +

+

+ If set to YES, GoldED+ behaves as usual: It saves the (perhaps + partially written) msg text in the internal editor to the msgbase + and exits. If set to NO, GoldED+ will save the msg text in + GOLDED.MSG just as if EDITAUTOSAVE function was in use and the + power went out. Next time you started GoldED+ and entered a msg, it + would detect the "lost" msg and ask you if it should be continued. +

+
+ + + TITLESTATUS <yes/no> + +

+ (yes) +

+

+ If enabled then brief status will be added to title. (Win32 and + OS/2 versions only) +

+
+ + + TWITMODE <mode> + +

+ (Blank) +

+

+ In GoldED+ you can define several "Twit" names, addresses or + subjects. With this keyword you can specify the action taken when + a Twit message is encountered. +

+

+ The <mode> can be one of the following: +

+

+ Show Show twit messages. + Blank Blank twit messages. + Skip Skip twit messages, unless to your USERNAME's. + Ignore Skip twit messages, always. + Kill Deletes twit messages, *without* confirmation! +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + TWITNAME <name/address> + +

+ With this keyword, you can specify "Twit" names and/or addresses. + When a Twit name/address is detected, the TWITMODE setting will + determine the action taken. +

+
+ + + TWITSUBJ <"string"> + +

+ With this keyword, you can specify "Twit" subjects. When a Twit + subject is detected, the TWITMODE setting will determine the + action taken. The subject string is searched in the entire subject + text, so you can specify a partial twit subject. Twit subjects are + limited to maximum 35 characters. +

+
+ + + TWITTO <yes/no> + +

+ (no) +

+

+ If enabled, GoldED+ will check both from- and to-names when + checking for twitnames. By default only the from-names are + checked. +

+

+ This is a global keyword and won't work as intended if used in a + random system group. +

+
+ + + USECHARSET <yes/no> + +

+ (yes) +

+

+ If set to no then GoldEd will not generate @CHRS and @CHARSET + kludges. +

+
+ + + USEFLAGS <yes/no> + +

+ (yes) +

+

+ If enabled, GoldED+ inserts the FLAGS kludge for certain extended + attributes, as defined in FSC-0053 by Joaquim H. Homrighausen, and + supported by FrontDoor, D'Bridge, IMail and other modern software. + GoldED+ uses FLAGS to emulate the Hold and Freq attributes which + are not defined in the Hudson message format. +

+
+ + + USEFWD <yes/no/ask> + +

+ (yes) +

+

+ If enabled, GoldED+ inserts the FSC-0092 kludges introduced by the + author of FleetStreet, Michael Hohner. These are +

+

+ FWDFROM The original From-Name + FWDORIG The original From-Aka + FWDTO The original TO-Field + FWDDEST The original TO-aka (only in netmails) + FWDSUBJ The original subject + FWDAREA The original areatag + FWDMSGID The original MSGID (useful for reply-linking) +

+

+ When forwarding, GoldED+ now adds these kludges, unless the + original message already contains them, in which case they are + preserved. When doing a normal reply (Alt-Q or Alt-R) to a message + with the FWD kludges, GoldED+ replies to the forwarder. To reply to + the from-name in the forwarded message, use the comment-reply + function (Alt-G). If the message contains the FWDAREA kludge, you + can reply to the forwarder in the original area (Alt-N) or reply + to the from-name in the original area (Alt-B). Note that it is not + possible to reply to the to-name of a message with the FWD + kludges, and it is also not possible to reply to the to-name of + the forwarded message (the FWDTO name). +

+
+ + + USEINTL <type> + +

+ (yes) +

+

+ The INTL kludge is normally only inserted in netmail messages, if + the origination zone is different from the destination zone (the + "Auto" setting), but on systems with many AKA's in the mailer, it + might be useful/necessary to add it ALWAYS (the "Yes" setting). + The "No" option should never be used. +

+

+ The <type> can be one of the following: +

+

+ Auto Only insert in inter-zone netmail. + Yes Always insert. Recommended and default. + No Never insert. +

+
+ + + USEMSGID <yes/no> + +

+ (yes) +

+

+ If enabled, the MSGID kludge is inserted in netmail and echomail, + and the REPLY kludge is inserted when replying to a msg with a + MSGID. +

+

+ The MSGID kludge is defined in FidoNet document FTS-9. +

+
+ + + USEPID <yes/no> + +

+ (no if GoldEd mentioned in tearline, yes otherwise) +

+

+ If disabled then @PID kludge will not be used in your messages + regardless of tearline contents. +

+
+ + + USERLIST <file> [zone/addr] + +

+ In addition to normal nodelist support, GoldED+ also supports the + "FIDOUSER.LST" style userlist format. The default zone is defined + by the first ADDRESS or AKA, but can be overridden by adding the + zone number or a full address after the filename. +

+

+ <file> Userlist file in FIDOUSER.LST format. + [zone/addr] Default address for the userlist (if no zone info + is present). +

+
+ + + USERLISTFILE <file> + +

+ (GOLDED.LST) +

+

+ GoldED+ can generate a list of all users in the current area. This + keyword defines the default name of the FIDOUSER.LST style + userlist output file generated with the READmakeuserlist command. +

+
+ + + USERNAME <name>[[,]< >address] + +

+ You can define many different names/aliases. When GoldED+ finds an + un-received message to one of your USERNAME's, it is marked as + received. Useful if you use alias names in some conferences. It is + possible to change the current name using the READchangeusername + popup menu. +

+

+ For msgbase formats with an associated user database, GoldED+ uses + the *first* defined USERNAME to look in the user database for + which lastread record to use. If your name is not found, it is + added and a new lastread record created. +

+

+ Example: +

+

+ USERNAME Odinn Sorensen, 2:236/77.999 +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + USETZUTC <yes/no> + +

+ (no) +

+

+ Activates usage of TZUTC kludge in your messages. You should + properly setup timezone information in your OS. For example, + in DOS you should set environment variable TZ to something + like this: +

+

+ TZ=MSK-3MSD,M3.5.0/02:00,M10.5.0/03:00 +

+

+ This line valid for Moscow, Russia. +

+

+ This option could be used in random system groups. +

+
+ + + UUDECODEPATH <path> + +

+ Specifies the path where files are placed when using the uudecode + feature. Files are placed in current directory if a path is not + specified. +

+

+ The specified path *must* exist ! +

+
+ + + VIEWHIDDEN <yes/no> + +

+ (no) +

+

+ Hidden lines are "unknown" kludge lines. If enabled, hidden lines + will be displayed (in a different color) when reading msgs. +

+

+ A hidden line is defined as a line which has the FidoNet kludge + char (^a, ASCII 1) as the first char and is not on the list of + internally or user defined known kludges. +

+

+ This keyword can be used globally and in a Random System group. +

+

+ IMPORTANT NOTE: +

+

+ In some conferences the hidden lines are used to give witty + comment "between the lines" in the plain text, but generally it is + considered a bad practice and should be avoided because it may + cause severe technical problems if a witty comment in a hidden + line happens to match a (perhaps experimentally) defined kludge + somewhere. It should also be noted that hidden lines are not kept + in their original places when used in the JAM msgbase. This is due + to the way the JAM specification stores FidoNet kludges. +

+
+ + + VIEWKLUDGE <yes/no> + +

+ (no) +

+

+ If enabled, known kludge lines will be displayed (in a different + color) when reading msgs. +

+

+ Known kludges are those defined internally in GoldED+ plus those + defined with the KLUDGE keyword. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + VIEWQUOTE <yes/no> + +

+ (yes) +

+

+ This is an experimental feature. It is similar to the VIEWHIDDEN + and VIEWKLUDGE keywords, but for quoted text. I implemented it + because I was annoyed with the excessive quoting often seen in + Internet newsgroups. When this keyword is set to NO, GoldED+ + attempts to trim down the quotes so that only the first line of + each quote block is shown. It is not always successful, sometimes + the result is not so useful. +

+

+ A key command has been added to supplement this feature: + READtogglequote. Suggested key assignment: Ctrl-V. Example: +

+

+ ^V READtogglequote +

+

+ Try it out if you are annoyed with excessive quotes. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + WHOTO <name> + +

+ This name is inserted in the TO: name field, when entering new + messages (not replies) in echomail or local areas. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + WILDCATUSERNO <userno> + +

+ Defines the lastread set used in the WildCat! 4.x message base. +

+
+ + + XLATCHARSET <importid> <exportid> <file> + +

+ This keyword defines character set translation table files. +

+

+ <importid> Charset import identifier. + <exportid> Charset export identifier. + <file> Charset translation table file. +

+

+ See the Character Translation chapter for details. +

+
+ + + XLATESCSET <import> <export> <escfile> + +

+ This keyword defines escape sequence translation table files. +

+

+ <importid> Escset import identifier. + <exportid> Escset export identifier. + <file> Escape sequence translation table file. +

+

+ See the Character Translation chapter for details. +

+
+ + + XLATEXPORT <charsetid> + +

+ Defines the export charset for your messages. See the Character + Translation chapter for details. +

+

+ This keyword can be used globally and in a Random System group. +

+

+ It can also be used in templates (the @xlatexport token). +

+
+ + + XLATIMPORT <charsetid> + +

+ (IBMPC) +

+

+ Defines the local charset for your machine. See the Character + Translation chapter for details. +

+

+ This keyword can be used globally and in a Random System group. +

+
+ + + XLATLOCALSET <charsetid> + +

+ (IBMPC) +

+

+ Use this keyword to specify the actual physical charset in effect + for text screen display. This was previously the hardcoded value + IBMPC, corresponding to the IBM codepage 437 (or the nordic + edition 865). +

+

+ NOTE: All charset translation files must translate from and to the + charset identified with the XLATLOCALSET keyword! +

+
+ + + XLATPATH <path> + +

+ This is the path where GoldED+ tries to find the XLATCHARSET and + XLATESCSET files. +

+
+ + + ZONEGATING <yes/no/ask> + +

+ (ask) +

+

+ When writing a netmail message to a destination in another zone, + you can either send the message directly (No) or via the local + ZoneGate (Yes). You can also be consulted each time (Ask). GoldED+ + won't ask if Cra or Hld attribute is set. +

+

+ + + + + + + Obsolete Keywords + +

+This is a list of keywords which were used in various older versions. +These keywords are now obsolete, either because they have been renamed +or replaced, or if they no longer have any function. Most of the +keywords are still active and remapped to the new names. +

+

+To check if you have obsolete keywords in your setup, run GoldED+ with +the -F -D commandline parameters. Then if you get a number of "Unknown +keyword" warnings, you should replace the old keywords with the new +ones or remove them. +

+

+ Old keyword: New keyword: +

+

+ AREAAUTOFREQ AREAFREQTO + AREABADMSGS SOUPBADMSGS + AREASORT AREALISTSORT + ASSIGNTO MEMBER + AUTOATTACH EDITAUTOATTACH + BEEPFACTOR (removed) + BLANKTIME SCREENBLANKER + BOARDNOS (removed) + CCATTRIB ATTRIBSCC + CCLIST CARBONCOPYLIST + CFMATTRIB ATTRIBSCFM + CHANGEDATE EDITCHANGEDATE + CHANGEPROMPT (removed) + CHARSET XLATCHARSET + CLEARKEYS (removed) + COLOUR COLOR + COMMENTNOISE BEEPCOMMENT + COOKIEFILE (removed) + CRLFTERM EDITCRLFTERM + DELORIG ASKDELORIG + DISPMSGLIST MSGLISTFIRST + DISPMSGLISTFAST MSGLISTFAST + DISPSTYLECODES STYLECODES + ECHOATTRIB ATTRIBSECHO + ECHOINFO CTRLINFOECHO + EDITMARGIN (removed) + EDITORVERSION (removed) + ELIMSNOW (removed) + ESCSET XLATESCSET + EXCLAREA AREAEXCL + EXPORTCHARSET XLATEXPORT + EXTKEYS (removed) + FIDOLASTREADNO FIDOUSERNO + FIELDCLEAR EDITFIELDCLEAR + FILECHECK (removed) + FILECHECKALL (removed) + FREEAREA (removed) + FREETEAR (removed) + GOLDEDCFM CONFIRMFILE + GOLDEDLOG LOGFILE + GOLDEDLST USERLISTFILE + GOLDEDMSG EDITORFILE + GOLDEDNAM NAMESFILE + GOLDEDPRN OUTPUTFILE + GOLDHELP (no longer documented) + GOLDKEYS (no longer documented) + GOLDLANG (no longer documented) + GOLDRAND (no longer documented) + GOLDXLAT (no longer documented) + HARDLINE EDITHARDLINE + HARDLINES EDITHARDLINES + HWMARKS (removed) + INCLAREA AREAINCL + INTERNALEDITOR EDITINTERNAL + LASTREAD FIDOLASTREAD + LASTREADUSER FIDOUSERNO + LISTWRAP (removed) + LOCALATTRIB ATTRIBSLOCAL + LOCALCHARSET XLATIMPORT + LOCALHIGHLIGHT (removed) + LOCALINFO CTRLINFOLOCAL + LOCALNOISE (removed) + MAPDRIVE MAPPATH + MATCHAKA AKAMATCH + MAXCOLS SCREENMAXCOL + MAXMSGSIZE EDITMSGSIZE + MAXROWS SCREENMAXROW + MIXCASE EDITMIXCASE + MULTIQBBS (removed) + NETATTRIB ATTRIBSNET + NETINFO CTRLINFONET + NETTEAR CTRLINFONET performs similar function + NEXTAREA AREANEXT + NEXTMSGS (removed) + NODELISTPAGEBAR (removed) + NOISEFACTOR (removed) + OVERLAYEMS OVERLAY performs similar function + OVERLAYEXT OVERLAY performs similar function + PAGEBAR (removed) + QBBSINCRESCAN (removed) + QBBSPATH HUDSONPATH + QBBSREBUILD (removed) + QBBSSCAN (removed) + QMSGPATH HUDSONPATH + REALMSGNO (removed) + REBUILD (removed) + RENAREA AREARENAME + REPLYRE EDITREPLYRE + RIGHTMARGIN DISPMARGIN + SAVEMENU EDITSAVEMENU + SAVETIME EDITAUTOSAVE + SAYBIBI (removed) + SCANAREA AREASCAN + SCREENELIMSNOW (removed) + SCREENUSEANSI (removed) + SHADOWS (removed) + SHARE SHAREMODE + SHOWTWITS TWITMODE + SIGNALFILE SEMAPHORE + SOUNDDEVICE (removed) + SPACEQUOTES (removed) + SPELLCHECKER EDITSPELLCHECK + STACKKEYS KEYBSTACK + STARTECHO AREASTART + SWAPALL DOSSWAP + SYSOP USERNAME + TABSIZE DISPTABSIZE + TAGLINEFILE (removed) + TIMESLICE (removed) + TIMEZONEOFFSET USETZUTC performs similar function + UNDELETELINES EDITUNDELETE + USEBIOS SCREENUSEBIOS + XPLIST CROSSPOSTLIST +

+

+ + + + + + Location Dependent Configuration Keywords + +

+The following configuration keywords are location dependent and should +be placed in a particular order in the configuration file(s). Keywords +that are *not* listed can be placed anywhere you want. +

+

+The keywords are listed in groups of those that depend on each other. +They are listed in the recommended order within each group. The order +between the groups is not important, with one noted exception. +

+

+Name/Address/Areas: + USERNAME + ADDRESS + AKA + ATTRIBSNET Specifies default attributes for AREAFILE etc. + ATTRIBSECHO As above. + ATTRIBSLOCAL As above. + FIDOMSGTYPE + PCBOARDPATH Recommended if you use PCBoard. + MAPPATH + AREARENAME Rename occurs before AREAEXCL/INCL. + AREAEXCL + AREAINCL + AREAISEMAIL + AREAISNEWS + AREAPATH Default path for the AREAFILE's. + AREAFILE + RA2USERSBBS Overrides AREAFILE RemoteAccess. + AREADESC Add description and more to some AREAFILE's. + AREA Overrides areas in AREAFILE's. + AREADEF As above. +

+

+Paths: + GOLDPATH + TEMPPATH MUST be in GOLDED.CFG. Used only by GoldNODE. + SWAPPATH +

+

+Nodelists: MUST be below ADDRESS/AKA and ONLY in GOLDED.CFG! + NODEPATH + NODELIST + USERLIST + EXCLUDENODES Remember to replace "ALL" with '*'. + INCLUDENODES As above. +

+

+Colors: + INTENSECOLORS Selects a default intense colorset if enabled. + COLORSET Selects a default colorset. + COLOR +

+

+External utils: + EXTERNOPTIONS + EXTERNUTIL +

+

+Character translation: + XLATPATH + XLATCHARSET + XLATESCSET +

+

+Random System: + GROUP Starts a group. + MEMBER Defines areas that are members of the group. + <Group Items> See the Random System chapter for a list. + ENDGROUP Ends a group. +

+

+ + + +Message Attributes Reference +

+This is a list and description of all message attributes that are +supported by GoldED+ in the keywords that accept attribute settings or +can be displayed in the header. +

+

+A/S Archive/sent. +ARQ Audit request. +ATT File attached. +CFM Confirmation receipt requested. +COV Fax cover letter. +CRA Crash - high priority mail. +DEL Deleted. +DIR Direct. Don't route this message. +FAX Fax image attached. +FRQ File request. +GRP Group message. +HIR Fax hi-resolution image. +HLD Hold for pickup. +HUB Host- or Hub-route message. +IMM Immediate - Send message NOW! +K/S Kill/sent. Delete message automatically after it is sent. +KFS Kill/file/sent. Delete attached files after they are sent. +LET Fax letterhead. +LOC Local. Message was written on your system. +LOK Lock. Prevents send/delete/purge/editing. +ORP Orphan. Could not be sent because destination node is unknown. +PRN Msg has been printed. Specific for Squish (bitvalue 00040000h). +PVT Private. Message may only be read by the addressee and author. +R/O Read only. Used in area definitions to prevent writing. +RCV Received. Read by the addressee. +RRC Return receipt. +RRQ Return receipt requested. +RSV FTS-1 reserved (unused) attribute. +SIG Fax signature. +SNT Sent. Message has been sent or exported from the msgbase. +TFS Truncate/file/sent. Truncate files to zero length when sent. +TRS Transit. Message passing through, not for you. +UNS Unsent message. +URQ Update file request. +XMA Xmail. Attach does not conform to the ARCmail 0.60 standard. +ZON Zonegate. Route through zonegate if possible. +

+

+ + + +Area Configuration +

+GoldED offers a wide variety of methods for defining message areas. +You can define each area manually in the GOLDED.CFG file (or an +INCLUDE'ed GOLDAREA.CFG file), or you can tell GoldED+ to read the area +setup files of many popular BBS/mailer/mail processor packages. +

+

+For manual definition of areas, use the AREA or AREADEF (recommened) +keywords. +

+

+For external area configuration, the general syntax for the AREAFILE +keyword is: +

+

+ AREAFILE <programname> [path or filename(s)] [-options] +

+

+Available options: +

+

+-NoChk +

+

+ Normally GoldED+ will check the areafile timestamps when starting + up, and recompile the configuration if a file was changed. If this + option is given for any AREAFILE, those areafiles will not be + checked. This can be useful in cases like TosScan, GEcho, IMail + and several others which "touch" their files every time they run. +

+

+-S<sortspec> +

+

+ If you are *not* using the global AREALISTSORT keyword for sorting + all the areas, you can sort the areas of each AREAFILE separately. + See the AREALISTSORT keyword for the definition of <sortspec>. +

+

+If no path is specified, the appropriate environment variable or the +AREAPATH is used to find the files. +

+

+The <programname> can be one of the following: +

+ + + AdeptXBBS + +

+ Reads the AdeptXBBS configuration files. +

+

+ Looks for the ADEPTXBBS environment variable. +

+
+ + + AreasBBS + +

+ GoldED+ is can handle a wide variety of AREAS.BBS type files. It + can read and distinguish between the old CONFMAIL style with paths + for *.MSG areas, the Hudson/Goldbase style with board numbers, the + Squish style with "$basename" and the JAM style with "!basename". +

+

+ The disadvantage of using an AREAS.BBS is that there are no area + descriptions. The echoid is used as description instead. However, + GoldED+ will use any text behind a semicolon on definition lines as + description. This may or may not be compatible with mail + processors, so be careful. A better solution may be to use the + AREAFILE Echolist to add descriptions from a separate file. +

+

+ One or more AREAS.BBS files may be specified on the same line. +

+
+ + + Concord + +

+ Support is planned but not yet implemented. +

+
+ + + D'Bridge + +

+ Reads the DBRIDGE.AA1/.AA2 files (for version 1.30) or the + DBRIDGE.ADF of the later versions. +

+

+ Looks for the "DBRIDGE" and "DB" environment variables. +

+
+ + + Dutchie + +

+ Reads the DUTCHIE.ARE file. +

+

+ Looks for the "DUTCHIE" environment variable. +

+
+ + + Echolist + +

+ Reads a simple ascii-text file containing an echolist in this + format: +

+

+ <echoid> <description> +

+

+ or DZ-format (requires -DZ switch): +

+

+ [Status], Tag, Comment, Moderator's Name, Address,[Flags] +

+

+ This feature adds descriptions to already existing areas in + GoldED+. Example: +

+

+ AREAFILE AreasBBS AREAS.BBS + AREAFILE EchoList ECHOLIST.TXT + AREAFILE EchoList echo5020.lst -dz +

+

+ Descriptions for unknown echoids are ignored. Blank lines and + lines beginning with characters which are illegal in echoids (such + as ';') are also ignored. +

+

+ Additional switch -SqaFix could be used to read echolist and groups + from SqaFix configuration file: +

+

+ AREAFILE Squish C:\SQUISH\ + AREAFILE EchoList C:\SQUISH\SQAFIX.CFG -SqaFix +

+
+ + + Ezycom + +

+ Reads CONFIG.EZY and MESSAGES.EZY. Supports Ezycom 1.02 and 1.10g, + but not 1.01. +

+

+ Looks for the "EZY" and "TASK" environment variables. +

+
+ + + FastEcho + +

+ Reads the FASTECHO.CFG file. Supports version 1.10 up to 1.46. +

+

+ Looks for the "FASTECHO" environment variable. +

+
+ + + Fidoconfig + +

+ Reads fidoconfig (used in Husky Project software). Supports + version 0.15. Used parser is more powerful than original from + fidoconfig, due to it strictly follows specification from proposal + and implements all features from there. Additionaly it implements + groups not described in proposal but used in in library. +

+

+ Looks for the "FIDOCONFIG" environment variable. +

+
+ + + FidoPCB + +

+ Reads FIDOPCB.CFG. Supports version 1.x. +

+

+ Looks for the "FIDOPCB" environment variable. +

+
+ + + FMail + +

+ Reads FMAIL.CFG and FMAIL.AR. Supports versions 0.92, 0.98, 1.0g, + and 1.20. +

+

+ Looks for the "FMAIL" environment variable. +

+
+ + + FrontDoor + +

+ Reads the SETUP.FD/FD.SYS and FOLDER.FD/FOLDER.SYS files. If you + want the real echoid's attached to the areas, you will also need + to supply the filename of the relevant AREAS.BBS file(s). Supports + versions 1.99c and 2.xx. +

+

+ Looks for the "FD" environment variable. +

+
+ + + GEcho + +

+ Reads SETUP.GE and AREAFILE.GE. Supports versions 1.00, 1.02, + 1.10, 1.11 and 1.20. +

+

+ Looks for the "GE" environment variable. +

+
+ + + IMAIL + +

+ Reads the IMAIL.CF and IMAIL.AR files. Supports version 1.60, + 1.7x and 1.8x. +

+

+ Looks for the "IMAIL" environment variable. +

+
+ + + InterMail + +

+ Reads the FD.SYS/IMSYS.CFG and FOLDER.CFG/IMFOLDER.CFG files. + Supports version 2.26 and newer. +

+

+ Looks for the "IM" environment variable. +

+
+ + + LoraBBS + +

+ Reads the CONFIG.DAT and SYSMSG.DAT files. Supports version 2.33, + 2.40 and possibly others. +

+

+ Looks for the "LORA" and "LORABBS" environment variables. +

+
+ + + Maximus + +

+ Reads the MAX.PRM and AREA.DAT or MAREA.DAT files. Compatible (or + should be) with both the old (1.xx) and (2.xx) and new (3.xx) + formats. If your AREA.DAT is named differently, you must supply + the correct filename. +

+

+ Looks for the "MAXIMUS" environment variable. +

+
+ + + ME2 + +

+ Reads the old ME2 editor AREADESC.ME2 file and AREAS.BBS file(s). + You must supply the names of both files. +

+
+ + + Opus + +

+ Reads the Opus 1.1x SYSTEM??.DAT files or the Opus 1.7x SYSMSG.DAT + file. +

+

+ Looks for the "OPUS" environment variable. +

+
+ + + ParToss + +

+ Reads the ParToss configuration file. +

+
+ + + PCBoard + +

+ Reads the PCBOARD.DAT, CNAMES.@@@ and CNAMES.ADD files. Supports + version 14.x and 15.x, up to and including 15.22. Note that, + depending on the version, echoid's may not be read from this + format. If the echoid is not available, the description is used as + echoid, after conversion to uppercase and spaces to underscores. +

+

+ Looks for the "PCBOARD" environment variable. +

+
+ + + Portal + +

+ Reads the PORTAL*.CFG and PORTAL.ARE files. +

+

+ Looks for the "POPCMDLINE" environment variable. +

+
+ + + ProBoard + +

+ Reads MSGAREAS.PB. Supports version 2.0. +

+

+ Looks for the "PB" environment variable. +

+
+ + + QEcho + +

+ Reads /etc/qecho/AreaList. Supports version patched by Eugene + Sorochinsky for JAM messae base support. +

+
+ + + QFront + +

+ Reads QORIGIN.DAT and QECHOS.DAT. Supports version 1.13b. +

+

+ Looks for the "QFRONT" environment variable. +

+
+ + + QuickBBS + +

+ Reads the CONFIG.BBS or QUICKCFG.DAT and MSGCFG.DAT files. To get + the real echoid's, you must also supply the filename of the + relevant AREAS.BBS. +

+

+ Looks for the "QUICKBBS" and "QBBS" environment variables. +

+
+ + + RaEcho + +

+ Reads AREAS.RAE. Supports version 1.00 and 1.01. +

+

+ Looks for the "RAECHO" environment variable. +

+
+ + + RemoteAccess + +

+ Reads the MESSAGES.RA file. To get the real echoid's, you must + also supply the filename of the relevant AREAS.BBS. Supports + versions 0.xx, 1.xx, 2.0x and 2.5x. +

+

+ Looks for the "RA" environment variable. +

+
+ + + Squish + +

+ Reads SQUISH.CFG and AREAS.BBS (if used). Supports version 1.0x + and 1.1x. The "Include <filename>" feature of Squish 1.10 is also + supported. +

+

+ The optional /G switch specifies the default group of the imported + areas, i.e. /g=G or /g=#103. +

+

+ Looks for the "SQUISH" and "MAXIMUS" environment variables. +

+
+ + + SuperBBS + +

+ Reads CONFIG.BBS, SCONFIG.BBS and BOARDS.BBS. Supports version + 1.16 and 1.17. +

+

+ Looks for the "SUPERBBS" and "SBBS" environment variables. +

+
+ + + timEd + +

+ Reads TIMED.CFG and any included file. Also reads the + configuration from other mail software defined in TIMED.CFG. +

+

+ Looks for the "TIMED" environment variable. +

+
+ + + Termail + +

+ This is for the Terminate Mail system (Termail). GoldED+ does + currently only support Termail 4.00 und 5.xx style .CFG-files. +

+

+ Reads TM.CFG and any AREAFILE (an AREAS.BBS type file) defined + there. +

+

+ NOTE: If you use this, you must start GoldED+ in the Termail + directory, because the standard TM configuration files use + relative paths. +

+

+ Looks for the "TM" environment variable. +

+
+ + + TosScan + +

+ Reads the FD.SYS/SETUP.FD and AREAFILE.FD files. Supports version + 1.00 and FrontDoor 1.99c and 2.xx. +

+

+ Looks for the "FD" environment variable. +

+
+ + + WaterGate + +

+ Reads the WTRCFG.TDB and AREABASE.TDB files. Supports version + 0.93. +

+
+ + + WMail + +

+ Reads the WMAIL.PRM and AREAS.PRM files. Supports version 2.2. +

+

+ Looks for the "WMAIL" environment variable. +

+
+ + + XMail + +

+ Reads the AREAS.XM file. Supports version 1.00. +

+

+ Looks for the "XM" environment variable. +

+

+ + + + +The Random System +

+With the Random System, you can define area-specific sets of origins, +tearlines, templates, usernames and many other items. If +more than one item of each type is specified, a random one is picked - +a Random System. This is a very useful feature when (for example) +participating in conferences with different languages. +

+

+The Random System is built on the idea of "groups". A group is a +collection of "items", belonging to the group. You can assign one or +more echomail areas, designated by their echoid's to a group. Groups +can also be specified for just a single echo, and DOS/4DOS-style +wildcards can be used to simplify the assignment of echoes with common +strings in their name, such as *.DK, SIG.* and so on. In this way, you +could for example setup one group for all national echoes, another for +special local echoes, a third for international echoes etc. +

+ + + Defining Groups + +

+The general syntax of a group definition is: +

+

+GROUP <id>[:] + ; items go here + [Member <id list>] +ENDGROUP +

+

+The Group <id> can be one of three things: +

+

+1. A group letter or #number, matching the group letters or numbers + used in the AREAFILE's of D'Bridge, GEcho, IMAIL, TosScan and many + others. To use this feature, you need to enable the AREAFILEGROUPS + keyword. +

+

+2. An individual echoid or echoid mask (wildcards can be used). The + items are then simply defined below the Group line. +

+

+3. A group label, terminated by a colon (:). The group items are + defined below the Group line. Echoes are assigned to the group by + adding one or more Member statements. +

+

+You can't assign a group to another group. It will not harm, but it +also won't work :-) +

+

+The order of groups is very important. GoldED+ scans the groups from +the top down. This means that the most general groups must be placed +at the bottom and exceptions (individual areas for example) must be +placed at the top. +

+
+ + + Defining Random Items + +

+The random items are defined much like in the main GoldED+ +configuration file. +

+

+If more than one of each item is defined within a group, those items +will be picked randomly (hence the name "Random System"), while GoldED+ +collects items when entering an area. +

+

+Random Item Keywords: + AKA + AKAMATCHING + AREACOPYDIRECT + AREACOPYTO + AREAFREQDIRECT + AREAFREQTO + AREAREPLYDIRECT + AREAREPLYTO + AREAYOUWROTETO + ATTRIBUTES + CTRLINFO + EDITHARDTERM + EDITMIXCASE + EDITREPLYRE + FORCETEMPLATE + INPUTFILE + INTERNETADDRESS + INTERNETGATE + INTERNETMSGID + INTERNETRFCBODY + LOADLANGUAGE + MSGLISTDATE + MSGLISTFAST + MSGLISTFIRST + MSGLISTHEADER + MSGLISTWIDESUBJ + NETNAME + NICKNAME + ORGANIZATION + ORIGIN + OUTPUTFILE + PLAY + QUOTEBUFFILE + QUOTECHARS + QUOTESTRING + QUOTEWRAPHARD + SEARCHFOR + TAGLINE + TAGLINECHAR + TEARLINE + TEMPLATE + TEMPLATEMATCH + TWITMODE + USEFWD + USERNAME + USETZUTC + VIEWHIDDEN + VIEWKLUDGE + VIEWQUOTE + WHOTO + XLATEXPORT + XLATIMPORT +

+

+See the Configuration Keyword Reference chapter for details about each +keyword. +

+
+ + + Random System Example + +

+Below is an example of how a Random System could be setup. Note how +the letter group 'D' goes first, followed by the explicit group +definitions for the NERDS and FOO echoes. Then comes the more general +groups (those with Label:'s), where the echoes are assigned with one +or more Member statements. At last there is the catch-all "Group *", +which works as the default group. +

+

+=== Cut, GOLDRAND.CFG === +

+

+Group NERDS ; For the NERDS echo. + Origin "I am a Nerd. Take me to your Loser!" +

+

+Group FOO ; This group is *only* for the FOO echo. + Tearline FooED @rev + Origin "Foo-ing my day away" +

+

+Group FooEchoes: + Member *FOO* ; Use wildcards to catch any other foo echo. + Tearline FooED @rev + Origin "This is a Foo-lish origin" +

+

+Group FidoNet: + Member NET_DEV, WORLDPOL, INTERCOOK + Member GREEN.029, C_ECHO, C_PLUSPLUS + Origin "Fight-O-Net? Good name..." + Template FIDONET.TPL + Whoto Everyone +

+

+Group SigNet: + Member SIG.* ; The wildcard is VERY handy here ;-) + Origin "To SIG or not to SIG..." + Template SIGNET.TPL +

+

+Group D ; Letter D for Danish echoes. + Template DANSK.TPL +

+

+Group * ; This is default group + Origin "Yet another forgotten echo" +

+

+=== Uncut === +

+

+See the example GOLDRAND.CFG in the ADVANCED archive for a real-life +setup similar to the one I use myself. +

+

+ + + + + + + Color Configuration + +

+Color configuration in GoldED+ is a bit complicated, and you probably +have to experiment quite a bit, if you want make your own setup. For +your convenience, I have added a number of example color setups, +provided by some of my many good users. I suggest you try them all and +use the one that suits you best, perhaps tuning it a bit to your +taste. +

+

+The COLOR keyword uses the following syntax: +

+ + + COLOR <window> <part> <colors> + +

+ <window> AREA, ASK, BACKGROUND, BRAG, HEADER, HELP, INFO, MENU, + READER, SHADOW, STATUS. +

+

+ <part> BLOCK, BORDER, BTYPE, EDIT, HIDDEN, HIGHLIGHT, INPUT, + KLUDGE, NOSELECT, ORIGIN, QUOTE, SELECTOR, TEARLINE, + TITLE, WINDOW. +

+

+The <colors> are composed of [blinking] <ink> [on <paper>]. +

+

+ <ink> Black, Blue, Green, Cyan, Red, Magenta, Brown, LGrey, + DGrey, LBlue, LGreen, LCyan, LRed, LMagenta, Yellow, + White. +

+

+ <paper> Black, Blue, Green, Cyan, Red, Magenta, Brown, LGrey. +

+

+For monochrome setups we instead have: +

+

+ <ink> Normal, Highlight, Reverse, Underline. +

+

+The SHADOW color does not need a <part>, because it is global. +

+

+The paper color always defaults to Black if not specified. +

+

+If <part> is "BTYPE", the <color> is a value in the range 0-3, which +defines the type of lines used when drawing menus and windows: +

+

+BTYPE 0 is single horizontal and single vertical lines. +BTYPE 1 is double horizontal and double vertical lines. +BTYPE 2 is single horizontal and double vertical lines. +BTYPE 3 is double horizontal and single vertical lines. +

+

+The default border type is always BTYPE 0. +

+

+The following is a description of the different window parts: +

+
+ + + Various general color items + +

+ SHADOW Shadow below windows and menus. + STATUS WINDOW Status line at the bottom. + BACKGROUND WINDOW Background for the startup window. + BACKGROUND BORDER Overscan color (currently DOS only). +

+

+ <anything> PAGEBAR Pagebar (scrollbar). +

+

+ The PAGEBAR color specifially sets the color of the pagebars + (scrollbars) in GoldED+. A pagebar color can currently be set for + AREA, READER and MENU. Note that BORDER will set both the BORDER and + PAGEBAR colors, so remember to place the PAGEBAR color below the + BORDER color. +

+
+ + + Startup screen / logo window + +

+ BRAG WINDOW The Copyright window. + BRAG BORDER Lines around the Copyright window. + BRAG TITLE The logo text. + BRAG HIGHLIGHT The inner logo lines. + BRAG BLOCK The outer logo lines. + BRAG BTYPE Copyright window border type. +

+
+ + + Area Selection Menu + +

+ AREA WINDOW Descriptions, the top line (inc. search). + AREA BORDER Lines. + AREA TITLE Titles on the border. + AREA SELECTOR Selection bar. + AREA HIGHLIGHT The color for the area marks. + AREA BTYPE Window border type. +

+
+ + + Message Header + +

+ HEADER WINDOW Header text. + HEADER BORDER Lines. + HEADER TITLE Titles on the border. + HEADER INPUT Message number input field. + HEADER EDIT Header input fields. + HEADER HIGHLIGHT Marks. + HEADER BTYPE Window border type. + HEADER FROM Header From field. + HEADER TO Header To field. + HEADER SUBJECT Header Subject field. +

+

+ The FROM/TO/SUBJECT colors supplement the HEADER WINDOW color. Note + that WINDOW will also set the FROM/TO/SUBJECT colors, so remember to + place the new colors below it. +

+
+ + + Message Text + +

+ READER WINDOW Normal message text. + READER BORDER The Pagebar. + READER QUOTE (Odd) Quoted lines. + READER QUOTE2 (Even) Quoted lines. + READER CURSOR Character at cursor pos. (int. editor). + READER KLUDHIDD Kludges and hidden lines. + READER TEARORIG Tearline and Origin. + READER BLOCK Block color (internal editor). + READER BTYPE Window border type. + READER HIGHLIGHT Search highlight in the message text. + READER KLUDGE Known kludges. + READER HIDDEN Hidden lines. (Unknown kludges). + READER SIGNATURE Internet-Style signatures ("-- "). + READER TAGLINE Taglines. (Only the one just above tearline). + READER TEARLINE Tearline. + READER ORIGIN Origin. +

+

+ The KLUDGE/HIDDEN colors replaces the old KLUDHIDD color. Note that + KLUDHIDD will set both the KLUDGE and HIDDEN colors, so remember to + place the new colors below it if you keep the old definition. +

+

+ The TAGLINE color is the color of taglines. GoldED+ detects a tagline + if it starts with "..." or "___" and is just above the tearline or + origin. +

+

+ The TEARLINE/ORIGIN colors replaces the old TEARORIG color. Note + that TEARORIG will set both the TEARLINE and ORIGIN colors, so + remember to place the new colors below it if you keep the old + definition. +

+
+ + + Miscellaneous Smaller Menus + +

+ ASK WINDOW Menu items. + ASK BORDER Lines. + ASK TITLE Menu title. + ASK SELECTOR Selection bar. + ASK NOSELECT Non-selectable menu items. + ASK HIGHLIGHT Hotkeys. + ASK BTYPE Window border type. +

+
+ + + Miscellaneous Larger Menus (Browser Windows) + +

+ MENU WINDOW Menu items. + MENU BORDER Lines. + MENU TITLE Menu title. + MENU SELECTOR Selection bar. + MENU NOSELECT Non-selectable menu items. + MENU HIGHLIGHT Hotkeys/marks. + MENU UNREAD When a msg is unread. + MENU UNREADHIGH Additional highlight of to/from. + MENU UNSENT When a msg is unsent. + MENU UNSENTHIGH Additional highlight of to/from. +

+
+ + + Help Screens + +

+ HELP WINDOW Help text. + HELP BORDER Lines. + HELP SELECTOR Current keyword. + HELP HIGHLIGHT Other keywords. + HELP BTYPE Window border type. +

+
+ + + Pop Up Information Windows + +

+ INFO WINDOW Window text. + INFO BORDER Lines. + INFO TITLE Info title. + INFO BTYPE Window border type. +

+
+ + + Stylecodes + +

+ STYLECODE ALL All stylecodes at once. + STYLECODE B *Bold* + STYLECODE I /Italic/ + STYLECODE BI /*BoldItalic*/ + STYLECODE U _Underline_ + STYLECODE BU _*BoldUnderline*_ + STYLECODE IU /_ItalicUnderline_/ + STYLECODE BIU _/*BoldItalicUnderline*/_ + STYLECODE R #Reverse# + STYLECODE RB *#ReverseBold#* + STYLECODE RI /#ReverseItalic#/ + STYLECODE RBI /*#ReverseBoldItalic#*/ + STYLECODE RU _#ReverseUnderline_# + STYLECODE RBU _*#ReverseBoldUnderline#*_ + STYLECODE RIU _/#ReverseItalicUnderline#/_ + STYLECODE RBIU _/*#ReverseItalicUnderline#*/_ +

+

+ Note that stylecode color definitions must be placed below COLOR + READER WINDOW, because it overrides the COLOR STYLECODE definitions. +

+

+See the GEDCOL*.CFG and GEDMON*.CFG files for examples of color +configuration. +

+

+ + + + + + + The Message Template + +

+The message template gives you a ready-made skeleton for writing your +messages in the editor. The template is one of GoldED+'s many strong +features. With this, you can eliminate the tedious typing of greetings +etc etc. GoldED+ also provides a number of replacement strings, +"tokens", to dynamically add message specific information to the +template. +

+

+As in the configuration file, a semicolon (;) first on the line makes +the line a comment. Any other line is put into the editor file, after +token expansion. Tokens are not case sensitive. +

+

+The following is a list of the tokens available: +

+ + + Conditional tokens + +

+ (these are replaced with a null string) +

+

+@changed Line is only inserted in Changed msgs (from others). +@comment Line is only inserted in Reply-Comments. +@echo Line is only inserted in Echomail. +@forward Line is only inserted in Forwarded messages. +@local Line is only inserted in Local messages. +@moderator Line is only inserted if substring "moderator" appeared in + from line. +@moved Line is only inserted in Reply-Moved messages. +@net Line is only inserted in Netmail. +@new Line is only inserted in New messages (not replies). +@position Specifies the starting line for the editor cursor. +@quotebuf Line is only inserted in Quotebuffered msgs. +@quoted Line is only inserted in Quoted replies. +@reply Line is only inserted in Non-Quoted Replies. +

+
+ + + Insert tokens + +

+ (anything else on the line is ignored) +

+

+@attrib <attributes> - Adds specific message attributes. +@include <filename> - Inserts the file. +@forcefrom <"from"> - sets message FROM: field, even if non-empty + (see @setfrom) +@forcesubj <"subject"> - sets message SUBJ: field, even if non-empty + (see @setsubj) +@forceto <"to"> - sets message TO: field, even if non-empty + (see @setto) +@loadlanguage Loads a partial language config file. +@message Inserts the original message (in Forward & Change). +@quote Inserts a quote of the original message. +@random [random.txt] - Inserts random text. +@setfrom <"from"> - Sets the message FROM: field. +@setsubj <"subject"> - Sets the message SUBJ: field. +@setto <"to"> - Sets the message TO: field. +@xlatexport <charset> - Sets the export charset. +

+
+ + + Replacement tokens + +

+ (replaced with message specific data): +

+

+@c3daddr Current user 3D (boss) address. +@caddr Current user address. +@cdate Current date. +@cdesc Current area description. +@cecho Current echoid. +@cfname Current user first name. +@clname Current user last name. +@cname Current user name. +@cpseudo Current pseudonym given by NICKNAME keyword, or @cfname. +@ctime Current time. +@ctzoffset Current timezone offset (if available and enabled). +@d3daddr Destination 3D (boss) address. +@daddr Destination address. +@dfname Destination first name. +@dlname Destination last name. +@dname Destination name. +@dpseudo Destination pseudonym (see addressbook), or @dfname. +@f3daddr Current from 3D (boss) address. +@faddr Current from address. +@ffname Current from first name. +@flname Current from last name. +@fname Current from name. +@fpseudo Current from pseudonym (see addressbook), or @ffname. +@longpid Long program id. "GoldED", "GoldED/2" or "GoldED/386". +@o3daddr Original 3D (boss) address. +@oaddr Original address. +@odate Original date. +@odesc Original area description if moved, else current. +@oecho Original echoid if moved, otherwise current. +@ofname Original first name. +@ofrom Original RFC "From" headerline. +@olname Original last name. +@omessageid Original RFC "Message-ID" headerline. +@omsgid Original MSGID kludge content. +@oname Original name. +@opseudo Original pseudonym (see addressbook), or @ofname. +@origin The current global or Random System origin. +@os2slash "/2" if running GoldED+/2. Empty otherwise. +@osslash same as above. +@otime Original time. +@otzoffset Original timezone offset (if available and enabled). +@oto Original RFC "To" headerline. +@pid Short program id. "GED", "GED/2" or "GED386". +@pseudo pseudonym (see addressbook), or @tfname. +@rev The revision number (in the form mmdd). +@serialno Emptiness. +@subject The message subject line. +@t3daddr Destination to 3D (boss) address. +@taddr Destination to address. +@tagline The current global or Random System tagline. +@tearline The current global or Random System tearline. +@tfname Destination to first name. +@tlname Destination to last name. +@tname Destination to name. +@tpseudo Destination to pseudonym (see addressbook), or @tfname. +@ver The simple version number (in the form x.yy) +@version The complete release version number of GoldED+. +@_caddr Current user address (fixed width: 19 chars). +@_cname Current user name (fixed width: 34 chars). +@_daddr Destination address (fixed width: 19 chars). +@_dname Destination name (fixed width: 34 chars). +@_oaddr Original address (fixed width: 19 chars). +@_oname Original name (fixed width: 34 chars). +@_taddr Destination to address (fixed width: 19 chars). +@_tname Destination to name (fixed width: 34 chars). +

+

+Tokens dealing with names may optionally have two parameters (each +parameter enclosed in curve brackets): your name and opponent name, +destination name additionally accepts third parameter - WhoTo name. +Here is example on how this feature could be used: +

+

+ @oname{I}{You} wrote to @dname{me}{you}{everyone}: +

+

+The template text begins at the first non-comment line. +

+

+See the included GOLDED.TPL for example usage. +

+

+If you need to put some text which contains one of these tokens into a +template file, use an extra '@' in front of the token. +

+

+Example: +

+

+ Internet: somebody@veryhot.com +

+

+would produce +

+

+ Internet: somebody2.51yhot.com (because @ver is a token) +

+

+so write it like this instead: +

+

+ Internet: somebody@@veryhot.com +

+

+The double '@' will then be translated to a single, and token +translation skips past the @token. +

+

+ + + + + + + The Online Help System + +

+GoldED has a built-in context sensitive help system, tied to the <F1> +key (one of the very few keys that cannot be reconfigured). It +contains a complete keyboard reference and help for most situations. +It is current not as complete or sophisticated as I'd like it myself, +but this may be improved in future versions. +

+

+You can completely redefine the help screens if you wish - the +GOLDHELP.CFG file is a plain ASCII text file which contains all help +definitions. The help file is split into several help categories. Here +is an example of a couple of defined help categories: +

+

+ *B 1,Help Category 1 + help text help text help text + help text help text help text + *P + help text help text help text + help text help text help text + *E +

+

+ *B 2,Help Category 2 + help text help text help text + help text help text help text + *P + help text help text help text + help text help text help text + See also: ^Help Category 1^ + *E +

+

+The "*B" indicator specifies the beginning of a help category. The +format is "*B helpcatnumber[,helpcatname]". In GoldED+ the help +categories are numbered 1000-9999, split into more or less logical +groups. See the help file for assignments. There should be only one +space between the "*B" and the help category number. The help category +name is only required for cross-references. If there are no +cross-references to that help category, then you can leave the +helpcatname parameter out. +

+

+The "*P" indicator specifies a page break and is optional. You may +have as many page breaks as you'd like. The "*E" indicator specifies +the end of the help category. The "*B", "*P", and "*E" indicators must +all begin in the first column. These indicators and the help category +name are case insensitive (can be in lowercase, uppercase, or mixed). +

+

+In the definition of Help Category 2, you will notice the +crossreference to Help Category 1. All cross-referencing is done by +embedding the cross- reference category name (not number) inside +carats (^). If you need to display a carat inside the help file, use a +double carat (^^). +

+

+Any text contained outside of the "*B" and "*E" is treated as +comments. If an "*E" is not found, then the end-of-file will be +treated as an "*E". +

+

+Not all of the help categories in this help file are actually used in +the current version of GoldED+. The ones not used are empty, except for +a two-line "header". +

+

+The usable dimensions of the help window are 60 columns by 16 lines. +In the help file there is a model of the actual window. +

+

+ + + + + + Character Translation + +

+GoldED implements several different proposals for character +translation in imported and exported messages: +

+ + + FSC-0050 "Charset Identifier" + +

+ by Thomas Sundblom. + + + + FSC-0051 "I51" + +

+ by Thomas Gradin. + + + + FSC-0054 "CHARSET proposal" + +

+ by Duncan McNutt. + + + + No FSC "Composed Characters" + +

+ by Andre van de Wijdeven. +

+

+FSC-0050 is currently known to be implemented in the OPMED 3.xx +message editor, and in Opus 1.7x. It uses the same identifier as +FSC-0054 (a ^aCHARSET kludge), but is a lot simpler (but not +necessarily better). +

+

+The "I51" and "CHARSET" proposals are in the process of being merged +to one proposal, which should combine the advantages of both. They are +both based on using the LATIN-1 (also known as ISO 8859-1) character +set for extended ASCII. The LATIN-1 set is the same set used by +Windows 3.xx, Amiga and many other non-PC computers. In addition to +LATIN-1, I51 defines a set of so-called escape sequences for +characters not found in the LATIN-1 set. +

+

+"Composed Characters" became quite popular in Holland, but the author +decided to drop his proposal because it relied on escape sequences +using the so called "soft-cr" (141d, 8Dh) character. GoldED+ will +continue to support Composed as long as it seems necessary. +

+

+If you want to know more about the details, I suggest you read the +proposals or contact the authors. +

+

+GoldED currently supports two types of translation tables, the *.ESC +files and the *.CHS files. +

+
+ + + The ESC translation tables + +

+The *.ESC files are used for import translation of the escape +sequences defined in I51 and Composed Characters. +

+

+In the ESC files, the semicolon is used for comments. The *first* +non-comment line defines the charset the escape code are mapped TO. +This is normally IBMPC, and should not be changed. Any other +non-comment line is treated as an escape sequence definition with this +syntax: +

+

+ <esc1><esc2><space><map chars>[; comment/description] +

+

+Leading spaces are *not* allowed in ESC files. <esc1> and <esc2> are +the two characters that define the escape sequence. <space> is ignored +and can be used to make the table look better. <map chars> defines the +local representation of the escape sequence, up to three characters. +Normally you would only map to one extended ascii character. The map +chars can be either the characters themselves, or decimal or +hexadecimal numbers of the form "\d<dec>" or "\x<hex>" (like in the C +programming language). +

+
+ + + The CHS translation tables + +

+The *.CHS files are used for import and export translation of the +CHARSET type character sets, and export of I51 and Composed escape +sequences. +

+

+The CHS files uses the format of the raw text files provided in the +CHARSET3.ZIP example implementation of FSC-0054. Study some of the +files provided if you want to know how to define them. +

+

+The two keywords XLATESCSET and XLATCHARSET are used to define which +files belong to what import and export set. You can define more than +one import and export set for each file. +

+

+The keyword XLATIMPORT defines which charset you have on your own +machine - this would normally be "IBMPC". It can be useful to change +this (using the Random System) in areas where another character set +than IBMPC is the dominant (like Amiga or MacIntosh, whatever). +

+

+The keyword XLATEXPORT defines the charset your messages should be +exported to, if any. +

+

+Confused? Yeah, I know - this is a confusing subject, and my +implementation and documentation is not perfect. Normally you will not +have to worry about it. Turn it off completely if you don't understand +it. +

+

+ + + + + + + Keyboard Command Reference + +

+Most of the GoldED+ keyboard commands can be reached with just one +keystroke. To ease operation for experienced users of other message +editors, GoldED+ comes with several sets of keys for each of the +keyboard commands - direct non-shifted keys, Alt/Ctrl-keys and +function keys. Many of these key assignments will be familiar for +users of Msged, Msged/Q, ME2 and FM. +

+

+The following is a list of all keyboard commands, sorted by type and +alphabetically, using the format +

+

+ <command> <short description> +

+

+This list is also available in the context-sensitive help system on +the <F1> key. +

+

+It is possible to almost completely redefine the keyboard - this in +done in the GOLDKEYS.CFG file, which also handles macro definition +(see later). +

+ + + Arealist commands + +

+: +

+

+AREAabort Abort the arealist. +AREAaskexit Exit GoldED+, prompt for final decision. +AREAboardnos Toggle sequential areas vs. board numbers. +AREAcatchup Point the lastread pointer to the last message + in the current area. +AREAdosshell Shell to DOS. +AREAdropmsgmarks Unmark all msgs in selected areas. +AREAgotofirst Move selection bar to first area. +AREAgotolast Move selection bar to last area. +AREAgotonext Move selection bar to next area. +AREAgotoprev Move selection bar to previous area. +AREAheat Heat highwatermarks. +AREAjump Move selection bar to next marked area. +AREAjumpnextmatch Move selection bar to next matching area. +AREAquitnow Exit immediately, no questions asked. +AREAscan Scan areas. +AREAscanpm Scan areas for personal mail. +AREAselect Enter the reader for the selected area. +AREAselectmarks Select which set of area marks should be used. +AREAsoundkill Stops currently played sound file. +AREAtoggle Toggle mark on the selected area. +AREAtouchnetscan Touches the SEMAPHORE NETSCAN file. +AREAwritegoldlast Write a fresh copy of GOLDLAST.LST +AREAzap Zap highwatermarks. +

+
+ + + Internal editor commands + +

+: +

+

+EDITabort Abort editing this message - ask first. +EDITanchor Set a block "anchor" on the current line. +EDITaskexit Exit from GoldED+ - ask first. +EDITblockdown Extend block area one line down. +EDITblockend Extend block area to the end of line. +EDITblockhome Extend block area to the beginning of line. +EDITblockleft Extend block area one character left. +EDITblockpgup Extend block area one screen up. +EDITblockpgdn Extend block area one screen down. +EDITblockright Extend block area one character right. +EDITblockup Extend block area one line up. +EDITcleardeletebuf Clears the undelete buffer. +EDITclearpastebuf Clears the cut'n'paste buffer. +EDITcopy Copies the block to the cut'n'paste buffer. +EDITcopyabovechar Inserts character same as in the same position + in previous line. +EDITcut Cut the block to the cut'n'paste buffer. +EDITdelchar Delete the char at the cursor position. +EDITdelete Delete the block. +EDITdeleteeol Delete from cursor position to end of line. +EDITdelleft Delete the char to the left of the cursor. +EDITdelline Delete the current line. (Copied to the +EDITdelltword Delete the word to the left of the cursor. +EDITdelrtword Delete the word to the right of the cursor. +EDITdosshell Shell to DOS. +EDITdupline Duplicates the current line. +EDITexitmsg Drop this message - NO ASKING! DANGEROUS! +EDITexporttext Exports the current block to a file. +EDITgobegline Move cursor to beginning of line. +EDITgobotline Move cursor to the bottom line in the display. +EDITgobotmsg Move cursor to the last line in the message. +EDITgodown Move cursor down to next line. +EDITgoeol Move cursor to the end of the line. +EDITgoleft Move cursor one position left. +EDITgopgdn Move cursor one page of lines down. +EDITgopgup Move cursor one page of lines up. +EDITgoright Move cursor one position right. +EDITgotopline Move cursor to the top line in the display. +EDITgotopmsg Move cursor to the first line in the message. +EDITgoup Move cursor up to the previous line. +EDITgowordleft Move cursor to the previous word. +EDITgowordright Move cursor to the next word. +EDITheader Edit the message header, attributes etc. +EDITimportquotebuf Imports the current quote buffer. +EDITimporttext Import text file into this message. +EDITkillquotes (ignored) +EDITloadfile Load the message file saved with EDITsavefile. +EDITlookupcursor Lookup name/node at cursor position. +EDITlookupdest Lookup TO: node. +EDITlookuporig Lookup FROM: node. +EDITnewline Terminate paragraph and/or add a new line. +EDITpaste Paste a previously cut block at the cursor. +EDITquitnow Quit GoldED+ immediately - no asking. +EDITreflow Reflows the current text or quote paragraph. +EDITsavefile Saves the current message as a file. +EDITsavemsg Save this message. +EDITsoundkill Stops currently played sound flie. +EDITspellcheck Calls an external spell checker for the msg. +EDITtab Add spaces to the next tab-stop. +EDITtabreverse Remove spaces to the prev tab-stop. +EDITtogglecase Toggle the case of the cursor character. +EDITtoggleinsert Toggle insert mode. +EDITtolower Change the cursor character to lowercase. +EDITtoupper Change the cursor character to uppercase. +EDITundelete Undelete previously deleted lines. +EDITzapquotebelow Deletes quotes below. +

+
+ + + File selection commands + +

+: +

+

+FILEabort Abort file selection. +FILEaskexit Exit GoldED+ - ask first. +FILEdosshell Shell to DOS. +FILEgotofirst Go to first file. +FILEgotolast Go to last file. +FILEgotonext Go to next file. +FILEgotoprev Go to previous file. +FILEmark Mark file. +FILEmarkall Mark all files. +FILEquitnow Quit GoldED+ immediately. +FILEselect Select the marked file(s). +FILEtogglemark Toggle file mark. +FILEunmark Unmark file. +FILEunmarkall Unmark all files. +

+
+ + + Message lister commands + +

+: +

+

+LISTabort Abort message lister. +LISTaskexit Exit GoldED+ - ask first. +LISTdosshell Shell to DOS. +LISTgotobookmark Go to BookMark message. +LISTgotofirst Go to first message. +LISTgotolast Go to last message. +LISTgotonext Go to next message. +LISTgotoprev Go to previous message. +LISTmarkingoptions Marking menu. +LISTquitnow Quit GoldED+ immediately. +LISTselect Go to reader at the selected message. +LISTtogglebookmark Toggle BookMark on the selected message. +LISTtoggledate Toggle date column content. +LISTtogglemark Toggle Mark on the selected message. +LISTtogglewidesubj Toggle between wide and short subject. +

+
+ + + Nodelist browser commands + +

+: +

+

+NODEabort Abort nodelist browsing. +NODEaskexit Exit GoldED+ - ask first. +NODEdosshell Shell to DOS. +NODEgotofirst Go to first node. +NODEgotolast Go to last node. +NODEgotonext Go to next node. +NODEgotoprev Go to previous node. +NODEquitnow Quit GoldED+ immediately. +NODEselect Select node. +

+
+ + + Message reader commands + +

+: +

+

+READaddressbookadd Add current/marked mail writer(s) to + addressbook. Ask first. +READaskexit Exit GoldED+, prompt for final decision. +READchangeaka Change default AKA address for current area. +READchangeattrs Change the attributes of the current message. +READchangemsg Change current message. +READchangeorigin Change default origin for the current area. +READchangetagline Change default tagline. +READchangetemplate Change default template. +READchangeusername Change default username. +READchangexlatimport Change default import charset. +READcommentmsg Comment-Reply to message. (Reply to TO name). +READcopymoveforward Enter the Copy/Move/Forward function menu. +READdecreasemargin Decrease message margin. For test purposes. +READdeletemsg Delete current/marked message(s). Ask first. +READdosshell Shell to DOS. +READfidorenumber Renumber Fido/Opus *.MSG files. +READfilerequest Generate a filerequest from the current msg. +READfindall Find string(s) in message header and text. +READfindheader Find string(s) in message header. +READgotobookmark Go to the "BookMark" message. +READgotofirstmsg Go to the first message in the area. +READgotolastmsg Go to the last message in the area. +READgotomsgno Go to a specific message number. +READgotonextarea Go directly to the next area. +READgotonextmsg Go to the next message. +READgotonextunread Go to the next unread message. +READgotoprevarea Go directly to the previous area. +READgotoprevmsg Go to the previous message. +READgotoprevunread Go to the previous unread message. +READgotoreplies Choose from the next messages in the replylink. +READgotoreply1st Go to the first reply to this message. +READgotoreplynext Go to the next reply to this message. +READgotoreplyprev Go to the parent message in the replylink. +READincreasemargin Increase message margin. For test purposes. +READlookupdest Lookup TO: node. +READlookuporig Lookup FROM: node. +READmakeuserlist Generate FIDOUSER.LST of users in the area. +READmakepathreport Added "path report" feature. The output file + can be processed by a RDDT (Route Diagram + Drawing Tool) utility. +READmarkingoptions Enter the marking menu. +READmessagelist Enter the message lister. +READmovecommentmsg Comment-Reply in another area. +READmovequotemsg Quote-Reply in another area. +READmsgcontinue Page down or go to next message. +READmsgend Display last part of current message. +READmsghome Display first part of current message. +READmsglinedown Scroll message display. +READmsglineup Scroll message display. +READmsgpgdn Page message display. +READmsgpgup Page message display. +READnewarea Enter the area selection screen. +READnewmsg Start a new message. +READquitnow Exit GoldED+ immediately, no questions asked. +READquotebuf Append quote of the msg to the quotebuffer. +READquotemsg Quote-Reply to message. (Reply to FROM name). +READreplymsg Reply to the current message, without quoting. +READsearch Launches the search engine. +READsoundkill Stops currently played sound file. +READthreadtree Enter the Message Threading lister. +READtogglebookmark Toggle a "BookMark" on the current message. +READtogglehexdump Toggle hexdump mode. For debugging purposes. +READtogglehiddklud Toggle display of Hidden and Kludge lines. +READtogglehidden Toggle display of Hidden lines. +READtogglekludge Toggle display of Kludge lines. +READtogglemark Toggle a message mark on the current message. +READtogglemarkread Toggle "Read Marked" mode. +READtogglepagebar Toggle the "PageBar" feature. +READtogglequote Toggle display of quoted lines. Experimental. +READtogglerot13 Toggle ROT13 encryption for the current msg. +READtogglerealmsgno Toggle between seq. or real message numbers. +READtogglestyles Toggle Disable/Show/Show+Strip of STYLECODES. +READtoggletwits Toggle Twit display - Show/Blank/Skip/Ignore. +READtouchnetscan Touches the SEMAPHORE NETSCAN file. +READtouchsemaphore Popup touch a manually entered semaphore file. +READuserbase Launches the addressbook. +READuudecode UUdecodes the current message. +READwritemsg Write message(s) to file or printer. +

+
+ + + Key undefine commands + +

+: +

+

+AREAundefine +EDITundefine +FILEundefine +LISTundefine +NODEundefine +READundefine +

+

+The undefine commands can used to undefine any of the built-in default +keyboard definitions. +

+

+See the Key Reference below for a list of the key symbols you can use +in keyboard redefinition. +

+

+ + + + +Macros and Keystacking +

+GoldED has a simple keyboard macro facility, which you can use to +automate certain common operations. In addition, a "keystacking" +facility allows you to create simple automatic macros on the fly. +

+

+The macro definition syntax is modelled after the syntax used in the +QEdit text editor: +

+

+ <assignment-key> Macro <commands or keys> + <assignment-key> AreaMacro <commands or keys> + <assignment-key> EditMacro <commands or keys> + <assignment-key> FileMacro <commands or keys> + <assignment-key> ListMacro <commands or keys> + <assignment-key> NodeMacro <commands or keys> + <assignment-key> ReadMacro <commands or keys> +

+

+Macros are defined in the GOLDKEYS.CFG file, where you can also find +several examples. +

+

+By using the word "Auto" as <assignment-key>, you can even define a +special macro which will be automatically executed when you start +GoldED. +

+

+Keystacking is a special form of auto-macros. You simply specify a +bunch of keys to be "stacked" in the (special internal) keyboard +buffer for sequential execution. +

+

+You can either specify a default set of keystacking in the .CFG +configuration file, or override any default keystacking by typing the +keystack definitions at the GoldED+ commandline or the GEDCMD +environment variable. +

+

+See the Key Reference chapter for a list of the key symbols you can +use in macros and keystacking. +

+

+ + + + + + Key Reference + +

+Below is the list of key symbols recognized by GoldED+ for +keyboard/macro definition and keystacking. +

+

+Unshifted function keys +

+

+ F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 +

+

+Shift-function keys +

+

+ #F1 #F2 #F3 #F4 #F5 #F6 #F7 #F8 #F9 #F10 #F11 #F12 +

+

+Alt-function keys +

+

+ @F1 @F2 @F3 @F4 @F5 @F6 @F7 @F8 @F9 @F10 @F11 @F12 +

+

+Ctrl-function keys +

+

+ ^F1 ^F2 ^F3 ^F4 ^F5 ^F6 ^F7 ^F8 ^F9 ^F10 ^F11 ^F12 +

+

+Alt-Numbers +

+

+ @0 @1 @2 @3 @4 @5 @6 @7 @8 @9 +

+

+Alt-Letters +

+

+ @A @B @C @D @E @F @G @H @I @J @K @L @M + @N @O @P @Q @R @S @T @U @V @W @X @Y @Z +

+

+Ctrl-Letters +

+

+ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M + ^N ^O ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z +

+

+Insert/Delete +

+

+ Ins ^Ins @Ins + Del ^Del @Del +

+

+Home/End +

+

+ Home ^Home @Home + End ^End @End +

+

+Page up/down +

+

+ PgUp ^PgUp @PgUp + PgDn ^PgDn @PgDn +

+

+Cursor left/right +

+

+ Left ^Left @Left + Right ^Right @Right +

+

+Cursor up/down +

+

+ Up ^Up @Up + Down ^Down @Down +

+

+Misc other keys +

+

+ Esc ^Grey* Key5 Space Tab #Tab @Tab BackSpace ^BackSpace + @BackSpace Enter ^Enter @Enter +

+

+Note that some of the Alt-keys, especially the cursor-related keys and +the F11/F12 keys, are "extended" keys normally only available on +systems with an extended keyboard bios. However, GoldED+ uses a few +tricks to make some the extended keys available on non-extended +systems. +

+

+ + + + + + Language Definition + +

+GoldED allows you to almost completely redefine the language dependent +text in the program. +

+

+The language dependent text in GoldED+ is defined in the plain ASCII +text GOLDLANG.CFG file. +

+

+See the example language file for the actual method and format of +language redefinition. +

+

+If you are planning to translate the text in GoldED+, you should also +look into the definition of the help screens. +

+

+You do not need permission from the author before announcing or +distributing your own modified language files. +

+ + + Date/Time Substitution Codes + +

+A few of the language texts can contain special date/time substitution +codes. The keywords for those are: MS_DateTimeFmt, MS_DateFmt, +MS_TimeFmt and ST_StatuslineTimeFmt. +

+

+Here are the valid substitution codes: +

+

+ %a Abbreviated weekday name (Mon, Tue, Wed, ...). + %A Full weekday name (Monday, Tuesday, Wednesday, ...). + %b Abbreviated month name (Jan, Feb, Mar, ...). + %B Full month name (January, February, March, ...). + %d Day of month (01-31). + %e Day of month, with leading space for single digits (1-31). + %E Day of month (1-31). + %H Hour (00-23) (24-hour clock). + %I Hour (01-12) (12-hour clock). + %j Day of the year (001-366). + %m Month (01-12). + %M Minute (00-59). + %p AM or PM according to 12-hour clock. + %S Second (00-59). + %U Week number (00-52) where sunday is first day of the week. + %w Weekday (0-6) where 0 is sunday. + %W Week number (01-53) where monday is first day of the week. + %y Year without century (00-99). + %Y Year with century. + %% Character '%'. +

+

+The %a, %A, %b and %B codes substitute to the current language setup +loaded using the LOADLANGUAGE keyword. +

+

+*** NOTE *** +

+

+In the continuing development of GoldED+, it is impossible to +completely maintain backward compatibility of the language format or +the text defined there. New features may add and/or obsolete some +definitions, or may change the format of others. +

+

+The existing language file may contain definitions which are already +obsolete, but which I haven't had time to search for and remove, as +well as there may be some texts in GoldED+ which are not yet definable. +All this will of course be corrected in future versions. If you find +inconsistencies, please report them, because I may have overlooked +them. +

+

+ + + + + + + Message Kludge Lines + +

+Kludge lines are special control lines, that begin with a ^a (ASCII 1) +as the first character of the line, followed by a unique identifying +name and the relevant control information. +

+

+GoldED is aware of a lot of these kludges, and supports a number of +them, if you want to have them inserted in your messages. +

+

+Some kludges are useless junk and more or less commercials for this +and that software, but a few are useful for miscellaneous purposes. In +the following, I will list (some of) the known and supported kludges, +and a short description of what they are used for. +

+ + + ACUPDATE: + +

+ This kludge is a feature of Squish 1.10: Message Broadcast + Modify/Delete. Read the docs for Squish 1.10 for details. +

+
+ + + AREA:<echoname> + +

+ This is not really a kludge, and it doesn't begin with a ^a, but I + included it on the kludge list because it sometimes turned up in + echomail areas where it should have been stripped off by the mail + tosser. +

+
+ + + CC: <name> <address> + +

+ When GoldED+ produces carbon copies, it adds to each message a full + list of the persons who get a copy. One version of this list is + hidden behind the CC: kludge. +

+
+ + + CHARSET:<charset identifier> + +

+ Proposed in FSC-0050 and FSC-0054, this kludge is an attempt to + find a solution to the problem of the high-bit characters (like + the IBM PC vs Amiga vs Mac etc. national chars) in messages. + GoldED+ can recognize, use and generate this kludge. +

+
+ + + CHRC:<font change id> + +

+ Proposed in FSC-0054, this is a kludge for changing fonts, + underlining and other stuff. +

+
+ + + CHRS:<charset identifier> + +

+ Alternative FSC-0054 version of the CHARSET kludge. +

+
+ + + DESTADDR:<destaddress> + +

+ This one is not proposed anywhere, but it looks like it gives the + address of the intended recipient. GoldED+ takes the address for + the dest field. +

+
+ + + DOMAIN <destdomain> <destaddress> <origdomain> <origaddress> + +

+ Proposed in FSC-0038, this tries to solve the problem of mail + crossing domain boundaries. GoldED+ takes both addresses. +

+
+ + + EID:<crc16> <stamp> [replycrc16] <replystamp> + +

+ Proposed in FSC-0031, this is used for dupe checking and reply + linking. The EID is today generally considered as garbage, but a + lot of older mail processors such as QMail still generate it. +

+
+ + + ENC: + +

+ Signifies that the message contains encrypted data. GoldED+ will + add this kludge if it detects that the message has been encrypted + with PGP. +

+
+ + + EOT: + +

+ End Of Text. See SOT. +

+
+ + + FLAGS <special attributes> + +

+ Proposed in FSC-0053, this is a special netmail kludge used by the + FrontDoor and D'Bridge mailers and the IMail mail processor. It + provides extra attributes not found among the standard attributes + in the normal message/packet headers. GoldED+ uses and generates + this kludge, if you set the attributes. +

+
+ + + FMPT <from point> + +

+ Defined in FTS-0001, this tells the point number of the + originator. Netmail only. GoldED+ can generate this line. +

+
+ + + FWDAREA <original area> + +

+ FSC-0092: The original area in forwards. See + USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + FWDDEST <aka> + +

+ FSC-0092: The original To: address in forwards. + See USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + FWDFROM <name> + +

+ FSC-0092: The original From: name in forwards. + See USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + FWDMSGID <aka serial#> + +

+ FSC-0092: The original MSGID in forwards. + See USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + FWDORIG <aka> + +

+ FSC-0092: The original from-aka in forwards. See + USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + FWDSUBJ <original subject> + +

+ FSC-0092: The original subject in forwards. See + USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + FWDTO <name> + +

+ FSC-0092: The original To: field in forwards. See + USEFWD and FSC-0092 for a more detailed + description. +

+
+ + + GATECHK:<???> + +

+ Some sort of gating kludge? Don't know what it's for. +

+
+ + + GIF:<filename> + +

+ Invented by Henk Wever and used in his + Dutchie software. The filename (which does not have an + extension) indicates a GIF picture of the author of the + message. +

+
+ + + GROUP:<echoname> + +

+ I think this one comes from stray Groupmail messages. Similar to the + AREA kludge. +

+
+ + + I51 (no parameters) + +

+ Proposed in FSC-0051, this indicates that the message text + conforms to the ISO-8859-1 (LATIN-1) + character set, and may contain certain escape codes. The + ISO-8859-1 set is used in Amiga and + Windows 3.xx. GoldED+ can recognize, use and + generate this kludge. +

+
+ + + INTL <destaddress> <origaddress> + +

+ Defined in FTS-0001, this one solves the problem of + crossing zone boundaries. Netmail only. GoldED+ can + generate this line. +

+
+ + + MSGID: <origaddress> <serialno> + +

+ Defined in FTS-0009, this is a method for unique + identification of a message. It can be used for dupe checking and + replylinking. GoldED+ can generate this line. +

+
+ + + MSGTO: <destaddress> + +

+ This one is not proposed anywhere, but it looks like it gives the + address of the intended recipient. GoldED+ takes the + address for the dest field. +

+
+ + + Original: <Carbon copy, original name> + +

+ Generated by the FrontDoor FM editor when it + produces carbon copies. +

+
+ + + PATH: <list of nodes> + +

+ Defined in FTS-0004, this is a valuable tool for finding + dupe links and other structural faults in the net structures. + Unfortunately the list of nodes is 2D (net/node), and this creates + problems when exporting echomail across zones. +

+
+ + + PTH: <list of nodes> + +

+ Not yet a FSC (or is it?), this is a 5D-version of the + PATH kludge, which sticks to the top of the msg. +

+
+ + + PID: <identifier> <version> [serialno] + +

+ Proposed in FSC-0046, this takes a stab at the tearline + abuse, and puts safe information about the first mail processing + software in the line. This could be message editors, mail scanners and + other stuff. +

+
+ + + Realname: <Name> + +

+ This kludge was probably born in Russia because of some software was + not able to properly handle non-ASCII characters in + the header lines. Name should be written in national codepage. + Otherwise I don't see any reason for this kludge. I don't know any + software that generate this kludge. +

+
+ + + RFD: <id> + +

+ Received For Distribution. A kludge inserted by one of the file + announcement programs. +

+
+ + + REPLY: <replyaddress> <replyserialno> + +

+ Defined in FTS-0009, this is the MSGID + counterpart. When replying to a message with a MSGID, the + MSGID of the original is renamed to REPLY. +

+
+ + + RID:<stuff> + +

+ Unknown kludge which looks suspiciously like the EID. +

+
+ + + ROUTE <list of nodes and points> + +

+ Specifies route path. Currently supported by Unimail and + S\Tosser. +

+
+ + + SEEN-BY: <list of nodes> + +

+ Defined in FTS-0004, this is a tool for finding dupe links + and other structural faults in the net structures. Depending on the + mail tosser, the seen-by's may or may not have a preceding ^a + character. Unfortunately the list of nodes is 2D (net/node), and this + can create problems when exporting echomail across zones. +

+
+ + + SN:<serialno> + +

+ Serial number inserted by the Dutchie message editor. +

+
+ + + SOT: + +

+ Start Of Text. See EOT. +

+
+ + + SPLIT: + +

+ Defined in FSC-0047. A method for splitting large msgs so + that some mail processors don't choke on them. +

+
+ + + TCL1:, TCL2: <long hex string> + +

+ Old obsolete swedish dupecheck/replylink kludge. +

+
+ + + TID: + +

+ Tosser ID. Similar to the PID, but specifically + for mail processors. +

+
+ + + TOPT <to point> + +

+ Defined in FTS-0001, this tells the point number of the + destination. Netmail only. GoldED+ can generate this line. +

+
+ + + TZ <offset from UTC> + +

+ Specifies the time to add to the header time to get the + UTC (Universal Time Coordinated) time. Generated by newer + versions of the TrackMail netmail processor. +

+
+ + + TZUTC + +

+ See TZ. GoldED+ can generate this line. +

+
+ + + Via: <netmail tossing info> + +

+ Routed netmail messages usually gets a Via line for each node + it passes through. This can be used for tracing faults in the netmail + routing structure. +

+
+ + + XID:<stuff> + +

+ Unknown kludge which looks suspiciously like the EID. +

+
+
+ + + +
+ +
diff --git a/manuals/gold_ref.txt b/manuals/gold_ref.txt new file mode 100644 index 0000000..af18712 --- /dev/null +++ b/manuals/gold_ref.txt @@ -0,0 +1,7028 @@ +#--------------------------------------------------------------------- +# GoldED Reference Manual +# $Id$ +#--------------------------------------------------------------------- +#manualfile GOLDREF.TXT +#pagelength 60 +#pagewidth 80 +#leftmargin 8 +#rightmargin 2 +#--------------------------------------------------------------------- + + + + + + + + + + + + + + + + + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + + Ú¿ Ú¿ Ú¿ + ³³ ³³ ³³ + ³³ ³³ ³³ + ³³ ³³ ³³ + ÚÂÄÄ¿ ÚÂÄÄ¿ ³³ ÚÂÄÄ´³ ÚÂÄÄ¿ ÚÂÄÄ´³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³ÃÄÄÁÙ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ Ú¿ ³³ ³³ + ÀÁÄÄ´³ ÀÁÄÄÁÙ ÀÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ + ³³ + ³³ + Ú¿ ³³ GoldED+ 1.0.0 + ÀÁÄÄÄÄÄÄÁÙ ÄÄÄÄÄÄÄÄÄÄÄÄÄ + + + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + + + Reference Manual + + + Program and manual written by + Odinn Sorensen, Dirk A. Mueller and others + + + Copyright (C) 1990-1999 by Odinn Sorensen + +#page +#--------------------------------------------------------------------- +#header +#--------------------------------------------------------------------- +#heading ______________________________________________________________________ +#heading +#heading
+#heading ______________________________________________________________________ +#heading +#--------------------------------------------------------------------- +#footer ______________________________________________________________________ +#footer +#footer GoldED Reference, Page +#--------------------------------------------------------------------- +#tocbegin +#chapter Table of Contents +#tocline ...................................................................... +#tocindent 4 +#tocpagenumber i +#toc +#tocend +#--------------------------------------------------------------------- +#pagenumber 1 +#chapternumber 1 +#--------------------------------------------------------------------- +#chapter Commandline Reference + +Commandline syntax: GOLDED [options] [keystacking] + + +Available options: + +-? + + Displays a help screen with all available commandline options. + + +-C + + Specifies another configuration file than the default GOLDED.CFG. + + +-D + + Disable old configuration keywords. For backward compatibility, + GoldED still supports a number of old names for some configuration + keywords. I recommend that you use -D sometimes and rename the + keywords that are reported as unknown. + + +-E + + If specified, GoldED starts directly in the specified echo, + bypassing the arealist screen. See the AREASTART configuration + keyword for more info. + + +-EXPORTSOUP + + Calls the SOUP packet export feature during the startup phase. + This is the same as starting it from the areascan SOUP + Packet->Export menu item. The SOUP export happens immediately + after the regular startup area scanning (if that is enabled) and + after SOUP import. + + +-F + + Force recompile of most configuration files, but not all. Does not + recompile the .CHS files. + + +-FF + + Force complete recompile of all configuration files, regardless of + whether they are up-to-date or not. This is equivalent to deleting + all the *.GE? files. + + +-H Same as option -?. + + +-INSTALL[=path] + + Start the quick install procedure. You should give a path to your + other mail software if it cannot be found using environment + variables or in current directory. + + Please see the INSTALL.TXT document for information about the + quick install procedure. + + +-IMPORTSOUP + + Calls the SOUP packet import feature during the startup phase. + This is the same as starting it from the areascan SOUP + Packet->Import menu item. The SOUP import happens immediately + after the regular startup area scanning (if that is enabled). + + +-M + + Mute. Disables all sounds in GoldED. + + +-N + + No share. If used, this prevents GoldED from using SHARE + compatible file-open calls, which are used by default. Works only + until the SHAREMODE keyword is used in GOLDED.CFG. This keyword is + normally not useful, but may be used to debug your setup or + something. + + +-NOSCAN + + Disable the automatic startup area scanning (if that is enabled). + This is useful for automated SOUP import/export in a batch file. + For example "-noscan -importsoup @x y" imports SOUP then exits. + + +-P + Since it seems that increasing the thread priority for the Win32 + version is a mixed blessing, the default is now to NOT increase + the priority. This option increases the priority (Win32 only). + +-Q + + Quiet. Turns off verbose config compile. On by default. This could + be used on the commandline to disable a -V(erbose) option in the + GEDCMD environment variable. + + +-S + + Sort all areas according to . See the AREALISTSORT + config keyword for details. + + +-T + + Set the timeout value. A value of zero (0) means never timeout. + See the TIMEOUT config keyword for details. + + +-V + + Turns on verbose config compile. When used, GoldED will display + the full filename of each main config file it compiles. It also + displays the name of the detected multitasker, if any. This can be + useful for debugging your setup, and see if GoldED accesses the + files (especially the AREAFILE's) it is supposed to. + + +-VV + + Same as -V, but also displays all the active lines while + compiling. This could be used to find the exact spot if it crashes + or stops while compiling. + + +-W + + If used, GoldED will create (and overwrite if existing) the file + GOLDAREA.INC, which will then contain all areas in the AREADEF + form, sorted by your AREALISTSORT specification. This is very + useful for converting your AREAFILE's to a form you can edit with + your favorite text editor and use in GoldED. It is also useful if + you have used the new AREADESC keyword or the AREAFILE EchoList + reader. The GOLDAREA.INC file (created in the GOLDPATH) can be + used by adding "INCLUDE GOLDAREA.INC" to your GOLDED.CFG or + GOLDAREA.CFG. When creating the file, GoldED will use '.' if an + aka is the same as the main aka, and leave out the optional origin + if it's the same as the first ORIGIN in your GOLDED.CFG. This + makes it easier to share the same GOLDAREA.INC between different + setups. + + +-X Reserved for debugging purposes. + + +-Y Reserved for debugging purposes. + + +-Z Reserved for debugging purposes. + + +Commandline keystacking + +Any non-option characters on the commandline are stuffed into the +keyboard buffer. See the chapter on keyboard definition and the +KEYBSTACK keyword for more info. + +Example: GOLDED @S A + +Makes GoldED go to the area scanning menu , and select +scanning of all areas. + +See the Macros and Keystacking chapter for more info. + +#page +#--------------------------------------------------------------------- +#chapter Environment Variables + +These are the GoldED specific environment variables: + + +GOLDED + + Path to the GOLDED.CFG file. It is recommended to set this + variable, but don't forget to change it if you move your GoldED + setup to a different directory! + + +GEDCMD + + Specifies additional commandline options. Use this if you want to + specify options, but need to run GoldED without them (for example + when renaming GOLDED.EXE to DBEDIT.EXE in older versions of + D'Bridge). You can override the environment options with + commandline options. + + +GOLDNODE + + The path where GoldNODE can find a GOLDED.CFG to use. + + +When the using AREAFILE feature to read external area configuration +from other programs, the individual AREAFILE's may use specific +environment variables to find the files. Please read the Area +Configuration chapter for specific details of each supported AREAFILE. + +#page +#--------------------------------------------------------------------- +#chapter Batchfile Errorlevels + +For operation in batch files, GoldED has a set of errorlevel values: + + 032 or higher Error exit (check the logfile for details). + 004 Echomail entered. + 002 Netmail entered. + 001 Local mail entered. + 000 No errors. No mail entered. + +Add values together to find the combined error levels. For example, +error level 6 is returned if netmail and echomail (2+4) was entered. + +Example RUNGOLD.BAT or RUNGOLD.CMD file: + +=== Cut === +@echo off +golded.exe +rem ged386.exe +rem ged2.exe +if errorlevel 008 goto error +if errorlevel 007 goto e_n_l +if errorlevel 006 goto e_n__ +if errorlevel 005 goto e___l +if errorlevel 004 goto e____ +if errorlevel 003 goto __n_l +if errorlevel 002 goto __n__ +if errorlevel 001 goto ____l +goto nomail +:error + echo golded error exit! + goto end +:e_n_l + echo **** New echo, net and local mail entered. + goto end +:e_n__ + echo **** New echo and netmail entered. + goto end +:e___l + echo **** New echo and local mail entered. + goto end +:e____ + echo **** New echomail entered. + goto end +:__n_l + echo **** New net and local mail entered. + goto end +:__n__ + echo **** New netmail entered. + goto end +:____l + echo **** New local mail entered. + goto end +:nomail + echo **** No new mail entered. +:end + echo. + echo Thank you for using GoldED! :-) +=== Cut === + +#page +#--------------------------------------------------------------------- +#chapter Nodelist and Userlist Support + +GoldED supports the FrontDoor, Version 7(+) nodelist indexes as well +as a plain FIDOUSER.LST. However, if you run software that doesn't use +any of these formats, you may want to use GoldED's own nodelist index. +This chapter describes how to do that. + +In order to enable nodelist/userlist lookup and browsing, GoldED needs +to use a set of special nodelist index files, created by the GoldNODE +nodelist compiler. + +GoldED normally uses and displays information from the nodelist when +browsing, but it doesn't really need the nodelist for anything. The +index files contains sufficient information for lookup and browsing of +names or addresses. This means that you can delete or pack away the +nodelists and/or userlists after compiling with GoldNODE, if you want +to save space and you don't need them for anything else. + +GoldNODE commandline syntax: + + GOLDNODE/GN386/GN2 [-options] [configfile] + +Available options: + + -C Conditional compile. + -D Remove duplicate nodes from index. + -F Forced compile. + -Q Quite compiled. No screen output improves speed. + -S Set the max size of names. Normally not used. + -U Create sorted FIDOUSER.LST userlist file. + +The following options are only interpreted by DOS real mode version: + + -M Compile max nodes (maximum is 65500). + -ND Enable DISK usage. + -NE Disable EMS usage. + -NX Disable XMS usage. + +The [configfile] is the path AND filename of the GOLDED.CFG +configuration file to read. If no filename is given, the path +specified with the GOLDNODE or GOLDED environment variables are used. + +The nodelist index files are named GOLDNODE.GX? are are placed in the +path pointed to by the NODEPATH keyword. + +The V7+ is automatically used if your NODEPATHV7 is set correctly. If +GoldED shows "xxxx / NODEX.DTP" at the bottom of the browser window, +the displayed information is taken from the raw nodelist entry, taken +from the V7+ index. + +GoldNODE can handle up to 45 nodelists and 10 userlists. GoldNODE can +read the german POINTS24-format directly! + +NOTE: If you use the EXCLUDENODES and INCLUDENODES keywords, please +note that the does NOT accept "ALL" or "WORLD" etc. You +must use wildcard '*' instead. + +#page +#--------------------------------------------------------------------- +#chapter Configuration Control + +The GOLDED.CFG configuration reader can be directed in several ways +with special keywords: + + +IF  +ELIF  +ELSEIF  (same as ELIF) +ELSE +ENDIF + + These control keywords can be used to setup sections of + configuration which enable different sets of keywords depending on + which version that is used. + + The following conditions can be used: + + dos true, if GoldED/DOS or GoldED/386 is used + 386 true, if GoldED/386 is used + os2 true, if GoldED/2 is used + w32 true, if GoldED/W32 is used + linux, unix true, if GoldED/Lnx is used + firebird true, if GoldED 3.xx is used + asa true, if GoldED-asa is used + + yes, true, on always true + + Example: + + IF OS2 + EDITOR c:\qedit\os2\q.exe @file -n@line + EDITSPELLCHECK c:\os2\cmd.exe /c c:\ss\ss.exe @file + ELIF DOS + EDITOR c:\qedit\dos\q.exe @file -n@line + EDITSPELLCHECK c:\ss\ss.exe @file + ENDIF + + If both IF 386 and IF DOS are used, it is important to put DOS as + the bottom choice. + + +IGNORE + + This tells the configuration file reader to ignore all subsequent + lines until another IGNORE keyword is encountered. Useful for + testing and quickly switching portions of configuration. + + However it is probably more useful to use the IF/ELIF/ENDIF + control keywords. + + +INCLUDE  + + This tells the configuration file reader to stop reading the + current .CFG file, and start reading the as an extra + configuration file, then resume reading the previous .CFG. The + INCLUDE filenames are stored and their timestamps are checked when + GoldED is started. INCLUDE files can be nested without limit. + + +REM + + Signifies a REMark (comment) line. The line is ignored. + + +Any non-alphabetic non-whitespace character at the beginning of a line +makes the line a comment. Example: + + ; This is a comment + % This is a comment + * This is a comment + // This is a comment + /* This is a comment */ + +By tradition, the semicolon is the standard comment character. The +semicolon (and only that) can also be used to add a comment at the end +of a configuration line. Example: + + ADDRESS 2:236/77 ; Main address. + AKA 2:236/77.1 ; SysOp point. + +#page +#--------------------------------------------------------------------- +#chapter Configuration Keyword Reference + +This is an alphabetical list of all the configuration keywords that +can be used in the main GoldED configuration file (GOLDED.CFG and any +file included from it). It also lists and documents the keywords that +are specific to the Random System groups. + +The following special symbols are used in the keyword parameter lists: + + () Default value. + [] Optional parameter. + <> Required parameter, not optional. + "" Parameter must be inclosed in quotes (""). + / Separates mutually exclusive values. + , Separates possible values for the keyword. + + +Here is the complete keyword list: + + +ADDRESS  + + Your network address, FidoNet-style. More than one address can be + specified if you are member of more than one network. The keywords + ADDRESS and AKA can be used interchangeably. + + If a pointnet is specified with a point address, GoldED will use + the so-called "3D" addressing method in netmail msgs, otherwise + the "4D" method is used. The 3D method works by putting the + address ZONE:POINTNET/POINT.0 in the msg header, instead of the 4D + format ZONE:NET/NODE.POINT. Most modern mailers and mail + processors now supports the 4D format, but if you are a point, you + should always consult your Boss about which format to use. + + The optional @domain part can be used to specify a "fifth" + dimension to the 4D address. It is normally not necessary to + specify a domain. Domains are never shown in the header and are + not put in the origin line. The only place the domain is + used/added by GoldED is in the MSGID kludge. + + Examples: + + Address 2:236/77 ; Node address + Address 2:236/77.1 ; Point address (4D) + Address 2:236/77.1, 16077 ; Point address (3D) + Address 2:236/77@fidonet ; Node address with domain + + This keyword can be used globally and in a Random System group. + + +ADDRESSBOOKADD  (yes) + + Setting this keyword to "always" means that GoldED will always add + unknown addressees to the addressbook when writing new or quoted + mails automatically. If you set the value to "yes", GoldED will + add them only if it's a netmail/email. ADDRESSBOOKADD NO disables + this feature entirely. + + NOTE that GoldED won't add unknown users if their name match one + of the following criteria: + + 1) it's a USERNAME + 2) it's a ROBOTNAME + 3) it's the WHOTO + 4) address/aka is unknown + + +ADDRESSLOOKUPFIRST  (Origin) + + By default address of sender taken from Origin line. If this + keyword set to MsgID then GoldEd looks for correct FTN address in + MSGID kludge first. + + +ADDRESSMACRO ,,
[,"subject"][,attribs] + + Defines a short name for often used addresses. Typical uses are + for AreaFix/AreaMgr, your uplink, boss, points or others you write + to often. To use a defined address macro, you just type it in the + To: name field. + + If (and ONLY if) the subject is enclosed in quotes ("" or ''), + GoldED will look for message attributes after the subject. See the + Message Attributes Reference for a valid attribute. You cannot + have quotes within quotes (not the same type anyway). + + The attribues are *added* to the ones already there, they do *not* + replace them. + + Examples: + + afup,AreaFix,2:236/512,"password -q -l",K/S + ffup,FileFix,2:236/512,password + odin,Odinn Sorensen,2:236/77,GoldED - What else? :-) + + A special format is supported for UUCP or INTERNET gateways. The + special format is indicated with a (@) as the first character in + the . + + jfu,@fallesen@diku.dk,2:310/33 + dn,@INTERNET/david@csource.oz.au,2:241/999 + + In the first example, GoldED will put "UUCP" (the default gateway + name) in the TO: msg header field and "To: fallesen@diku.dk" on + the first line of the message text. + + In the second example, GoldED will put "INTERNET" in the TO: + field, and "To: david@csource.oz.au" in the message. The forward + slash (/) separates the gateway name from the receiver address. + Any gateway name may be used. + + The address macros can also be specified in an external file, like + the NAMES.FD file supported by the FrontDoor mailer/editor and + Maximus BBS. See the keyword NAMESFILE for details. However, you + should not use the syntax with the attributes in the NAMES.FD + file, because FrontDoor and Maximus do not know this syntax. + + +ADEPTXBBSPATH  + + The path where you keep your AdeptXBBS. + + +ADEPTXBBSUSERNO  + + By default GoldED will use the first record in the userfile and + lastreads. If you are not the first user in the userfile, or are + sharing the messagebase with other GoldED users, you must either + set this keyword to -1, or use a different number for each user. + Each user must be defined in the userbase. + + +AKA  + + AKA (Also Known As) is an alias for the ADDRESS keyword. + + This keyword can be used globally and in a Random System group. + + +AKAMATCH  + + This is an enhancement of the existing aka matching logic, which + in some circumstances fails to find the correct aka. + + Example: Lets say that zone 21, 22 and 23 are part of the same + network, and that you have an aka in zone 22. You would put + something like this in your setup: + + ADDRESS 2:236/77 + AKA 22:33/44 + + In this case, if a mail comes in from zone 23, the normal aka + matching logic would fail, because it does not try to guess the + correct zone. To the rescue comes the new keyword. Now you can add + this to your setup: + + AKAMATCH 21:*/*.* 22:33/44 + AKAMATCH 23:*/*.* 22:33/44 + + It tells GoldED that any mail from zone 21 or 23 matches your zone + 22 aka. Note the use of wildcards here. Wildcards are not strictly + necessary, you could also have just written "23:" or "23:*". + + When an address does not match any AKAMATCH definition, the normal + aka matching logic takes over. + + +AKAMATCHECHO  (no) + + If enabled, GoldED will attempt to match one of your akas to the + address of the person you are replying to in echomail areas. + + Normally it is not desirable to enable aka matching in echomail, + because some echoes may be restricted to members of one particular + network, and an accidental wrong aka matching may attract unwanted + attention from the moderator or the compulsive flamers :-) + + +AKAMATCHING  + + This keyword is only valid in Random System groups. When used, it + overrides any global AKAMATCHNET, AKAMATCHECHO or AKAMATCHLOCAL + you may have. + + +AKAMATCHLOCAL  (no) + + If enabled, GoldED will attempt to match one of your akas to the + address of the person you are replying to in local areas. + + It doesn't really make sense to do aka matching in local areas. + The keyword is just there for completeness. + + +AKAMATCHNET  (yes) + + If enabled, GoldED will attempt to match one of your akas to the + address of the person you are replying to in netmail areas. This + is especially useful if you are a member in more than one network, + and therefore have more than one address. + + +APP [keyword and/or parameters] + + This is a way for other programs to place configuration data in + GoldED's configuration file. + + For example, if a program named "OtherProg" wants to read its + configuration from GOLDED.CFG, here is how it might look: + + APP OtherProg REGKEY xyaxajlsaduoiweqeq + APP OtherProg IRQ 5 + + GoldED itself will ignore APP lines just like REM lines. + + +AREA <"desc"> [type] [akano] [attrs] + + This keyword defines a mail area in GoldED. You need to define at + least one mail area to run GoldED, or use the AREAFILE keyword to + read the area setup of your mailer, mail processor or BBS. + + Mail area identifier. + <"desc"> Area description in ("") quotes. + O(Opus *.MSG), S(FTS-0001 *.MSG), Q(QuickBBS), + R(RemoteAccess), H(Hudson), M(Squish), J(JAM), + E(Ezycom), G(Goldbase), P(PCBoard). + [type] N(Netmail), E(Echomail), L(Local). + Directory path/file or Hudson board number. + [aka] AKA number (starting from 0) + [attrs] R/O(Read-Only), and/or other attributes. + + "O(Opus)" are *.MSG files with binary date/time stamps. + "S(FTS-0001)" are *.MSG files, but with zone/point header fields. + "Q(QuickBBS)", "R(RemoteAccess)" and "H(Hudson) are synonyms. + "M(Squish)" is the Squish format. + "E(Ezycom)" is the Ezycom format. + "J(JAM) is the JAM format. + "G(Goldbase)" is the Goldbase format. + "P(PCBoard)" is the PCBoard format. + "X(AdeptXBBS)" is the AdeptXBBS format. + "W(WildCat!)" is the WildCat! 4.x format. + + GoldED can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED translates the path to + C:\POINT\path\name. + NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED to recompile it's config, you must force + it with the -F or -FF command parameter. + + It is recommended to use the newer AREADEF keyword, which allows + more detailed mail area setup. + + +AREAAUTOID  (verbose) + + Defines how an automatically created echoid should look, when + AREAFILE finds an area without an echoid. + + When the "verbose" option is used, the echoid is given a name + similar to the function of the area, such as NETMAIL, NET_SENT, + ECHO_BAD, ECHO_DUPES and so on. + + When the "long" option is used, the echoids are numbered + sequentially like this: NETMAILxxx, ECHOMAILxxx and LOCALxxx. This + is how it worked in older versions (including 2.42.gamma). + + When the "short" option is used, the echoids are numbered + sequentially like this: NETxxx, ECHOxxx and LOCALxxx. This is how + it worked in 2.50.beta until B1016. + + +AREAAUTONEXT  (yes) + + If enabled, GoldED will automatically jump to the first marked + area in the arealist on startup, and the next marked area after + exiting from an area you have been reading. + + +AREACATCHUPREAD  (yes) + + If enabled, GoldED will set all skipped messages to "read" when + using AREAcatchup in the arealist-screen. This implies that + HIGHLIGHTUNREAD YES is used, otherwise it has no function. + + +AREACOPYADDID  (no) + + If enabled, GoldED will insert the control line + "AREA:" at the top of each message that is copied + or moved. This can be a help when regularly copying messages to a + "THE_SAFE" type area. + + This keyword can and should only be used in Random System Groups. + + It is useful if you copy echomails to some local "ARCHIVE" areas. + In this case, GoldED can add the "AREA:"-kludge to + inform you from where you copied the mail to. + + +AREACOPYDIRECT  (no) + + If enabled, the destination area selection list is bypassed, + thereby making possible a "seamless" copy/move to the default + destination area. The destination area should be set with + AREACOPYTO. + + This keyword can be used globally and in a Random System group. + + NOTE: It is probably not a good idea to enable this keyword + globally. + + +AREACOPYTO  + + Sets the default area for the Copy/Move functions. Typically you + could set it to a "safe/permanent storage" type of area, for + example a JOKES2KEEP or THE_SAFE area. Note that the Forward + function uses the AREAREPLYTO area instead. + + This keyword can be used globally and in a Random System group. + + Related keywords: AREAFREQTO, AREAREPLYTO. + + +AREADEF  + + This is newer version of the "AREA" keyword, with more detailed + parameters. + + The full syntax is: (must be all on one line) + + AREADEF <"desc"> + <(attrs)> ["origin"] + + The echoid. + <"desc"> Area description in quotes. + Groupid uppercase letter (A-Z) or 0 if not in a + group. Use #groupnumber to specify group numbers in + the 1-999 range. Example: #117. + Net, Echo, Local, EMail or News. + Opus, FTS1, Hudson, Squish, Ezycom, JAM, Goldbase or + PCBoard. + Area path, boardnumber or base filename. + Aka address for the area, or '.' for main aka. + <(attrs)> Default attributes in brackets (). + ["origin"] Optional default origin in quotes. + + This looks a lot like the AREA keyword. Additional parameters are + the , the verbose and , the fully specified + address, the brackets for the attributes and the optional + origin. + + Note the possibility of using '.' to specify the main aka. This, + and the optional default origin, makes it simpler to create a + common INCLUDE'able area configuration for several setups with + different addresses, for example two people sharing the same + msgbase. + + GoldED can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED translates the path to + C:\POINT\path\name. + NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED to recompile it's config, you must force + it with the -F or -FF command parameter. + + +AREADESC <"desc"> [group] [aka] [(attrs)] ["origin"] + + Adds a description and optionally a group letter, aka, attributes + and origin to an _existing_ (previously defined) area. This is + useful if you use an AREAFILE that does not contain descriptions, + groups, akas, attributes or origins. + + The echoid. + <"desc"> Area description in quotes. + [group] Optional groupid letter (A-Z) or 0 if not in a group, + or #groupnumber (1-999) or '-' to keep the existing + groupid. + [aka] Optional aka address for the area, or '.' for main + aka, or '-' to keep the existing aka. + [(attrs)] Optional default attributes in brackets (), '-' to + keep the existing attributes. Note that if they are + specified, they are _added_ to the default + net/echo/local attributes. + ["origin"] Optional default origin in quotes. + + NOTE: You cannot skip any of the optional parts in the middle, + even if you only want to set, say, an origin. Use '-' to keep the + existing value for the parts you skip. + + +AREAEXCL  + + With this keyword, you can define the echoids of areas which + should be ignored by GoldED (thereby leaving them out of the + arealist). This is normally used in connection with AREAFILE, to + exclude areas you are not interested in reading. DOS/4DOS-style + wildcards (* and ?) can be used in the echoid mask. + + Examples: + + AREAEXCL * Excludes all areas. + AREAEXCL *INTER* Excludes all areas containing "INTER" anywhere + in the echoid. + AREAEXCL INT*.* Excludes all areas beginning with "INT" and + containing a '.' anywhere in the echoid. + + You can use the AREAINCL keyword to re-include areas which have + been excluded with AREAEXCL. + + NOTE: This keyword must be placed before any AREA, AREADEF or + AREAFILE keyword. + + +AREAFILE [path/file] [switches] + + GoldED can read the area setup of many popular mailers, mail + processors and BBS'es, thereby making it much easier and simpler + to configure GoldED for the mail areas you receive, by eliminating + the need to write AREA lines for all or most of your areas. + + Name of the program. + [path/file] Filename or path to the area setup files. + [switches] Msgbase specific switches. + + For most programs, GoldED can automatically find the path or + filename using environment variables. By default, GoldED will look + for the area setup files in the AREAPATH. + + There are switches for sorting the areas, and for turning off an + update-check when GoldED starts up. + + GoldED can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED translates the path to + C:\POINT\path\name. + NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED to recompile it's config, you must force + it with the -F or -FF command parameter. + + This keyword is explained in greater detail in the Area + Configuration chapter. + + +AREAFILEGROUPS  (yes) + + In some AREAFILE setups, you can groups the areas using single + letters (A-Z) or numbers (#1-999). If this keyword is enabled, + GoldED will use the area groupid instead of the area echoid when + gathering area specific information from the Random System. + + If this keyword is enabled, you should setup matching GROUP's in + GOLDRAND.CFG. See the Random System chapter for details. + + +AREAFREQDIRECT  (no) + + If enabled, the destination area selection list is bypassed, + thereby making possible a "seamless" file request in the default + destination area. The destination area should be set with + AREAFREQTO. + + TIP: If you (like most) only have one mailer netmail area, you + should enable the AREAFREQDIRECT keyword globally for + simpler file requests. + + This keyword can be used globally and in a Random System group. + + NOTE: It is probably not a good idea to enable this keyword + globally. + + +AREAFREQTO  (first netmail area) + + Sets the default area for the filerequest function. You should set + this to the netmail area where you normally put the filerequest + messages. + + Note that if AREAFREQTO is not specified, it defaults to the first + netmail area found. + + This keyword can be used globally and in a Random System group. + + Related keywords: AREACOPYTO, AREAREPLYTO. + + +AREAINCL  + + With this keyword, you can define the echoids of areas which + should be re-included by GoldED, if they have been excluded with + the AREAEXCL keyword. DOS/4DOS-style wildcards (* and ?) can be + used in the echoid mask. + + Examples: + + AREAINCL * Includes all areas. + AREAINCL *INTER* Includes all areas containing "INTER" anywhere + in the echoid. + AREAINCL INT*.* Includes all areas beginning with "INT" and + containing a '.' anywhere in the echoid. + + You can use the AREAINCL keyword to re-include areas which have + been excluded with AREAEXCL. + + NOTE: This keyword must be placed before any AREA, AREADEF or + AREAFILE keyword. + + +AREAISEMAIL  + + For Internet e-mail areas. See AREAISNEWS for details. + + +AREAISNEWS  + + Wildcards * and ? are allowed. These keywords are designed to mark + areas which are read from an AREAFILE as Internet e-mail or + newsgroups. This may be necessary in some cases to enable the + Internet specific features without having to manually define all + Internet areas. Examples: + + AREAISNEWS alt.*, rec.*, sci.* + + +AREAKEEPLAST  (yes) + + If enabled, GoldED will write the file GOLDLAST.LST in the + GOLDPATH at exit and read it back when run next time. The contents + of the file is a list of lastread information for each area as it + was at last scan. + + This feature is helpful when you know that there have not been + tossed new mail and don't want to wait for a full msgbase scan. + Now you can just hit ESC at the startup screen to abort the area + scan and GoldED will put up the lastread info from the previous + session. + + It also makes the "new mail since last scan" feature even better, + because the new mail marker now shows which areas that have new + mail since last session even when scanning areas at startup. + + In addition, GoldED now makes extra backups of the file, so that + earlier versions of the files can be found in GOLDLAST.BK1 and + GOLDLAST.BK2. + + GoldED now only writes the GOLDLAST.LST file at exit if it + survived the initial startup scan. + + +AREALISTECHOMAX  (0) + + Allows you to specify a fixed or dynamically sized width of the + EchoID column in the arealist. + + If a negative value is specified, the width will be the that of + the widest echoid in the arealist plus the negative value. This + might be useful if some long-name echoes have uninteresting ends, + such as "VERYLONGECHOID_R23.PUB" (could benefit from a of + -7). There is currently no provision for long echoids with common + beginning. + + The arealist can dynamically resize the EchoID and Description + columns, so that long echoids are not cut off. The sizing of the + EchoID column is done against the Description column, which + thereby looses or gains width. In version 2.41 and earlier, the + EchoID column width was fixed at 13 chars on 80 column displays. + + +AREALISTFORMAT  ("AM D CPUN E G ") + + The arealist column layout is configurable. This keyword allows you + to change the layout to whatever you like + + The default is: + + AREALISTFORMAT "AM D CPUN E G " + + This produces the usual layout. Here is another: + + AREALISTFORMAT "ME D CPUN G " + + This one puts the echoid in front and eliminates the area numbers. + + The letters stand for the following: + + letter meaning default width + A Area number 4 + M Marked 1 + D Description Dynamic + C Number of messages 6 + P Personal mail mark ('+') 1 + U Number of unread/new messages 6 + N Changed since last scan mark ('*') 1 + E Echoid AREALISTECHOMAX + G Groupid Dynamic: 0, 1 or 3 + + You can also specify widths if you don't like the defaults: + + AREALISTFORMAT "AM D C4PU4N E G " + + In this example, the Msgs and New columns are put back to the size + they had in "old days". + + If you leave out a letter, that column will not be shown. + + Use only the defined letters. Use spaces to specify required space + between columns. Use only positive numbers for widths. Failure to + obey these rules may cause undocumented behaviour. + + +AREALISTGROUPID  (yes) + + If enabled, the arealist screen will display the groupid letters, + if any, in a column to the right of the EchoID column. If a + groupid is not a letter in the range A-Z (a value in the range + #65-#90), the groupid is not shown. + + +AREALISTNOS  (no) + + If enabled, GoldED will display the board numbers of Hudson areas + in the arealist instead of the default sequential numbers. + + +AREALISTPAGEBAR  (yes) + + Enables or disables a pagebar (scrollbar) in the arealist. + + +AREALISTSCAN <"L menu text"> [path] [-delete]] + + This keyword allows you to define additional menu items for the + arealist scanning menus (Alt-S or Alt-P). + + The first two characters of the menu text are the "hotkey" letter + that will be highlighted in the menu text, plus a space. + + The filename specifies a plain text file, with the echoids + (wildcards allowed) of the areas you want to scan when the menu + item is selected. There can be several echoids on each line in the + file. If no path is given, the file is loaded from the GOLDPATH. + + The -delete option will cause GoldED to delete the list file after + scanning the areas in it. For example, if your mail processor + generates a list of the areas that it tossed new mail to, you + could add the list as a menu item on the scanning menu and use it + to scan only those areas with new mail. Note that some mail + processors automatically delete their list after using it for + replylinking. You may want to do some creative stuff with + batchfiles to grab a copy. + + Examples: + + AREALISTSCAN "g Scan Newsgroups" NEWSGRPS.LST + AREALISTSCAN "L Scan Latest" R:\GECHO\IMPORT.ALL -delete + + === Cut, NEWSGRPS.LST === + ALT.*, COMP.*, MISC.*, NEWS.* + REC.*, SOC.*, SCI.*, TALK.* + === Cut === + + === Cut from an import batchfile === + gecho mgr toss pack -tossbad + if exist import.jam type import.jam >>import.all + if exist import.hmb type import.hmb >>import.all + if exist import.sdm type import.sdm >>import.all + mbutil link -clean + === Cut === + + +AREALISTSORT  (FYTUE) + + This keyword defines how the area list should be sorted. You can + override the default setting from the commandline with the -S + switch. + + The can be composed of the following types: + + A Sort by aka. + B Sort by board number. + D Sort by description. + E Sort by echoid. + F Sorts all "fuzzy search" matches first. + G Sort by group (if any). + M Sorts all marked areas first. + O Sort by original order. + P Sort by personal mail. + T Sort by type (in the order net, echo, local). + U Sort by unread messages (try it!). + X Sort by msgbase type. + Y Sorts all areas with "new" mail first. + Z Sort by msgbase path. + - Descending sort (largest first). + + Ascending sort (smallest first) (default). + + In practice 'M' and 'Y' will usually give the same result, because + GoldED automatically marks scanned areas if they contain new mail. + + Example: + + AREALISTSORT T-U+E + + This sorts ascending by Type, descending by Unread (that is, areas + with the most unread messages comes first) and ascending by Echoid + (in case two areas have the same number of unread msgs). + + By default no sorting is done, and all areas are listed in the + order they were found (unless sorting was specified with an + AREAFILE keyword). However, the configuration examples all make + use of the Unread sorting type. This is a very useful way of + sorting areas, because it keeps all the areas with mail together. + + Personally I now sort my areas like this: "AREALISTSORT FYTUE". + This puts all areas with new mail first, then sorts these into + type (net/echo/local), then into number of new msgs and finally + into echoid. The 'F' at the start enables fuzzy match sorting, + which is very handy when looking for an echoid containing a + particular word. Let's say I want a list of all GOLDED echoes. I + can now simply type "GOLDED" and then the arealist automatically + sorts itself so that all echoes with an echoid containing "GOLDED" + comes first :-) + + The 'X' sort type sorts areas according to msgbase type, in the + following order: + + Hudson + Goldbase + JAM + Squish + OPUS *.MSG + FTS-1 *.MSG + Ezycom + PCBoard + + The 'X' and 'Z' sort types were implemented for internal use, to + optimize area scanning speed. When scanning areas, GoldED starts + by sorting the arealist using the sortspec defined with the + AREASCANSORT keyword. + + +AREALISTTYPE  (new) + + Defines the contents of the 4th column (the one after the "Total" + column). + + New Displays the amount of new (unread) msgs. + Last Displays the number of the last msg read. + + +AREAPATH  + + If you use the AREAFILE keyword, GoldED might need to know where + the area setup files are located. This keyword specifies where + they are found, if not current directory. + + NOTE: Most AREAFILE types can find the path using the environment + variable(s) specific for the program(s). Such environment + variables (or a path specified with the AREAFILE definition) + always overrides the AREAPATH. + + +AREAPMSCAN  + + This keyword defines areas which will be automatically scanned for + personal mail when starting GoldED. DOS/4DOS-style wildcards (* + and ?) can be used in the echoid mask. + + Examples: + + AREAPMSCAN * Scan all areas. + AREAPMSCAN *INTER* Scan all areas containing "INTER" anywhere + in the echoid. + AREAPMSCAN INT*.* Scan all areas beginning with "INT" and + containing a '.' anywhere in the echoid. + + It is recommended to have an "AREAPMSCAN *" to scan all areas at + startup. If you don't want to wait for the scan to complete, you + can abort the scan by pressing ESC during startup. + + +AREAPMSCANEXCL  + + With this keyword you can prevent areas from being scanned with + AREAPMSCAN on startup. This is good if you use "AREAPMSCAN *", but + have some big areas which slows it down. + + +AREAPMSCANINCL  + + Here you can specify areas to be scanned with AREAPMSCAN even if + they were excluded with AREAPMSCANEXCL. Useful for partial + reversal of wildcard specs in the excludes. + + +AREAREADONLY  (soft) + + If this keyword is set to "hard", it is no longer possible to + enter/reply/change messages in areas marked read-only with the R/O + area attribute. The "soft" setting uses a menu to ask permission + as in the previous versions. This option is designed for those who + setup a system for new computer users who might be confused enough + to enter a message in a read-only area despite the warning menu. + + +AREARENAME  + + Renames one echoid to another. The feature is meant to be used in + connection with AREAFILE, where some types do not store echoids + with the areas (and GoldED then automatically gives them unique + echoids). + + Examples: + + AREARENAME NET001 NETMAIL + AREARENAME ECHO001 BAD_MSGS + AREARENAME LOCAL001 BBS.USERS + + +AREAREPLYDIRECT  (no) + + If enabled, the destination area selection list is bypassed, + thereby making possible a "seamless" reply/forward to the default + destination area. The destination area should be set with + AREAREPLYTO. + + TIP: If you run a utility or have a mail processor which copies + personal mail to a separate area and puts an "AREA:" line at + the top of the messages, you should create a random system + group for the area and enable AREAREPLYDIRECT in it: + + Group ECHO_PERSONAL + AreaReplyDirect yes + + With such a setup, GoldED replies directly to the area found + in the "AREA:" line, so that you do not have to explicitly + use the Alt-N command to reply in the original area, because + GoldED automatically stores the reply in the appropiate + area. However, if you use , you can select a diffrent + area (i.e. Netmail). + + This keyword can be used globally and in a Random System group. + + NOTE: It is probably not a good idea to enable this keyword + globally. + + +AREAREPLYTO  (first netmail area) + + Sets the default area for the READmovequotemsg, READmovecommentmsg + and Forward functions. The default area is the first netmail area + found in your setup. You should check if GoldED found the correct + one if you have more than one. If you find yourself often + forwarding or quoting from one area to another, it might be a good + idea to setup a Random System group and put in this keyword. + Example: + + Group GOLDED + AreaReplyto GOLDED.BETA + EndGroup + + This keyword can be used globally and in a Random System group. + + Related keywords: AREACOPYTO, AREAFREQTO. + + +AREASCAN  + + This keyword defines areas which will be automatically scanned + when starting GoldED. DOS/4DOS-style wildcards (* and ?) can be + used in the echoid mask. + + Examples: + + AREASCAN * Scan all areas. + AREASCAN *INTER* Scan all areas containing "INTER" anywhere in + the echoid. + AREASCAN INT*.* Scan all areas beginning with "INT" and + containing a '.' anywhere in the echoid. + + It is recommended to have an "AREASCAN *" to scan all areas at + startup. If you don't want to wait for the scan to complete, you + can abort the scan by pressing ESC during startup. + + +AREASCANEXCL  + + With this keyword you can prevent areas from being scanned with + AREASCAN on startup. This is good if you use "AREASCAN *", but + have some big areas which slows it down. + + +AREASCANINCL  + + Here you can specify areas to be scanned with AREASCAN even if + they were excluded with AREASCANEXCL. Useful for partial reversal + of wildcard specs in the excludes. + + +AREASCANSORT  (XZBE) + + When scanning areas, GoldED can optimize area scanning speed if it + first sorts the arealist in an order so that each msgbase format + is scanned in sequence rather than on semi-random order. + + If you don't like this or don't need it, you can define your own + sort order. + + See the AREALISTSORT keyword for the definition of the sortspecs. + + +AREASEP <"desc">  + + You can define area separation lines between groups or areatypes. + The syntax is nearly the same as the AREADEF keyword except for + the fields after . + + Examples: + + These five are area separation lines that are designed to list + before each type of area. This works well when AREALISTSORT has + T (for type) as one of the primary sort orders. + + AREASEP !NET "Netmail areas" 0 Net + AREASEP !EMAIL "E-mail areas" 0 EMail + AREASEP !ECHO "Echomail areas" 0 Echo + AREASEP !NEWS "Newsgroup areas" 0 News + AREASEP !LOCAL "Local areas" 0 Local + + These can be used to separate areas with group letters (it will + also work with group numbers like #117). Areas should then be + sorted primarily on the group. + + AREASEP !A "Group A" A Local + AREASEP !B "Group B" B Local + AREASEP !C "Group C" C Local + + In these examples, I put a '!' in front of the echoid to make + sure it is sorted ahead of the areas. This may not be necessary + in all cases, depending on the sort order in effect. If you do + put '!' in front of the echoid, have fuzzy sorting as the + primary sort order, and type '!' in the fuzzy search, you'll get + the interesting effect that all area separation lines collect + themselves at the top :-) + + + The area separation lines are implemented like a special kind of + area, and are therefore sorted in the arealist just as if they + were actual areas. This is also the reason why you can place the + cursor bar on the separation lines. Originally I wanted to make + the cursor skip the separation lines, but I think I'll leave it as + it is, because it can be useful sometimes, especially when using + the fuzzy feature to quickly go to an area, for example, type "!C" + to quickly move down to the group C areas (using the group sorted + example). + + When configuring area separation lines, be careful to consider the + AREALISTSORT, so that the lines are sorted into the positions you + want. If you don't sort areas, you must make sure that the AREASEP + definitions are placed correctly in your GOLDED.CFG or + GOLDAREA.CFG, that is, between/before AREADEF lines. + + You will note that the separation lines are not fully connected + into the left and right edges. This is both by design and for + practical reasons (easier to implement), not a bug. + + Currently the descriptions are hardcoded to the natural location + in the description column. + + +AREASTART  + + Normally GoldED starts by displaying the arealist, to let you + select which area you want to read. If this keyword is defined, + the arealist is bypassed and GoldED starts directly in the + configured area. You can override AREASTART with the -E + commandline switch. + + +AREATYPEORDER  + + This keyword allows you to change the ordering of the Net, Echo, + Local, EMail and News types when sorted by AREALISTSORT. + + The default is + + AREATYPEORDER Net EMail Echo News Local + + This keyword was added to give greater flexibility to the new + AREASEP feature. + + +AREAYOUWROTETO  + + GoldED automatically copies mails written by yourself to the given + area when saving a new mail. GoldED will also add an AREA-kludge + so you can see from which area the mail originally is copied from. + + This keyword can be used globally and in Random System group. + + +ASKDELORIG  (yes) + + If enabled, you will be asked if the message you just replied to + should be deleted. Otherwise it is left untouched. + + This keyword is only functional in netmail and local areas. + + +ATTACHPATH  + + Defines the default when selecting files for attachement. + + +ATTRIBSATTACH  + + Defines the attributes that are *added* to the existing attributes + of a message when the file attach attribute is toggled on. + + +ATTRIBSCC  + + Defines the default attributes of Carbon Copy messages. CC + attributes are *added* to the existing attributes of the original + message. Usually used to add the Kill/Sent attribute. + + +ATTRIBSCFM  + + Defines the default attributes of the Confirmation Receipt + message. + + +ATTRIBSECHO  + + Defines the default attributes of messages entered in echomail + areas. + + +ATTRIBSEMAIL  + + Defines the default attributes of messages entered in e-mail + areas. + + +ATTRIBSFRQ  + + Defines the attributes to use for messages generated with the file + request function. Suggested attributes are: PVT K/S CRA. The FRQ + and LOC attributes are added automatically. + + +ATTRIBSLOCAL  + + Defines the default attributes of messages entered in local areas. + + +ATTRIBSNET  + + Defines the default attributes of messages entered in netmail + areas. + + +ATTRIBSNEWS  + + Defines the default attributes of messages entered in news groups. + + +ATTRIBUTES  + + Defines the default attributes for area members of the current + Random System group. + + +BEEPCOMMENT  (yes) + + If enabled, GoldED will make a noise when the cursor in the + internal editor is moved across a word defined with the + EDITCOMMENT keyword. + + +BEEPLOCALMSG  (no) + + If enabled, GoldED will make a noise if it finds a msg with the + "Local" (LOC) attributes set. This can be useful for the sysop who + wants to monitor the msgs entered by users on his/her BBS. + + A related keyword is DISPLOCALHIGH. + + +BEEPNOISES  (yes) + + If enabled, GoldED makes noises when it wants attention. + + NOTE: This is the "master switch" for all noises in GoldED. + + +BEEPYOURMAIL  (yes) + + If set to "yes", GoldED will make a noise if it finds a + non-received message to one of your USERNAME's. If set to + "always", GoldED will make the noise even if it has already been + marked as received. + + +CARBONCOPYLIST  (Names) + + This specifies the format of the Carbon Copy list, as it will look + after processing. You can also change the format in the CC menu + before processing. + + The can be one of the following: + + Keep Keep the list as entered. + Names Convert list to "CC: Name, Name, Name.." format. + Visible Convert list to "CC: Name Address" format. + Hidden Convert list to "^aCC: Name Address" format. + Remove Remove the list completely. + + More details can be found in the Carbon Copy and Crossposting chapter. + + +COLOR  + + Using this keyword you can define or redefine all the colors used + in GoldED. See the Color Configuration chapter for details. + + A complete color setup consists of a quite a lot of COLOR + keywords, and it is normal practice to put them in a separate .CFG + file and use the INCLUDE keyword to let GoldED read it. The COLORS + archive contains a number of example color/mono setups. Try them + out if you think the default colors stink :-) + + +COLORSET  (Normal or Mono) + + Three color setups are built-in, and can be selected with this + keyword. + + The Normal set is the default when a color display adapter is + detected. The Normal set has all black background, with bright + neon-like colors for the window frames. Some hate it, some love + it. :-) + + The Intense set switches off the "blink" attribute, thereby + enabling the use of intense (bright) colors for the background + ("paper") colors as well as the foreground ("ink") colors. This is + used in the Intense set to make a bright white background, sort of + like the standard Windows 3.0 setup. + + The Mono set is the default when a monochrome adapter is detected. + + +CONFIRMFILE  (GOLDED.CFM) + + GoldED supports the Confirmation Receipt attribute, as used in + FrontDoor 2.xx with the FLAGS CFM kludge. If GoldED finds an + unreceived message to one of your USERNAME's with the CFM (or the + RRQ Return Receipt Request) attribute set, it generates an + automatic response message from the content of the CONFIRMFILE. In + the file you can use many of the template tokens to personalize + the automatic message. You can specify the default attributes for + the message with the ATTRIBSCFM keyword. + + Template tokens are explained in the Message Template chapter. + + +CONFIRMRESPONSE  (ask) + + An unreceived message to you with the CFM attribute set tells + GoldED that the sender has requested a receipt that you have read + the message. With this keyword you tell GoldED what to do when + such a message is found. Either always automatically generate the + receipt ("yes"), always ignore the requests ("no") or ask you in + each case. Older versions always generated receipts. + + +COOKIEPATH  (defaults to the GOLDPATH) + + Defines the default path for the @random template token. + + +CROSSPOSTLIST  (Verbose) + + This specifies the format of the Crosspost list, as it will look + after processing. + + The can be one of the following: + + None Crosspost without a list in the msgs. + Verbose Change the list to lines of "* Crossposted in ..." + Yes Also adds "* Crossposted in ...", but expands echolist + in line rather than in column. + Raw Keep the crosspost list as you entered it. + + More details can be found in the Carbon Copy and Crossposting + chapter. + + +CTRLINFO  + + Specifies if you want a tearline and/or origin in your messages. + + This keyword can ONLY be used in random system groups. + + This may be helpful for QWK users, who can now create a group for + the QWK areas and put "CTRLINFO No" in it. + + +CTRLINFOECHO  (Tearline Origin) + + Specifies if you want a tearline and/or origin in your echomail + messages. They will be added by your echomail processor if you + disable them here. + + Examples: + + CTRLINFOECHO Tearline Origin ; Add both tearline and origin. + CTRLINFOECHO Tearline ; Add only a tearline. + CTRLINFOECHO Origin ; Add only an origin. + + NOTE: If you use the last example, your mail processor may get + confused. However, most modern mail processors *can* handle msgs + without a tearline. + + +CTRLINFOEMAIL  (No) + + Specifies if you want a tearline and/or origin in your Internet + e-mail messages. This is not recommended. + + +CTRLINFOLOCAL  (No) + + Specifies if you want tearline and origin in your messages in + local areas. In local areas, the tearline and origin is normally + never required but can be used for cosmetic purposes. + + Examples: + + CTRLINFOLOCAL Tearline Origin ; Add both tearline and origin. + CTRLINFOLOCAL Tearline ; Add only a tearline. + CTRLINFOLOCAL Origin ; Add only an origin. + + +CTRLINFONET  (Tearline) + + Specifies if you want tearline and origin in your netmail + messages. In netmail areas, the tearline and origin is normally + never required but can be used for cosmetic purposes. + + Examples: + + CTRLINFONET Tearline Origin ; Add both tearline and origin. + CTRLINFONET Tearline ; Add only a tearline. + CTRLINFONET Origin ; Add only an origin. + + +CTRLINFONEWS  (No) + + Specifies if you want a tearline and/or origin in your Internet + news articles. This is not recommended. + + +DISPAREANO  (yes) + + This keyword specifies if GoldED should display the area number on + the top line in the reader. + + Yes Display it only if non-zero. + No Never display it. + Always Always display the area number. + + The area number is the same as that displayed in the leftmost + column in the arealist. This also means that the number displayed + can be either the "real" area number (Hudson/Goldbase/Ezycom + board) or the standard sequential number (toggleable with Alt-B in + the arealist). + + The number is displayed in square brackets to the left of the area + description. I am not sure that is the best place for it - things + are getting kinda crowded up there... Suggestions are welcome. + + +DISPATTACHSIZE  (kbytes) + + Controls how the size of attached files is displayed in the + header. Either the exact byte size, the rounded kbyte size, or not + displayed at all. If the kbytes setting is chosen, the value is + rounded according to the following formula: kbytes = (bytes + 512) + / 1024. So a 600 bytes file is rounded up to "1k", but a 500 bytes + file is rounded down to "0k". + + +DISPAUTONEXT  (yes) + + If enabled, GoldED will automatically jump to the next message + when entering an area. + + +DISPHDRDATESET  (-20 20) + + Specifies the position and length of the date field in the header + display. If a negative value is specified, that value is added to + the current display width. + + +DISPHDRNAMESET  (8 36) + + Specifies the position and length of the from/to name field in the + header display. If a negative value is specified, that value is + added to the current display width. + + +DISPHDRNODESET  (44 16) + + Specfies the position and length of the from/to node address field + in the header display. If a negative value is specified, that + value is added to the current display width. + + NOTE: The attributes display moves along with the DISPHDRNODESET + values. + + +DISPLISTCURSOR  (middle) + + Selects the starting position of selection bar in the message list + and nodelist browsers. + + Top At the top if possible. + NearTop At top + 1/3 if possible. + Middle At middle of possible. + NearBottom At bottom - 1/3. + Bottom At bottom. + + +DISPLISTWRAP  (no) + + Enables/disables wrap-around when the selection bar in the main + list/browser windows reaches the top or bottom. + + +DISPLOCALHIGH  (yes) + + If enabled, GoldED will display the FROM name with the highlight + color, if a message has the Local (LOC) attribute set. + + A related keyword is BEEPLOCALMSG. + + +DISPMARGIN  (0) + + This is the right margin (display width) used for message display. + If the value is 0 (zero), GoldED will default to the current + screen width. If a negative value is specified, that value will be + added to the current screen width (thereby decreasing the display + width relative to the screen width). + + If the DISPPAGEBAR keyword is enabled, the right margin is + automatically decreased by one char. + + +DISPMSGSIZE  (bytes) + + When enabled, this keyword displays the msgbody size in bytes, + kbytes or lines in the lower left side of the header. The size + displayed is for the message body text only, the header and + nul-terminator (and anything that may lurk beyond it) is excluded + from the calculation. + + NOTE: This feature currently only works when _reading_ msgs. While + editing a msg in the internal editor, this feature is disabled - + however, the size will be displayed when you are in the Save msg + menu (if EDITSAVEMENU is enabled). + + +DISPPAGEBAR  (yes) + + If enabled, a "pagebar" (similar to the scrollbar in GUI's) will + appear on the right margin, telling you about the relative size + and position in the message you are reading. It is only displayed + if a message is longer than a screenful. + + The pagebar automatically decreases the DISPMARGIN by one char. + + +DISPREALMSGNO  (no) + + GoldED can display the message numbers in two ways: + + 1. As the actual (real) msg numbers. + 2. As "relative" numbers, which are always sequential from msg + number 1. + + Normally the relative numbers are best, because they reflect the + actual number of msgs in the system. + + +DISPSOFTCR  (no) + + If enabled, GoldED will treat the so-called Soft-CR character + (ASCII 141, HEX 8D) just like any other displayable character, + instead of ignoring it like linefeed chars (LF). Note that by + enabling this feature, you _disable_ the character translation + feature that uses the Soft-CR as an escape character. This feature + was added to help users in countries which use the Soft-CR + character for other purposes like 2-byte characters in Japan. + + NOTE: The Ezycom msgbase format requires the Soft-CR to terminate + each line. Therefore this feature is unlikely to be useful to + Ezycom sysops. + + +DISPSTATUSLINE  (yes) + + If set to NO, the statusline with memory meter, clock etc. will be + disabled. This option has been implemented as a temporary help for + visually impaired users. More extensive help may be implemented in + future versions. + + +DISPTABSIZE  (4) + + The tab size (number of spaces) used when displaying the tab + (ASCII 9) character, and when pressing in the internal + editor. + + If you use an external editor, you should switch it to create + spaces instead of tabs, because tabs are technically not allowed + in FidoNet technology messages. + + +DOSPROMPT (yes/no) (yes) + + If enabled, GoldED will add a message about itself to the DOS + prompt when shelling out. + + +DOSSWAP  (yes) + + With this keyword you can specify what storage devices the DOS + shell swapper should try or use, and what order to try them in. + + It is only relevant for the standard 16-bit DOS version. The 386, + W32, OS/2 and Linux versions will ignore this keyword. + + The YES parameter tells the swapper to try EMS, XMS, DISK in that + order, and NO tells it not to swap at all (this will leave the + main part of GoldED in memory, and give you little room in the DOS + shell). + + You can specify your own order, such as "DOSSWAP EMS, XMS, DISK", + which makes it try it in that order, or "DOSSWAP EMS, DISK", which + makes it ignore XMS. + + If disk swapping is used, the swap file will be placed in the + SWAPPATH. + + These parameters modify the disk swapping behaviour: + + HIDE Hides the swapfile, if diskswapping is used. + CHECKNET For some reason, disk swapping is slower if running + on a (Novell) network without this. + NOPREALLOC Use this if you are always running on a network + (instead of enabling CHECKNET). + + IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT + + Some programs use extended memory in ways that may conflict with + the XMS extended memory driver, causing inexplicable crashes. If + you have problems, you should first try turning off the OVERLAY + keyword, and if it still fails, turn off DOSSWAP (or stop using + those other programs :-) + + +EDITAUTOATTACH  (yes) + + If enabled, and you use drivespec (C:, D:, etc.) in the subject in + a netmail message, GoldED will automatically turn on the file + attach attribute. Autoattaching only works if the subject has been + edited, so that subject files will not automatically be + re-attached in replies. + + +EDITAUTOSAVE  (30) + + If a non-zero value is given, the internal editor will + automatically execute the EDITsavefile function with intervals of + . Good for keeping automatic backup of the message you + are writing. The saved file can be restored with the EDITloadfile + command. The name of the saved file is defined with the EDITORFILE + keyword. + + If disaster strikes (crash, lockup, power blackout, etc.) while + you are writing a message in the internal editor, this feature + lets you continue from the last autosaved message, which will + popup automatically when you enter the internal editor again. + + NOTE: This feature only works 100% if KEYBMODE is set to "poll". + If KEYBMODE is set to "block", autosave won't happen until you + press a key after the interval has passed. + + +EDITCHANGEDATE  (yes) + + If set to "always", GoldED will always "touch" the message date in + the header, if you change a message after saving it. + + If set to "yes", GoldED will only "touch" the message date in the + header, if you change a message written by yourself. This is + useful in cases such as when you need to edit messages written by + other people (in-transit netmails for example) which may be + mis-addressed or something without messing up the date. + + If set to "no", the message date is not changed when changing a + message. + + +EDITCHARPARA [']['] (' ') + + This keyword defines the character GoldED displays at the end of + paragraphs in the internal editor. This is where the CR character + will be placed once the msg is saved. + + +EDITCHARSPACE [']['] (' ') + + This keyword defines the character GoldED displays when it should + display a space character in the internal editor. See also the + description of the EDITCHARPARA keyword. + + The keywords EDITCHARPARA and EDITCHARSPACE were added to aid me + while rewriting and debugging the new internal editor. By + redefining them to visible characters instead of spaces, I could + see if strange things were happening while inserting or deleting + characters. This was a great help. Personally I now always use + redefinitions to ASCII 20 (a paragraph sign) and CP437 250 (a + small dot). + + +EDITCOMMENT <"word"> <"comment"> + + This feature is mostly for fun :-) + + It allows you to define words which causes GoldED to display a + comment in the statusline, when you place the cursor on the word + in the internal editor. + + Example: + + EDITCOMMENT ":-(" "Don't worry, be happy!" + EDITCOMMENT ":-)" "Are we having fun yet?" + EDITCOMMENT ";-)" "Wink wink, nudge nugde..." + EDITCOMMENT "!!!" "Flame Warning!" + EDITCOMMENT "GoldED" "Great program, isn't it?" + EDITCOMMENT "Odin" "One more 'n' please." + EDITCOMMENT "Odinn" "That's right :-)" + + Have fun with it! + + +EDITCOMPLETION <"abbreviation"> <"completion"> + + This feature allows you to define abbreviations which will be + automatically expanded to full words or sentences when typed in + the internal editor. Examples: + + EDITCOMPLETION "/Odin" "Odinn" + EDITCOMPLETION "/GED" "GoldED" + EDITCOMPLETION "/V7" "Version 7" + EDITCOMPLETION "/FD" "FrontDoor" + EDITCOMPLETION "/WfW" "Windows for Workgroups" + + NOTE! The abbreviation is case-sensitive. If "XX" is defined as + an abbreviation, completion will NOT be triggered if "xx" is + typed. + + +EDITCRLFTERM  (no) + + If enabled, all text paragraphs in your messages will be + terminated with a CR/LF combination. If disabled, only a single CR + is used. This option was created to fix a problem with an older + version of the Dutchie mail processor, that apparently needed the + CR/LF termination of kludge lines. + + +EDITFIELDCLEAR  (yes) + + If enabled, the input-fields will be automatically cleared for new + entry, if a non-edit key is the first key pressed. + + +EDITHARDLINE  ("<<") + + The string is needed if you use an external editor that terminates + all lines with a CR or CR/LF. The hardline string acts as a text + paragraph terminator, and the normal CR's are ignored. + + The concept of "hardlines" is explained in the Hardline Feature + chapter. + + +EDITHARDLINES  (yes) + + This keyword enables the "hardline" feature. If disabled, the + EDITHARDLINE string is never written to the editor message file, + and the editor message file is read back exactly as entered, + including terminating CR's on all lines. + + +EDITHARDTERM  (no) + + If enabled, GoldED will hard-terminate all lines in your messages + at the editor margin. It is recommended to enable this keyword for + Internet e-mail and newsgroups, because some user-unfriendly + Internet software does not wrap long lines properly. But DON'T + enable it in normal FidoNet echomail. + + This keyword can be used globally and in Random System groups. + + +EDITHDRNAMESET  (8 36) + + Specfies the position and length of the from/to name field in the + header edit display. If a negative value is specified, that value + is added to the current display width. + + +EDITHDRNODESET  (44 36) + + Specfies the position and length of the from/to node address field + in the header edit display. If a negative value is specified, that + value is added to the current display width. + + +EDITHEADERATTRS  (yes) + + This keyword allows you to turn off the large attributes window + that is shown during header edit. Even if the window is turned + off, the Alt-keys are still active for toggling attributes. + + +EDITHEADERFIRST  (yes) + + This keyword controls the circumstances that will present you with + the header editor first of all. + + New When entering a new message. + Changes When changing a message + Replies When making a reply. + Forwards When forwarding a message. + Yes Always (all of the above). + No Never. + + The New, Changes, Replies and Forwards values can be combined. YES + is equivalent to enabling all four of these. + + For example, we want to edit the header only when entering a new + message or when changing a message: + + EDITHEADERFIRST New, Changes + + If the circumstances match the setup of this keyword, the header + edit will be bypassed and you will start directly in the EDITMENU + (if enabled) or in the internal or external editor. A new menu + item has been added in the EDITSAVEMENU, "Edit Header", which + allows you to edit the header after you have written your message, + but before it is finally saved. + + If you set EDITHEADERFIRST to NO, you must either have the + EDITSAVEMENU enabled, or use the internal editor, because + otherwise it is not possible to edit the header at all. + + +EDITINTERNAL  (yes) + + Specifies if the internal editor should be the default, even if an + external editor is defined. You can always change the setting in + the editor menu (if EDITMENU is enabled) before you start writing + your message. + + +EDITMENU  (yes) + + This keyword enables or disables the "Edit menu" that pops up + right after you have edited the message header. If you disable the + menu, you will go to the internal or external editor immediately + and save a keystroke, but you will of course lose the features + available from the menu, such as selection of template etc. + + +EDITMIXCASE  (no) + + If this keyword is enabled, GoldED will automatically format the + name with uppercase the first letter in words and lowercase the + rest, when entering names in the header. + + Examples: + + "odinn sorensen" or "ODINN SORENSEN" + + These would be re-cased to "Odinn Sorensen". + + +EDITMSGSIZE  (64000 in DOS, 512000 in all others) + + This lets you limit the size of loaded msgs. GoldED currently + cannot handle msgs larger than 64k in the DOS version (all other + platforms do not have this limit). This keyword ensures that the + system will not get confused and possibly crash or exit, if a + message was encountered that was larger than 64k. + + +EDITOR [@file] [@line] + + With GoldED it is possible to use your favorite text editor or + even word processor to write messages. With this keyword you + specify the commandline for the editor. + + If you use a word processor, be sure to make it export clean ASCII + text files without control codes. You may also need to enable the + DOSSWAP keyword, if the editor or word processor requires a lot of + free memory to run. + + Program commandline. + @file Token which is replaced by the editor message + filename. + @line Token which is replaced by the @Position + template line number. + + +EDITORFILE  (GOLDED.MSG) + + Defines the name of the temporary editor message file. This file + is written by GoldED when swapping to the external editor, or when + using the EDITsavefile command in the internal editor. + + The file is written in the GOLDPATH if there is no explicit path. + + +EDITQUOTEMARGIN  (75) + + Sets the right margin for editing quoted lines in the internal + editor. This should be set to the same or wider than the + QUOTEMARGIN. + + +EDITREPLYRE  (no) + + If enabled, GoldED inserts the "Re:" string in front of the + subject when you reply to a message. If not enabled, GoldED will + strip any leading "Re:" when you reply to a msg. + + The "Re:" string in subjects is an obsolete practice, and today it + only slows down modern replylinking software. Do yourself and + others a favor and let GoldED strip the Re: in your replies. + + The "numeric" option makes GoldED use numeric Re:'s, of the form + "Re^n:". + + This keyword can be used globally and in Random System groups. + + +EDITSAVEMENU  (yes) + + This keyword enables or disables the "Save menu" that pops up + after you have edited your message in the internal or external + editor. If you disable the menu, your message will be saved (or + discarded if not edited) immediately and save you a keystroke, but + you will also lose the features available from the menu. + + +EDITSAVEUTIL <"L menu text"> + + Defines the external utilities that will be added to the + EDITSAVEMENU (if enabled). The menu text is inserted in the menu. + The first two characters of the menu text are the "hotkey" letter + that will be highlighted in the menu text, plus a space. Example: + + EDITSAVEUTIL 1 "S PGP Sign the msg" + EDITSAVEUTIL 2 "l PGP Clear-Sign the msg" + EDITSAVEUTIL 3 "E PGP Encrypt the msg" + EDITSAVEUTIL 4 "p PGP Encrypt & Sign the msg" + + If you have changed the default language in this menu (in + GOLDLANG.CFG), then make sure the highlight letters don't clash. + + With EDITSAVEUTIL definitions and EDITSAVEMENU enabled, you can + directly call an external utility to do things like encoding or + encrypting msgs before saving them. + + +EDITSOFTCRXLAT  + + If a translation char is defined, GoldED will translate the + soft-cr character (ASCII 141, HEX 8D) in prompts and in the + internal editor. Example: + + EDITSOFTCRXLAT H + + This example for russians translates the soft-cr to an 'H'. + + Please note that this option only applied when DISPSOFTCR set to + YES. + + +EDITSPELLCHECK [@file] + + While in the internal editor, you can use the EDITspellcheck + command to save your message to a file and shell to external + spellchecking software. When the check is completed, the corrected + file is read back and you can continue editing your message. The + EDITspellcheck command internally uses the EDITsavefile and + EDITloadfile commands. + + Spellchecker program commandline. + [@file] Token which is replaced by the message filename + (defined by the EDITORFILE keyword). + + +EDITUNDELETE  (50) + + This keyword defines the number of lines to keep in the undelete + buffer between messages. + + +EMPTYTEARLINE  (no) + + With this keyword enabled, GoldED will always strip the tearline + down to just the three dashes, "---", and instead inserts the PID + (Product IDentification) kludge line, which contains the same + information, but in a safer form in a safer place. The PID kludge + is proposed in FidoNet document FSC-0046. + + +ENCODEEMAILHEADERS  (yes) + + By default headers in e-mails MIME-encoded according to RFC. In + Russia it is general practice not to encode headers, so you + probably want to say no if you're in Russia. + + +ENDGROUP + + Ends a Random System GROUP definition. + + +EVENT  + + This keyword allows you to specify which soundfile to play when a + specfic event occurs. The following 's are defined: + + EVENTTYPE TRIGGER: + + Arealist When the arealist shows. + AskYesNo Any Yes/No type prompt. + Attention Warnings or information popup messages. + DosShell When entering a DOS or OS/2 shell. + EditComment When an editcomment is found. + EndOfMsgs When there are no more msgs in the area. + ErrorFatal Fatal error exit. + Exit Exit from GoldED. + JobDone Successful completion of a job. + JobFailed Unsuccessful completion of a job. + MsgDeleting When deleting a msg. + MsgFromYou When a msg from you is found. + MsgIsLocal When a msg marked Local is found. + MsgIsTwit When a msg from a Twit is found. + MsgToYou When a msg to you is found. + SearchFailed Search operation failed. + SearchSuccess Search operation was successful. + Startup When the GoldED startup screen shows. + + There is currently only one defined: + + PLAY . + + The parameter to PLAY can be either a sound file or one of the + following standard beepnoises: + + TheEnd A high and a low note. + GotIt Two sets of low-high notes. + TooBad A falling note. + ToYou A rising and falling note. + SayBiBi A single beep. + SOS Morse S O S (...---...). + + If a sound file is specified, the sound driver must support the + format. + + The DOS and 386 versions need a Goldware Sound API compatible TSR + or program loader which installs an interrupt service function on + the multiplex interrupt 2Dh. See the chapter about the Goldware + Sound API for more details. The GCTVSAPI program loader (released + separately) currently only supports the CT-VOICE.DRV driver for + .VOC files. + + The OS/2 version relies on MMPM/2 (using the mciSendString API + call) to play the sound files. On my system with a Sound Blaster + Pro, MMPM/2 plays both .WAV and (to my surprise) .VOC files. It + even plays .MID files :-) + + The Win32 version uses the Win32 API to play the sound files. It + should be able to play any multimedia file that Windows knows how + to handle. + + Example usages: + + EVENT MsgToYou PLAY HIMAN.VOC + EVENT MsgIsTwit PLAY SHOTGUN.VOC + + You have to select the sounds carefully and probably with a lot of + experimentation, unless you want to turn your mailreader into a + honking, wailing and farting monster and drive your poor family or + yourself nuts with a cacophony of noises... + + +EXCLUDENODES  + + You can define up to 50 different addressmasks to be excluded from + the compiled nodelists. Use this if you are short of space, or the + nodelist compile takes very long on your system. This keyword is + used by GoldNODE. + + Excluded nodes can be re-included with the INCLUDENODES keyword. + + +EXTERNOPTIONS <-options> + + Defines the default options for the EXTERNUTIL's. Valid options: + + -Cls * Clear screen. + -Cursor * Cursor in shell. + -KeepCtrl * Keep control lines in the message. + -Pause Pause for keypress before returning to GoldED. + -PauseOnError * Pause only if utility errorlevel is nonzero. + -Reload * Reload the message file (@file). + -Swap * Swap GoldED out of memory before shelling. + -Wipe Wipe editorfile and temporary file after use. + + Plus the reverse options with a "No" prefix, for example -NoCls. + The default options are marked with an asterisk (*). + + Use -NoKeepCtrl when you want to clearsign a message. This will + strip the control lines (kludges, tearline and origin) from the + message before passing it to the external utility. The tearline + and origin is appended to the message when reloading it. The + default is to keep control lines in the message. + + Use -Wipe when you want the temporary unencrypted message files to + be wiped and removed from the disk after they have been read into + memory. GoldED wipes a file by writing a block of 512 random bytes + over the entire length of the file, then truncating it to zero + bytes and finally deleting it. The default is not to wipe files. + + +EXTERNUTIL [-options]  + + This new feature can be used to "filter" msgs, for example calling + PGP or other encryption utilities. + + The must be in the range 1 to 24 for utilities that will + be called with key definitions (see below). Higher numbers can be + used for utilities that are called from the EDITSAVEMENU (if + enabled). See the EDITSAVEUTIL keyword for details. + + The default options are those specified with the EXTERNOPTIONS + keyword. With [-options], you can change the those options locally + for specific utils. See the EXTERNOPTIONS keyword for a list of + valid options. + + The specfies the DOS or OS/2 commandline you want to + execute. This works in the same way as for the external editor and + spellchecker. See the manual for details about this, especially if + you want to execute batchfiles. In the you can use + @tokens to transfer information from the msg to the commandline. + The @tokens are the same as for templates, and in addition you can + use two other @tokens: + + @path The GOLDPATH, including a trailing backslash. + @file The full filename of the message file (GOLDED.MSG) + that will be written to disk before the utility is + called. + @tmpfile The full filename of a temporary message file + (GEDTMPxx.xxx) that will be written to disk before the + utility is called. + + Examples: + + EXTERNUTIL 1 c:\4dos\4dos.com /c c:\crypt\encrypt.bat @file + EXTERNUTIL 2 c:\4dos\4dos.com /c c:\crypt\decrypt.bat @file + + To call a defined external utility, you must assign a key to it. + There are 24 new keyboard commands you can use in GOLDKEYS.CFG for + this purpose: + + ExternUtilNN + + Where NN is in the range 01 to 24 _with_ leading zero. Examples: + + F11 ExternUtil01 + F12 ExternUtil02 + + Then if you press F11, you would call external utility number 1 + and so on. The ExternUtilNN keywords ONLY work in reader mode, not + in the internal editor or any other place. + + HOW IT WORKS: + + 1. Just before the external utility is called, GoldED writes the + current message text to the GOLDED.MSG file in the GOLDPATH. + The file is written as a textfile with each line CR-LF + terminated. The content is exactly as you see it on the + screen, which means that kludges are only included if you have + enabled kludge viewing. If the -NoKeepCtrl option is used, + kludges, tearline and origin are stripped before the file is + written. If the token @tmpfile is used, a temporary file named + GEDTMPxx.xxx (where xx.xxx is something unique) is created + with exactly the same content as @file. + + 2. GoldED clears the screen and then calls the utility after + swapping itself out of memory (if swapping is enabled or + relevant for the version). + + 3. The utility can now load and process the @file and/or + @tmpfile, or do anything else you want. It doesn't have to + have anything to do with the current msg. You could call a + spreadsheet, a game, whatever. But I think this feature will + mainly be used for utilities that process the @file. If the + utility processes the @file, it could write the changes back + to the @file. + + 4. After returning from the utility, GoldED reloads the @file and + displays it just as if it was the current message. For + example, if your utility was a decrypter and the msg was + encrypted, you would now see the decrypted msg. Neat eh? :-) + + 5. If you want to make the reloaded text permanent (save it in + the msg), you can use the Change Msg function and immediately + choose "Save Message" from the Editing menu (if enabled with + EDITMENU Yes). This is in fact the method you could use if you + wanted to EN-crypt a msg (however, it is easier to use the + method which involves the EDITSAVEUTIL keyword). + + The QUOTESPACING feature can interfere with encoded msgs that + include the '>' character at the beginning of lines (often seen in + uuencoded msgs), by automatically inserting blank lines before and + after the lines with '>'. I have therefore changed the + quotespacing default from YES to NO. Be sure to check if you have + a different setting if you are using an older edition of the + advanced configuration files. + + If the string "-----BEGIN PGP MESSAGE-----" is found as the first + 27 characters in a reloaded message, GoldED will automatically add + the FSC-0073 kludge "^aENC: PGP" to indicate that the message is + encrypted. This kludge may be used by some software to set up + alternative routing for encrypted mail which would otherwise be + bounced if sent through normal channels. + + See the "Using PGP as an External Utility" chapter for batchfile + examples and instructions on how to use this new feature with PGP. + + !!! IMPORTANT !!! From FidoNet Policy 4.07 (chapter 2.1.4): + + "[..] Therefore, encrypted and/or commercial traffic that is + routed without the express permission of all the links in the + delivery system constitutes annoying behavior." + + So be careful with this feature! + + TIP: You can use the EXTERNUTIL feature to setup keys to view or + print an attached fax. Use something like this in GOLDED.CFG: + + EXTERNUTIL 11 c:\zfax\zfax.com pf @subject ; print fax + EXTERNUTIL 12 c:\zfax\zfax.com vf @subject ; view fax + + And this in GOLDKEYS.CFG: + + @F11 ExternUtil11 ; Press Alt-F11 to print the fax + @F12 ExternUtil12 ; Press Alt-F12 to view the fax + + Or choose your own key assignments and fax view/print utils. + + Note that this assumes that the fax file is listed in the subject + line like an attached file. + + NOTE: If you're running GoldED/386 and try to use a Win32 program + as an EXTERNUTIL, you might get the error "This program cannot be + run in DOS mode". You can work around this by calling the Win32 + program via the shell. For example if this call fails: + + EXTERNUTIL 1 c:\utl\mywin32.exe @file + + Replace it with: + + EXTERNUTIL 1 command.com /c c:\utl\mywin32.exe @file + + Then it should work. If not, try using full path to command.com. + + +EZYCOMMSGBASE  + + Defines the base path for the Ezycom msgbase. If not set, AREAFILE + Ezycom will set it. + + +EZYCOMUSERBASE  + + Defines the base path for the Ezycom userbase. If not set, + AREAFILE Ezycom will set it. + + +EZYCOMUSERNO  (0) + + Defines the lastread set used in the Ezycom message base. + + +FIDOHWMARKS  (no) + + If enabled, GoldED will use the echomail "highwater mark" (1.MSG) + to determine if a message is "sent" or "unsent" in *.MSG areas. + + NOTE: Some older echomail processors do not update the highwater + mark in a way that GoldED can recognize. If all messages appear to + marked "Uns", even after the mail has been scanned out, try + turning off this keyword. + + +FIDOLASTREAD  (LASTREAD) + + Defines the filename of the *.MSG lastread files. DO NOT specify a + path. + + +FIDOMSGTYPE  (Opus) + + This keyword defines the default format of Fido *.MSG files. It is + only used by some AREAFILE's when reading external area + configuration files, where the preferred format is unknown. + + The FTS1 (FTS-0001.012 and later) format uses zone/point fields, + where the Opus format uses date/time stamps. When set to Opus + format, GoldED interprets the date/time stamps as DOS-style + bitmapped date/time. + + +FIDONULLFIX  (no) + + If set to YES, GoldED will replace NUL chars with LF chars in the + msg body when reading a Fido *.MSG file. This is slower of course, + but not noticably on fast machines. + + This option was created to enable GoldED users to read msgs that + were created/handled by brain-dead programs (I don't have names, + sorry) which are not obeying our primary technical standard: + FTS-0001. FTS-1 states that a NUL terminates the msg body. But + sometimes msgs are encountered which have a NUL as the first char + in the msg body or perhaps in other places, thereby causing GoldED + to show a blank or cut-off msg. In some Pascal-based readers, such + as FM, these msgs can be read anyway, because in Pascal a NUL does + not terminate a string like in C/C++. + + NOTE: Even if the new FIDONULLFIX keyword is disabled, GoldED will + still fix a NUL if it is the _first_ character in the msg body. + This probably fixes most of these buggy msgs without the overhead + of checking the entire msg. + + +FIDOUSERLIST  + + Path and filename of a FIDOUSER.LST file. + + This file is expected to be sorted in ascending alphabetical order + using plain ASCII case-insensitive sort. Each line in the list is + expected to be 60 characters plus a CR and a LF, or in other words + records of 62 bytes each. If the list is produced by a nodelist + compiler, everything should be okay, but be careful if you have + edited the file manually. Note that a FIDOUSER.LST file only + supports a name lookup (to get the address). + + +FIDOUSERNO  (0) + + This is an index into the FIDOLASTREAD file. Each user occupies 2 + bytes in the lastread file. + + +FILEALIAS  + + Used to define short alias names for filenames. If you regularly + write msgs to different files in different paths, this feature is + very useful, and reduces the risk of typing wrong. + + Example: + + FILEALIAS DKB R:\DKBBS\DKBBS + + With this file alias, you can simply write "DKB" at the filename + prompt, and the long filename will be used. + + +FILELISTPAGEBAR  (yes) + + Enables or disables a pagebar (scrollbar) in the file attach list + function. + + +FORCETEMPLATE  (no) + + If enabled, GoldED will popup a template selection menu when you + start writing a new msg or reply. If you have both TEMPLATE(s) and + FORCETEMPLATE in a Random System group, you can tell GoldED to use + the random template(s) by hitting ESC instead of selecting from + the menu. + + This keyword can be used globally and in Random System groups. + + +FORMFEEDSEPARATOR  (no) + + Used when saving messages to file. If enabled, it inserts a Form + Feed (12d) character after each message. + + +FRQEXT <.ext> + + With this keyword you can add extra known filename extensions for + the filerequest function. The following extensions are already + known by default, and need not be defined (duplicate definitions + are ignored): + + .ARC .ARJ .DOC .EXE .GIF .LHA .LZH .JPG .PAK .PNG .RAR .RUN .SDA + .SDN .TXT .ZIP .ZOO + + Each extension _must_ have the leading dot. + + Example: FRQEXT .XYZ + +FRQNODEMAP  + + This keyword is used for the file request feature (Ctrl-F). It + allows you to define mappings from a nodenumber used in a file + announcement to another nodenumber. This is useful in the cases + where a multi-line system announces files using their primary + nodenumber, which may be a regular V34 modem number, but they also + have an ISDN number, which you would prefer to use instead. + Examples: + + // change-to: from: + FRQNODEMAP 2:236/99 2:236/100 + FRQNODEMAP 2:236/1043 2:236/43 + + So, if I saw a file announcement from 2:236/100, and requested + some files, the request would automatically be addressed to + 2:236/99. + + +FRQOPTIONS  (FromTop) + + Defines options for the file request function: + + Sort Sort the list of files alphabetically. + FromTop Scan the message from the top of the message. + NotFromTop Scan the message from the top of the screen. + NoFiles Don't list the file FILES if no files were found. + NoWazooMsg Don't save the request message. + Fast Bypass the header edit and save the msg immediately. + + By default, the "FromTop" option is enabled. If you often request + files from very long announcement messages, you might find it very + useful to set the "NotFromTop" option. + + The "NoFiles" option was added because if no filenames are found + in a message, the file request function defaults to listing the + magic name FILES instead of complaining that no files were found. + + If the FRQWAZOO keyword is enabled, the default behaviour is to + save the request message with the FRQ attribute stripped. Use the + "NoWazooMsg" option if you don't want the request message. + + Use the "Fast" option if you find that you almost never change the + destination of the file request message anyway. If you enable this + option, remember that you can always go over to the netmail area + and change the file request message before it is sent. + + The UseFlowFile option enables a feature which was default in + 2.50, but which I have been informed is problematic for modern + mailers in some setups. The default is now to ONLY create/update + the .REQ file and NOT also touch/create a .?LO flowfile. + + +FRQWAZOO  (no) + + If enabled, GoldED will create WaZOO .REQ files instead of file + request messages. You must define an OUTBOUNDPATH if you enable + this feature. + + +GEDHANDSHAKE  (yes) + + If this switch set to yes GoldEd displays handshake char in + statusline. If you annoyed with this feature you could hide this + character by setting this option to no. + + +GERMANKEYBOARD  (autodetect) + + This option is meanful for w32 version only. Due to right Alt key + required to enter some native characters in german version of + Windows it could be defined to yes for this. + + +GOLDBASEPATH  + + Specifies the directory where GoldED can find the Goldbase msgbase + files. + + +GOLDBASESYSPATH  + + Specifies the directory where GoldED can find the NETMAIL.DAT and + ECHOMAIL.DAT files of the Goldbase msgbase. If not specified, the + GOLDBASEPATH is used. + + +GOLDBASEUSERNO  (0) + + Specifies the lastread set used in the Goldbase message base. + + +GOLDPATH  + + This is the path where GoldED finds all it's control files. It is + not necessary to define this, unless you have special needs. The + GOLDPATH defaults to directory where the GOLDED.CFG file was + found. + + +GROUP  + + Starts a Random System group. See the Random System chapter for + details. + + +HAPPYBIRTHDAY  + + The only valid value is "friend". Currently do nothing. + + +HIGHLIGHTUNREAD  (no) + + If enabled, GoldED updates (increases) the "timesread" field in + each message that you read. If set to NO, it doesn't touch the + message. The YES setting causes a slight performance decrease, + because the header of each message has to be read, the timesread + field updated and the header written back to disk. The update + happens immediately after the message is displayed, so you may not + notice it at all. A message is only updated if the timesread field + contains the value 0 (zero). + + This keyword only works in the following msgbase formats: Fido + (*.MSG), Hudson, Goldbase, JAM, Squish, Ezycom and AdeptXBBS. In + Squish and Ezycom, there is no timesread field, but I have annexed + a reserved message attribute (in Squish, 0x00080000, now called + MSGSEEN; in Ezycom, extattr 0x80) for the purpose of marking a + message as read at least once. The other formats (PCBoard, + WildCat) have no timesread field, but they have reserved fields or + attributes which *could* be used. Let me know if you want this. + + +HUDSONPATH  + + Specifies the directory where GoldED can find the Hudson msgbase + files. + + +HUDSONSIZEWARN  (16000000) + + When the Hudson MSGTXT.BBS file exceeds this size, GoldED starts + to warn that the msgbase is getting dangerously close to the + structural limit (which is 16MB for the MSGTXT.BBS file). With + this keyword you can raise or lower the warning size in case you + think the default is too low or too high. + + +HUDSONSYSPATH  + + Specifies the directory where GoldED can find the NETMAIL.BBS and + ECHOMAIL.BBS files of the Hudson msgbase. If not specified, the + HUDSONPATH is used. + + +HUDSONUSERNO  (0) + + Specifies the lastread set used in the Hudson message base. + + +IGNORECHARSET  (no) + + If set to yes then GoldEd ignores CHRS kludges in messages thus + you will be able to switch codepage in messages with inappropriate + charset. + + +IMPORTBEGIN  ("=== Cut ===") + + This keyword, together with IMPORTEND, defines some text to add in + the beginning and end of an imported text file in the internal + editor. If only IMPORTBEGIN is defined, the text is also used for + the IMPORTEND. The may be enclosed in quotes ("") if + leading or trailing spaces are needed. The quotes are stripped. + + The replacement token "@file" can be used in the . It will + be replaced with the import filename as entered. + + Example: + + IMPORTBEGIN === Cut Begin: @file === + IMPORTEND === Cut End === + + +IMPORTEND  (same as IMPORTBEGIN) + + See IMPORTBEGIN. + + +INBOUNDPATH  (defaults to GOLDPATH) + + The inbound path is currently only used with the file request + feature (the READfilerequest command, ). If you use this + feature, GoldED will put the file descriptions into a FILES.BBS in + the inbound path, ready for when the requested files are moved to + the correct file areas. + + +INCLUDENODES  + + You can define up to 50 different addressmasks to be included from + the compiled nodelists. This is only used in conjunction with the + EXCLUDENODES keyword to include otherwise EXcluded nodes. This + keyword is only used by GoldNODE. + + +INPUTFILE  (*) + + Defines the default name in the internal editor file import + function. + + GoldED can automatically uuencode and apply a base64 encoding to + the files during importing them into the internal editor. + + NOTE: This is a very simple implementation of encoders. It cannot + split large files over several messages. The file mode number 644 + is hard-coded and has nothing to do with the actual file mode. + + This keyword can be used globally and in Random System groups. + + +INTENSECOLORS  (no) + + GoldED is capable of switching off the "blink" color, and thereby + enabling the use of bright background (paper) colors. Enable this + keyword, and try out one of the intense color setup examples. + + +INTERNETADDRESS  + + Specifies your Internet address. This must be the address only, no + name. The INTERNETADDRESS and USERNAME will be combined to a + standard "From: internetaddresss (username)" headerline when you + write e-mail or articles. + + Example: + + USERNAME Odinn Sorensen + INTERNETADDRESS odinn@ibm.net + + Produces the RFC line: + + From: odinn@ibm.net (Odinn Sorensen) + +INTERNETDOMAIN  (username%domain.net) + + Defines the domain-part of outgouing Message-ID's. If you don't + know your full domain, leave it as default, which should work just + fine. + + +INTERNETGATE [gatename<,>]
 + + Defines the local Internet gate you use when sending netmail to + Internet users. This option is activated when you write an + Internet address in the TO: field in the header display. GoldED + detects the Internet address by looking for the '@' character. If + detected, GoldED puts the gate address from INTERNETGATE in the + TO: address field. If you have defined the optional gate name + (typically UUCP), GoldED also replaces the typed Internet address + with the gate name and puts the Internet address in a TO: line in + the message body. Some gate software accepts the Internet address + directly in the header, while other software may need the special + (UUCP) name and a separate TO: line. Examples: + + INTERNETGATE UUCP, 1:105/42 ; Standard, with gate name + INTERNETGATE 2:230/9316 ; My uplink runs GIGO software + + This keyword can be used globally in GOLDED.CFG, if you only ever + use one gate, or in GROUP's for specific areas in GOLDRAND.CFG if + you have multiple netmail areas and regularly use more than one + gate. + + NOTE: If you enable the INTERNETRFCBODY keyword, you should always + use the gatename UUCP, because otherwise the gateway software may + send duplicate copies (carbon copies) of your e-mails. + + +INTERNETLOOKUP  (no) + + If set to Yes, GoldED will check the systemname in the nodelist + when doing a lookup and if the systemname looks like an Internet + address (contains an '@' char), the msg will be addressed to that + Internet address using the INTERNETGATE name/address if defined. + + For example, let's say there was something like this in the + nodelist: + + ,999,somebody@somewhere,Whereever,Some_Body,... + + And this in my GOLDED.CFG: + + INTERNETLOOKUP Yes + INTERNETGATE 2:230/9316 + + Then if I did a lookup of "Some Body" and selected the entry with + the Internet address, GoldED would make a msg looking like this: + + -------------------------------------- + From : odinn@winboss.dk 2:236/77 + To : somebody@somewhere 2:230/9316 + Subj : whatever + -------------------------------------- + + Or if my gate was defined as "INTERNETGATE UUCP 2:230/9316": + + -------------------------------------- + From : odinn@winboss.dk 2:236/77 + To : UUCP 2:230/9316 + Subj : whatever + -------------------------------------- + To: somebody@somewhere + + So what's the use of all this? It allows you to make a + nodelist-style list of users with Internet addresses and use it + with GoldED so that you can do a lookup of normal names instead of + trying to remember strange Internet addresses. Of course something + similar could be done using the ADDRESSMACRO's, but with the + nodelist approach, you could build a "network" of users which have + offline Internet access via FTN-gate software and distribute the + nodelist for automatic processing. + + +INTERNETMSGID  (no) + + Specifies whether the FTN MSGID kludge should contain an RFC1036 + compatible Message-ID or the normal FTS-9 format. Note that using + the RFC1036 format in MSGID breaks the FTS-9 (version 001) + specification, so please don't use this feature in FidoNet netmail + or echomail. As a safeguard, GoldED will only use the RFC1036 + format in areas specifically marked as e-mail or newsgroups, using + the SOUPEMAIL and SOUPNEWSRCFILE keywords or using the Email and + News area types with the AREADEF keyword, even when INTERNETMSGID + is set to YES globally. + + +INTERNETREPLY  (yes) + + When INTERNETREPLY is enabled, GoldED always uses the FSC-35 + REPLYADDR/REPLYTO kludges to gate replies to msgs from Internet + correctly. If disabled, GoldED only uses the FSC-35 method if the + Internet address is too large to fit in the max-35-character TO: + header field. Some gate software requires that the FSC-35 method + is used, while other software accepts Internet addresses directly + in the header. + + +INTERNETRFCBODY  (no) + + Tells GoldED whether to look for and process RFC headerlines at + the top of the message body, before the first empty line. Also + tells GoldED to insert its own RFC headerlines at the top of the + message body instead of as kludge lines. This option should only + be used when receiving Internet mail as QWK packets where the RFC + headerlines are usually found at the top of the messages, or when + sending Internet mail via FTN packet to a gateway running GIGO. + GIGO does not recognize RFC header in kludges, but it does + recognize them at the top of the messages, if it is properly + configured (with lines of "Allow_Xxx:" in GIGO's HEADERS.CFG, + where Xxx are the RFC headerlines the gate administrator wants to + allow). + + +INTERNETSERVER  +INTERNETSERVER [] [] + + No code currently associated with this keyword. + + +INVALIDATE <"findstring"> <"replacestring"> + + This is used to invalidate (change) certain control strings in + quoted text. Use this in conjunction with old versions of D'Bridge + or other software that chokes on control strings in quoted text. + As an added bonus feature, if the tearline or origin is + invalidated to a null string (""), they will not be quoted at all. + + The can be one of the following: + + Tearline Invalidate tearline ("---"). + Origin Invalidate origin (" * Origin: "). + Seenby Invalidate SEEN-BY's. + + By default, the following invalidations are used: + + INVALIDATE Tearline "---" "-+-" + INVALIDATE Origin " * Origin: " " + Origin: " + INVALIDATE Seenby "SEEN-BY" "SEEN+BY" + + If you want to disable invalidation entirely, use this: + + INVALIDATE Tearline "---" "---" + INVALIDATE Origin " * Origin: " " * Origin: " + INVALIDATE Seenby "SEEN-BY" "SEEN-BY" + + The defined INVALIDATEs are also used during importing a file when + editing a mail in the internal message editor. + + +JAMHARDDELETE  (no) + + The default setting makes GoldED conform to the JAMAPI specs when + deleting msgs in JAM msgbases. This means that deleted msgs are + only marked as such in the message header, not in the index. As a + result, GoldED will find and display the deleted msgs until you + run a message pack utility to physically remove the deleted msgs. + + If JAMHARDDELETE is set to Yes, GoldED will zap the reference to + the message in the index when deleting msgs. This way the deleted + msgs will not show up again later. The drawback of this approach + is that it is hard to undelete msgs, and may break other software + which assume 100% to-the-letter conformance to the specs. Note + however, that the hard-delete method is transparent to normal use + of JAM msgbases. Probably the only software that might break are + undelete utilities. + + For the techies and programmers, the hard-delete method is simply + setting both UserCRC and HdrOffset in the index to 0xFFFFFFFF + instead of only the UserCRC. According to the JAMAPI specs, a + value of 0xFFFFFFFF in HdrOffset means that "there is no + corresponding message header". Sounds remarkably like a deleted + msg, right? :-) + + +JAMPATH  (defaults to the HUDSONPATH) + + Defines the path where GoldED can access the NETMAIL/ECHOMAIL.JAM + files, which are used by mail processors to find and scan out mail + written by users. + + GoldED can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED translates the path to + C:\POINT\path\name. + NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED to recompile it's config, you must force + it with the -F or -FF command parameter. + + +KEYBCLEAR  (no) + + Tells GoldED whether or not to clear the keyboard buffer on + startup. This also clears KEYBSTACK or commandline key stuffing. + In older versions of GoldED, it was necessary to enable this + keyword if you had renamed GOLDED.EXE to DBEDIT.EXE. This version + detects the .EXE renaming and automatically enables KEYBCLEAR, + regardless of the configuration setting. + + +KEYBDEFAULTS  (yes) + + GoldED defines a default keyboard configuration setup internally. + The keys can be reconfigured in the GOLDKEYS.CFG file. By default, + the internal keyboard setup is active always, redefinable with the + definitions in GOLDKEYS.CFG. But in some cases it can be + preferrable that the internal keyboard setup is turned off, so + that only the keys in GOLDKEYS.CFG are active. If you want this, + set KEYBDEFAULTS to NO. + + +KEYBEXT  (detect) + + If enabled, GoldED will use extended bios calls to read the + keyboard. With the extended keyboard, you can use keys like + , and other extended keys. If you don't have + an extended keyboard, don't despair - using a few neat tricks, I + have made it possible to use some of the extended keys even with a + non-extended keyboard. + + +KEYBMODE  (poll) + + If this option is set to Poll, GoldED switches its keyboard + handling code from "blocking" to "polling" mode. This enables + GoldED to provide a continuously running statusline clock, + automatic internal editor autosave, timeout exit and screensaver. + If set to Block, the timeout exit and screensaver are disabled, + and the clock and autosave are dependent on key presses. + + In order to minimize waste of CPU resources in keyboard polling + mode, GoldED automatically detects DESQview, Windows and OS/2 and + releases timeslices during the keyboard poll. + + +KEYBSTACK  + + With this keyword, you can "stack" keys in the keyboard buffer. + The KEYBSTACK can be overridden by commandline keystacking, which + uses the same syntax. + + The can be a mixture of the following: + + ^Char Ctrl-key (^Letter). + ~Char Ctrl-key (~Letter). (Use this with 4DOS!). + @Key Alt-key (@Number or @Letter). + Char Literal character. + "String" String, enclosed in double quotes. + 'String' String, enclosed in single quotes. + Number Keyboard scan code (decimal). + ! Clear keyboard buffer. + + Whitespace (space and tab) is ignored, except in quoted strings. + + See the Macros and Keystacking chapter for more info. + + +KLUDGE  + + The definition may optionally be enclosed in quotes. A definition + must be enclosed in quotes if it contains leading or trailing + spaces. The KLUDGE tells GoldED which kludges it should consider + as "known" in addition to the built-in known kludges. + + Here are a bunch of examples, most of which are kludges generated + by the GIGO Internet gateway software: + + KLUDGE " " ; For wrapped kludges + KLUDGE "Content-Type:" + KLUDGE "Date:" + KLUDGE "From:" + KLUDGE "In-Reply-To:" + KLUDGE "Message-Id:" + KLUDGE "Mime-Version:" + KLUDGE "Organization:" + KLUDGE "Newsgroups:" + KLUDGE "Received:" + KLUDGE "Reply-To:" + KLUDGE "Sender:" + KLUDGE "Subject:" + KLUDGE "To:" + KLUDGE "Errors-To:" + KLUDGE "X-FTN-From:" + KLUDGE "ORIGREF:" ; Gated? + KLUDGE "ORIGID:" ; Gated? + KLUDGE "RFC-" ; Seen in NET_DEV + + The kludges defined with KLUDGE are not case-sensitive, but when + GoldED looks for the kludges, it matches to the exact length. This + means that for example "RFC-" will match all kludges beginning + with that string. + + The ASCII 1 kludge char should not be included in the definition + string, but GoldED can handle it if you do. + + +KLUDGECHRS  (yes) + + If set to YES, GoldED uses the "^aCHRS" kludge instead of the + "^aCHARSET" kludge when appropriate. + + +LOADLANGUAGE  + + If defined, this keyword will load a language definition file. + + This feature can be used to load a small set of national language + definitions in national areas, an english set in international + areas, etc. Typically this would be used to load the definitions + of the date/time strings for use in the template and the + Msg/From/To/Subj strings in the header display. + + In the ADVANCED archive, a set of GEDLNG*.CFG files are provided, + which are designed for use with LOADLANGUAGE. Please note that + there is also a @loadlanguage template token. This way you can + choose to load a language file from the template, or by using the + Random System. The template token takes precedence over the + LOADLANGUAGE in the Random System, but if both are defined, both + will be loaded. + + This keyword can be used globally and in Random System groups, but + it is probably not very useful when used globally. + + +LOGFILE  (GOLDED.LOG) + + Defines the name of the GoldED logfile. You should not change the + default. + + +LOGFORMAT  (fd) + + Defines the log format GoldED should use when writing to the + logfile. + + +LOOKUPECHO  (no) + + If enabled, GoldED will use nodelist lookup when entering the TO: + name in msgs in echomail areas. + + GoldED *won't* lookup the name if it exactly matches the current + WHOTO - text. This is a feature, because a lookup of "All" is not + very useful. :-) + + +LOOKUPLOCAL  (no) + + If enabled, GoldED will use nodelist lookup when entering the TO: + name in msgs in local areas. + + GoldED *won't* lookup the name if it exactly matches the current + WHOTO - text. This is a feature, because a lookup of "All" is not + very useful. :-) + + +LOOKUPNET  (yes) + + If enabled, GoldED will use nodelist lookup when entering the TO: + name in msgs in netmail areas. + + +LOOKUPUSERBASE  (no) + + If enabled, GoldED will attempt to find a matching username in the + user database if a to-name with wildcards is entered in echo or + local areas. + + The userbase lookup feature is not new, but a need arose for an + option to turn off the lookup. I decided to let the default be to + disable the lookup. Previously the lookup was always enabled. + + +MAILINGLIST [contribution address] + + Defines one or more mailing lists. When importing e-mail from a + SOUP packet, GoldED will look at the Internet address in the + "Sender" header and if it matches one of the MAILINGLIST's, the + e-mail will be tossed to the defined area. Note that GoldED + supports only participation in, not hosting of mailing lists. The + contribution address is the destination Internet address for mail + you write to the mailing list - the address is typically given to + you when you subscribe to a list. If the contribution address is + not specified, the senderaddress is assumed. + +MAILTOSS  + + This is acutally the same as MAILINGLIST in disguise with the + parameters recorded and it also enables the full set of pattern + matching. The can be written exactly as if in the prompt + for the advanced search feature. + + Any number of MAILTOSS lines can be given for a particular list, + if there is for some reason no single way to identify the list. + + When determining the contribution address, the first MAILTOSS + (or MAILINGLIST) that matches the echoid is chosen. + + MAILTOSS and MAILINGLIST can both be used at the same time and for + the same lists. MAILINGLIST is always the faster, because it looks + only at specific headerlines. MAILTOSS uses much more complex + pattern matching and can even match based on message body content. + + +MAPPATH  + + This keyword is used to map paths, for example if you have + different drive letters on a server machine and a workstation. You + might have your FidoNet mailer and mail processor setup to run + with the server drive letter (C:), but run GoldED from a + workstation where that drive is mapped to a different letter (J:). + If you use AREAFILE's to get the area configuration for GoldED, + you need to use MAPPATH to map the server drive letter to the + workstation equivalent. + + Another case might be that you have a setup with DOS-style paths + and want to run the Linux version with the same GoldED setup. You + can then use MAPPATH to map the DOS drive-based paths to Unix + style paths. + + Examples: + + MAPPATH C: J: + MAPPATH C:\ /mnt/dos/c/ + + NOTE: You don't have to worry about backslash/forwardslash in this + case - they are always mapped automatically to the correct type + for the operating system. + + +MEMBER  + + Defines Random System group members. See the Random System chapter + for details. + + +MENUDROPMSG  (no) + + Defines the default selection in the "Drop This Msg?" menu. + + +MENUMARKED  (default) + + Specifies the position of the selection bar in the Marked/Current + menu. + + Marked Set selector to Marked. + Current Set selector to Current. + Previous Set selector to previously selection. + Default Set selector to Marked if there are marked msgs. + + Note that older versions (before 2.50) used the equivalent of the + "previous" setting. + + +MOUSE  (no) + + The mouse support in GoldED is currently not functional, so this + keyword is ignored. + + +MSGLISTDATE  (written) + + Can be used globally and in groups. This keyword specifies the + default date shown in the right column in the message list. If + "no" is specified, the date column is removed and the space used + to widen the other columns. Personally I prefer to see the + "arrived" date, which is why I implemented this feature. + + The key command LISTtoggledate (Ctrl-D) toggles between them. + + Note that the "arrived" date doubles as the "processed" date for + messages that are written locally and scanned out from your + messagebase. + + Not all messagebase formats supports all three dates. The table + below shows which messagebase supports which dates: + + Written Arrived Received + JAM X X X + *.MSG X X + Squish X X + Ezycom X X + Hudson X + Goldbase X + PCBoard X + + If a date is not supported, "n/a" (for "not available") is shown + instead. + + +MSGLISTFAST  (yes) + + The message lister can operate in two ways, fast or slow. In the + fast mode, only the message headers are loaded for the list + information. Depending on the msgbase format and message type, + some information may not be quite the same when presented in the + lister because information which is gathered from kludges or other + control information in the message text will be missing. Most of + the time this may not be a problem, so if you want speed, chose + the fast mode (default). + + The slow mode loads and fully interprets the content of each + message before the message list is presented. The slowness is most + noticable when entering the lister and when paging up and down. + You may want to use the slow mode for areas with Internet + newsgroups and e-mail, where GoldED uses the "From" kludge to get + the real name of the message writer. + + This keyword can be used globally and in Random System groups. + + +MSGLISTFIRST  (no) + + If enabled, GoldED automatically starts the message lister when + entering an area. + + This keyword can be used globally and in Random System groups. + + +MSGLISTHEADER  (no) + + If enabled, GoldED shows the header of the current message when + you scroll the bar up and down. This is how it worked in previous + versions. If disabled, GoldED does not show the header and instead + uses the screen space to show more messages. By eliminating the + header display, it is also much faster at scrolling the list. + + This keyword can be used globally and in Random System groups. + + +MSGLISTPAGEBAR  (yes) + + Enables or disables a pagebar (scrollbar) in the message list. + + +MSGLISTVIEWSUBJ  (yes) + + If enabled, GoldED will display the full subject in the bottom + border of the list window. Note that this feature slows down + scrolling a bit. + + +MSGLISTWIDESUBJ  (no) + + If enabled, the Subject column is made wider by removing the To + column. This is especially useful in gated Internet newsgroups, + where the To name is always "All". + + You can toggle between wide and short subject with Ctrl-B + (keycommand LISTtogglewidesubj). + + This keyword can be used globally and in Random System groups. + + +NAMESFILE  (NAMES.FD) + + GoldED supports the "address macro" file supported by FrontDoor + and Maximus. If no path is specified, the file is first searched + for in the path from the "FD" environment variable and then the + GOLDPATH, if the FD variable failed. + + The address macros are added *after* those defined with the + ADDRESSMACRO keyword (if any) (see this for details on the + format). + + +NICKNAME  + + Defines the nick name (pseudo) for the current USERNAME. Can be + used globally and in random system groups. + + +NODELIST [zone/addr] + + Here you define the nodelists that are used by GoldED and the + companion nodelist compiler GoldNODE. The nodelists must generally + be in the standard "St.Louis" nodelist format, but they can also + contain FrontDoor/Version7 style Boss/Point extensions. The + default zone is defined by the first ADDRESS or AKA, but can be + overridden by adding the zone number or a full address after the + filename. GoldED currently needs it's own special index files to + use the nodelists. These index files are created by GoldNODE. + + Nodelist file. If the extension is .999 or a + wildcard (".*"), the newest file with a numeric + extension is used. + [zone/addr] Default zone or address for the nodelist (if no + zone info is present in the list itself). + + See also the USERLIST keyword, and the Nodelist Browsing chapter. + + NOTE: If you have nodelists with duplicate some of each others + nodes, the nodelist with the newest or most correct entries should + be placed LAST, and you should use the -D (remove duplicates) + option with GoldNODE. + + +NODELISTWARN  (yes) + + If set to YES, GoldED will warn you during startup if one or more + nodelists are missing. Use NO to disable the warning if it bothers + you or you delete/pack your nodelists when the nodelists are + compiled. + + NOTE: GoldED can work fine with lookups etc. without nodelists as + long as it can access its own indexes (GOLDNODE.GX?). Only the + extra details will be missing. + + +NODEPATH  + + This is where GoldED and GoldNODE finds the nodelist files and + indexes. + + +NODEPATHFD  + + Path where GoldED can find the FrontDoor nodelist index files. + + +NODEPATHIM  + + Path to the InterMail nodelist index files. This is actually just + an alias name of the NODEPATHFD keyword, since InterMail and + FrontDoor uses the same nodelist index files. + + +NODEPATHV7  + + Path where GoldED can find the Version 7 nodelist index files. + + NOTE: For the Version 7 nodelist index support, GoldED *requires* + that the files SYSOP.NDX, NODEX.NDX and NODEX.DAT are present. + None of these files may be missing and no other filenames are + supported. Multiple sets of index files are not supported. + +NODEV7FLAGS  + + The Version 7 nodelist index does not by default define any + nodelist flags except the CM flag. Unfortunately the V7 index does + not point to the actual nodelist, it only has some bits which are + marked "reserved" in the specifications. The NODEV7FLAGS keyword + allows you to define the meaning of each of these bits. + + The field can be a number or a bit number. Allowed numbers + are: 32, 64, 128, 256, 512, 1024, 2048, 8192 and 16384. Allowed + bit numbers are: b5, b6, b7, b8, b9, b10, b11, b13 and b14. + + Example: + + NODEV7FLAGS MO b5 + NODEV7FLAGS LO b6 + NODEV7FLAGS MN b7 + NODEV7FLAGS NC b8 + NODEV7FLAGS ZEC b9 + NODEV7FLAGS REC b10 + NODEV7FLAGS NEC b11 + NODEV7FLAGS XA b13 + NODEV7FLAGS XX b14 + + See also the NODEV7MODEM keyword for other nodelist flags. + + The nodelist flag bits in the index files are put in by your + Version 7 nodelist compiler. You must make sure that the nodelist + flag definitions in your nodelist compiler setup match those in + your GoldED setup. + + +NODEV7MODEM  + + The Version 7 nodelist index does not by default define any + nodelist modem type flags. Unfortunately the V7 index does not + point to the actual nodelist, it only has some bits which are + marked "reserved" in the specifications. The NODEV7MODEM keyword + allows you to define the meaning of each of these bits. + + The field can be a number or a bit number. Allowed numbers + are: 1, 2, 4, 8, 16, 32, 64 and 128. Allowed bit numbers are: b0, + b1, b2, b3, b4, b5, b6 and b7. + + Example: + + NODEV7MODEM VFC b0 + NODEV7MODEM HST b1 + NODEV7MODEM V34T b2 + NODEV7MODEM V32B b3 + NODEV7MODEM V34 b4 + NODEV7MODEM V42B b5 + NODEV7MODEM ZYX b6 + NODEV7MODEM ISDN b7 + + See also the NODEV7FLAGS keyword for other nodelist flags. + + The modem type bits in the index files are put in by your Version + 7 nodelist compiler. You must make sure that the modem type + definitions in your nodelist compiler setup match those in your + GoldED setup. + + +ORGANIZATION  + + Specifies the content of the RFC Organization header for Internet + messages. + + +ORIGIN <"string"> + + You can define many different origins for use in GoldED. You can + select one of the defined origins from the Origin selection menu + (the READchangeorigin keyword), which is also available from the + EDITMENU and the EDITSAVEMENU. + + Leading and/or trailing spaces can be added by enclosing the + origin string in quotes. + + This keyword can be used globally and in a Random System group. + + NOTE: Origins defined in the Random System will always override + the global origins defined with this keyword, except when they are + selected from the EDITSAVEMENU. + + +OUTBOUNDPATH  + + Defines a Binkley-style outbound path. Currently only used for + WaZOO .REQ file requests (see FRQWAZOO). This should be the name + of your primary outbound without extension. + + +OUTPUTFILE  + + This is the default name of the file written using the + READwritemsg command. + + This keyword can be used globally and in a Random System group. + + +OVERLAY  (ems) + + This keyword controls where GoldED places the overlay swap blocks. + GoldED (the standard DOS version) uses the Borland VROOMM dynamic + overlays to decrease the resident executable code. + + See the DOSSWAP keyword for a warning note! + + Ignored by the 386, W32 and OS/2 versions. + + +PCBOARDPATH  + + Defines the default path where GoldED should look for the PCBoard + setup files if it can't find the PCBOARD environment variable. + + +PCBOARDUSERNO  (0) + + Specifies the lastread set used in the PCBoard message base. + + +PERSONALMAIL  + + Specifies options regarding the personal mail scan feature. None + of them are enabled by default. + + If the "startup" option is used, GoldED scans for personal mail + while doing the startup mail scan. + + If the "allnames" option is used, GoldED scans for mail to all the + USERNAME's instead of only the first. The default is not to scan + for personal mail at startup and to scan only for the first name. + This is faster. + + Example: + + PERSONALMAIL Startup, AllNames + + The example makes GoldED scan for personal mail to all your + USERNAME's at startup. + + +PLAY  + + See the EVENT keyword for a definition of the PLAY parameters. + + This keyword can be used globally and in a Random System group. + + +PRINTDEVICE  (PRN) + + Defines the name of the device used for printing. PRN is the + default, but LPTx can also be used. Printers on COMx ports may + also work, but this has not been tested. + + Devices are opened in Write-Only text mode. The function has been + successfully tested to work with two popular peer-to-peer network + packages. + + You should NOT use a filename as devicename. Use the filename + option in the Write menu instead. + + +PRINTFORMFEED  (yes) + + Used when printing messages. If enabled, it prints a Form Feed + (12d) character after each message. + + +PRINTINIT  + + This keyword defines the command string sent to your printer to + initialize it before the actual printing. + + The can contain items like these: + + $Hex A hexadecimal string. + #Decimal A decimal (integer) number. + "String" Text string, enclosed in double quotes. + 'String' Text string, enclosed in single quotes. + Other chars Ignored. + + +PRINTLENGTH  (60) + + Defines the number of lines per page for printing. A formfeed is + printed when every time PRINTLENGTH lines have been printed. + + +PRINTMARGIN  (80) + + The right margin to use in printed messages. + + +PRINTRESET  + + This keyword defines the command string sent to your printer to + reset it after printing. + + See the PRINTINIT keyword. + + +QUOTEBLANK  (no) + + If enabled, GoldED will put the QUOTESTRING on blank lines in the + quote. Otherwise blank lines are left blank in quotes. + + +QUOTEBUFFILE  + + If used, it sets the default filename for the quotebuffer. If no + path is specified, the GOLDPATH is used. + + This keyword can be used globally and in Random System groups. + + NOTE: If this keyword is used in globally (in GOLDED.CFG), it + effectively disables the automatically named quotebuffers, as + described in the chapter about the QUOTEBUFMODE keyword. + + +QUOTEBUFMODE  (ask) + + Specifies what GoldED should do, if the quotebuffer file exists + already. + + Ask A menu asks you to select append/overwrite/skip. + Append Always append, no asking. + Overwrite Always overwrite, no asking. + + The "always overwrite" mode is not very useful I guess, but it's + there if you need it. + + The quotebuffer feature automatically creates special filenames + for the buffer file, using these guidelines: + + FORMAT FILENAME LOCATION + Fido GOLDED.QBF In the directory with the *.MSG's. + Hudson GOLDHxxx.QBF In the HUDSONPATH. + Squish filename.QBF Where the Squish area is. + Ezycom GLDxxxxx.QBF In the EZYCOMMSGPATH. + JAM filename.QBF Where the JAM area is. + Goldbase GOLDGxxx.QBF In the GOLDBASEPATH. + PCBoard filename.QBF Where the PCBoard area is. + + Note that they all have extension .QBF so that you can easily find + them. + + +QUOTECHARS ["]["] + + Defines up to 10 chars to recognize in addition to '>' as quote + string chars. This is most useful in gated Internet newsgroups, + where chars such as '|', ':' and ';' are sometimes used instead of + the '>'. + + This keyword can be used globally and in Random System groups. + + Example: + + Group Internet: + Member alt.*, comp.*, net.email + Quotechars "|:;" + Username odinn@winboss.dk + EndGroup + + The example is similar to the one I use myself (net.email is a + local netmail area where I import my gated e-mail from + winboss.dk). The username is my actual Internet address. + + Note that using additional quotechars such as '|' and ':' may + cause odd results when quoting in the cases when they are actually + NOT used in a message as quotechars. Consider for example quoting + a smiley :-) + + +QUOTECTRL  + + Specifies if you want quote tearline and/or origin in your + messages. + + This keyword can be used in random system groups. + + +QUOTEMARGIN  (70) + + The margin to which quotes are wrapped. A negative value means + that the negative value is added to the DISPMARGIN (not + recommended). + + +QUOTESPACING  (no) + + If enabled, GoldED will automatically add blank lines before and + after a block of quoted text, if none are present already. This + improves the readability of some messages. + + +QUOTESTRING  (" FL> ") + + With this keyword you define how you want the quotestring to look + in your quoted replies. + + The can contain these characters: + + F Replaced with the first letter of the first name. + M Replaced with the letters of the middle names. + L Replaced with the first letter of the last name. + > Required quote-char. + Spaces Cosmetics. + + Other characters are allowed but *not* recommended. + + This keyword can be used globally and in Random System Groups. + + +QUOTEWRAPHARD  (yes) + + This keyword controls behaviour of quoted text (wrap or reflow). + + +QWKBADMSGS  + + Specifies the area where messages in unknown conferences are put. + If you get messages tossed here by accident, you must move them + manually to the correct area. If the badmsgs area is not defined, + the messages will silently disappear. Messages tossed to the + badmsgs area will have the control line "AREA:_" at + the top of the message. + + +QWKCONFMAP ["]["]  + + Defines the mapping between the BBSID and conference names in the + QWK packets and the echoid name of the conference as required by + GoldED. You MUST define a mapping for every conference that you + subscribe to. If you don't, the messages will be tossed to the + area defined by QWKBADMSGS or disappear. The is the name + listed on line 5 in CONTROL.DAT after the comma. The is + the conference names listed on line 13 and on alternate lines + onwards in CONTROL.DAT. If a conference name contains embedded + spaces, the must be enclosed in double quotes, like + this: "Main Board". The area must be already defined + either in an AREAFILE or using the AREADEF or AREA keywords. + + +QWKEXPORTPATH  + + Path where outgoing QWK reply files (BBSID.MSG) can be placed. + + +QWKIMPORTPATH  + + Path where incoming QWK packet files (CONTROL.DAT and + MESSAGES.DAT) can be found. + + +QWKOPTIONS  + + The is the BBSID (same as the name of the QWK packet) for + which the options will be active. The can be any or a + combination of the following, separated by commas or spaces: + + KLUDGES/NOKLUDGES: Defaults to NOKLUDGES. Specifies whether or not + to include the FidoNet-style kludges at the top of messages when + exporting to QWK. NOTE: Unless you enable this option, GoldED will + *not* include kludges in your QWK packets. You should check if the + BBS supports kludges in QWK packets. If it does, please enable + this option. + + MIXCASE/NOMIXCASE: Defaults to NOMIXCASE. Specifies whether or not + the BBS allows mixed upper/lower case in the QWK message headers. + The default is to uppercase the TO and FROM header fields when + exporting to QWK packets. + + RECEIPT/NORECEIPT: Defaults to NORECEIPT. Specifies whether or not + the BBS supports return receipt requests (RRQ). If the RECEIPT + option is enabled, GoldED will insert "RRR" at the front of the + subject field if the RRQ attribute is set on your messages, when + exporting to QWK packets. + + +QWKREPLYLINKER  + + Commandline for a replylinker program to call after QWK import. + + +QWKTOSSLOG  + + Name of a file where GoldED puts the echoids of each area where + articles have been imported. The tosslog file is intended to be + used with a replylinker. If no path is given, it defaults to the + GOLDPATH. + + +RA2USERSBBS  (detect) + + GoldED supports the two different formats of the Hudson USERS.BBS + file. With this keyword you can tell GoldED which format to use. + + If set to YES, the RA2 format is used. Otherwise if the it is set + to NO, the Hudson format is used. + + If this keyword is NOT used, GoldED tries to detect the format by + looking at the size of the USERS.BBS file and comparing this to + the record sizes of the RA2 and Hudson formats. + + If the size matches one and not the other, the format is detected + to be of the matching type. + + If the size matches both (which is quite normal), GoldED looks for + the RA environment variable and if found, in the RA config files + for the RA version. + + If the size does not match either of them (indicating a possibly + damaged userfile), GoldED exits with an error message and writes + in the log with details of the problem and an advise to run a + userbase packing utility. + + If used, this keyword should be placed in the configuration file + _after_ any AREAFILE keyword. + + +RCVDISABLESCFM  (yes) + + If this keyword defined to "no" then GoldEd will recognize RRq + (receipt request) and/or CFM (confirmation) flag on messages with + RCV (received) flag set. After that RRq and CFM flags will be + resetted. It is useful if your netmail tracker sets RCV flag + before you actually read messages. + + +REGISTERKEY +REGISTERNAME + + These keywords do nothing and won't do anything in the future. + They were used when GoldED was a Shareware product. + + +REM + + This keyword ignores everything behind it. This is useful to + comment a single line out. + + +REPLYLINK  + + Defaults to "direct" for JAM and "chain" for everything else. + + If set to "direct", GoldED will link your reply directly to the + original message. If set to "chain", it will link to the last + message in the reply chain. The default ("chain") is how GoldED + has done it in all previous versions. + + The advantage of the "direct" linking method is that you can + easily find the the original message the reply was for. Unless of + course you have later re-linked using a chain-linking replylinker + utility. I can recommend the utility SQLINK by Serge Terekhov. + SQLINK links Squish areas using the MSGID/REPLY kludges and makes + direct links instead of chain-linking on the subject line like + most other replylinkers do. There are probably also similar + replylinkers for other msgbase formats, I just don't know them. + + +REPLYLINKLIST  (fast) + + When there is more than one reply to a msg in a JAM or Squish + area, GoldED pops up a list of the replies. This keyword affects + the contents of the list. + + In the "fast" mode, the list data is based solely on what can be + found by reading the message header, which is quite fast. + Unfortunately some software does not (or cannot) fill the header + with the correct origination address. In that case, set this + keyword to "full", which makes GoldED read and scan each message + for control data to get the origination address. That can be very + slow. + + +ROBOTNAME  + + A "robot" is a program on the Boss or Uplink system which responds + automatically to netmail messages. Usually the robot links or + unlinks echomail areas or distributed files. + + The following ROBOTNAME's are defined by default: + + AreaFix, AreaMgr, FileFix, AreaLink, AllFix, Raid, GEcho. + + If you write a netmail message where the TO: name is one of the + robot names, GoldED will ignore any template definition, and give + you a blank msg (possibly with a tearline) to edit. + + +SCREENBLANKER [BLACK] (180) + + If non-zero, GoldED will blank the screen after the defined number + of seconds, and put a small moving window up instead. Hitting any + key (including shiftkeys) will return the screen to normal. If + zero, no blanking is done. + + If the additional parameter "BLACK" is given, GoldED will switch + the screen completely black instead of showing its own animated + screenblanker. This is useful if you have a monitor with + powersaving-features. + + Example: + + SCREENBLANKER 300 BLACK + + NOTE: This feature only works if KEYBMODE is set to "poll". + + +SCREENMAXCOL  (0) + + On some systems, GoldED may no detect the correct display size. + With this keyword you can force a specific size. If zero, + autodetect is used. + + +SCREENMAXROW  (0) + + On some systems, GoldED may not detect the correct display size. + With this keyword you can force a specific size. If zero, + autodetect is used. + + +SCREENPALETTE OR (red green blue) + + You can change the color palette used in GoldED. The palette has + 16 color registers, corresponding to the 16 colors from black (0) + to intense white (15). By changing the values in the palette + registers, it is possible to make any of the 16 colors a + completely different color. You can even make the background + colors intense, without using the intense color feature. There are + 64 different colors to chose from. + + To configure the palette colors in GoldED, the SCREENPALETTE + keyword is used. There are two different syntaxes: + + SCREENPALETTE + SCREENPALETTE (red green blue) + + So you can either compose the color value using separate red, + green, blue components, or directly use a precalculated value. The + red/green/blue values can only be in the range 0-3. + + These are the original palette values: + + SCREENPALETTE 0 (0 0 0) + SCREENPALETTE 1 (0 0 2) + SCREENPALETTE 2 (0 2 0) + SCREENPALETTE 3 (0 2 2) + SCREENPALETTE 4 (2 0 0) + SCREENPALETTE 5 (2 0 2) + SCREENPALETTE 6 (2 2 0) + SCREENPALETTE 7 (2 2 2) + SCREENPALETTE 8 (1 1 1) + SCREENPALETTE 9 (1 1 3) + SCREENPALETTE 10 (1 3 1) + SCREENPALETTE 11 (1 3 3) + SCREENPALETTE 12 (3 1 1) + SCREENPALETTE 13 (3 1 3) + SCREENPALETTE 14 (3 3 0) + SCREENPALETTE 15 (3 3 3) + + Copy these lines into your GOLDED.CFG and start experimenting! :-) + + If you have written a program to edit the palette and write a + GoldED palette setup file, please don't keep it a secret! :-) + + +SCREENSHADOWS  (yes) + + If enabled, all relevant windows and menus in GoldED will have + shadows. + + +SCREENSIZE  (Auto) + + Use this to force GoldED to use either 25 lines, 43/50 lines on + EGA/VGA, or even special videomodes supported by your SuperVGA + adapter (modes like 132x44, 100x40 or 80x60). + + The can be one of the following: + + Auto Use detected size. + 25 Switch to 25 lines. + 28 Switch to 28 lines. + 4350 Switch to 43/50 lines. + Mode Switch to videomode NN (a hexadecimal value). + + Please check your video adapter manual carefully before trying out + the Mode option. SELECTING A WRONG MODE CAN DAMAGE YOUR MONITOR!!! + + The Mode option is ignored in the W32 and OS/2 version. + + +SCREENUSEBIOS  (no) + + If enabled, GoldED will use standard BIOS calls for screen + updates. This is VERY slow, and should only be used if really + needed. Normally GoldED uses direct screen writes. + + This feature is only interpreted in the DOS version. + + +SEARCHFOR ["]["] + + Defines a set of search strings, separated by the '|' character. + The search set defined here is the default when using the Alt-F/Z + search functions or the marking system. + + The '|' character works like an OR operator. That is, the search + is successful if one OR more of the strings are matched. The '&' + character is used as the logical AND operator. + + Please refer to appropriate section in user's guide for more + information. + + Older versions used the ';' semicolon character as a separator, + but that conflicts with the config reader which treats the + semicolon in a special way. The semicolon is still accepted as + separator char like '|', but if semicolons are used, you MUST + enclose the search strings with quotes or the config reader will + treat the first semicolon as the start of a comment. + + Examples: + + SEARCHFOR string1 + SEARCHFOR string1|string2|stringx + SEARCHFOR "string1;string2;stringx" + SEARCHFOR "string 1"|string2&stringx + + This keyword can be used globally and in Random System groups. + + +SEMAPHORE  + + This keyword defines "semaphore" files, for use with other mailer + and/or mail processing software. + + The can be one of the following: + + NETSCAN Empty netmail scan file (for D'Bridge/FD). + ECHOSCAN Empty echomail scan file (for D'Bridge). + EXPORTLIST Echoid-list of your new messages. + IMPORTLIST Echoid-list of new imported messages. + + The semaphore files are placed in the AREAPATH, if no path is + specified. + + See the example .CFG files for typical semaphore filenames. + + NOTE: You should not set SEMAPHORE EXPORTLIST to + %JAMPATH%\ECHOMAIL.JAM. This is incorrect and probably may cause + your mail processor to malfunction. Use the JAMPATH keyword + instead. + + GoldED can handle enviroment variables correctly in paths + specified in connection with this keyword. For example, if a path + is defined as %MAIL%\path\name, and SET MAIL=C:\POINT is in + AUTOEXEC.BAT (or whatever), then GoldED translates the path to + C:\POINT\path\name. + + NOTE: The translation is done at config compile time, so if you + change the environment variable and haven't changed anything else + that would cause GoldED to recompile it's config, you must force + it with the -F or -FF command parameter. + + In addition, GoldED itself can watch for some semaphore files and + execute the appropiate function if it is in the arealist screen. + This can be useful if you have a multitasking system and you want + to "tell" GoldED that there is new mail in some areas and GoldED + should update its display correctly. + + In detail, there are + + EXITNOW Quit immediately. + SCANALL Scan all areas + SCANNETMAIL Scan all netmail areas + SCANTHIS Scan the areas listed in the file + PMSCANALL PM-scan all areas + PMSCANNETMAIL PM-scan all netmail areas + PMSCANTHIS PM-scan the areas listed in the file + QWKIMPORT Import QWK packets + QWKEXPORT Export to QWK + SOUPIMPORT Import SOUP packets + SOUPEXPORT Export to SOUP + IDLETIME Number of seconds between checks + + If SEMAPHORE IDLETIME is defined and non-zero, then GoldED will + check this list of semaphore files when the user has not pressed a + key in the specified number of seconds. The semaphores are only + checked when the arealist screen is active. If a semaphore file is + found, the file is deleted and then the action is performed. If no + path is given for the files, the GOLDPATH is assumed. + + Example: + + SEMAPHORE SCANALL SCANALL.NOW + SEMAPHORE IDLETIME 30 + + This causes GoldED to check every 30 seconds for the SCANALL.NOW + file in the GOLDPATH, and scan all areas if it's found. + + +SERIALNO + + Everything mentioned above about REGISTERKEY and REGISTERNAME + applied to this keyword. + + +SHAREMODE  (yes) + + If enabled, GoldED opens all files in a SHARE.EXE compatible mode. + + The default share-mode is "Share Deny None", but another may be + specified directly if you give the mode number as the keyword + parameter (decimal). + + It is normally not necessary to change the default. + + +SOUNDPATH  (defaults to the GOLDPATH) + + Tells GoldED where to find the sound files for the PLAY and EVENT + keywords. + + +SOUPBADMSGS  + + Specifies the area where "bad messages" from SOUP packets can be + tossed. It should be an echomail or newsgroup area. + + +SOUPEMAIL  + + Specifies the area where Internet e-mails can be tossed. It must + be a netmail or e-mail area. + + +SOUPEXPORTMARGIN  (76) + + This is the margin that GoldED will hard-wrap to when exporting to + SOUP packets. If you're getting complaints that your lines are too + long, you may want to set this to 70 or 60. + + NOTE: You should NOT enable EDITHARDTERM in email and newsgroups + that are exported to SOUP. If you do, your messages will probably + be exported with short line "droppings" after the wrapping margin. + + +SOUPEXPORTPATH  + + Path where outgoing SOUP reply packet files (REPLIES and + GOLD*.MSG) can be placed. + + +SOUPIMPORTPATH  + + Path where the incoming SOUP packet files (AREAS and *.MSG) can be + found. + + +SOUPNEWSRCFILE  + + Name with full path of the NEWSRC file which lists the newsgroups + you are connected to. GoldED uses the list to mark the matching + areas as newsgroups. These will then be scanned for outgoing mail + when starting a SOUP export. + + +SOUPREPLYLINKER  + + Commandline for a replylinker program to call after SOUP import. + + +SOUPREPLYTO  + + Internet-Address other users should use when they respond to your + mails (Reply-To Headerline). + + +SOUPTOSSLOG  + + Name of a file where GoldED puts the echoids (newsgroup names) of + each area where articles have been imported. The tosslog file is + intended to be used with a replylinker. If no path is given, it + defaults to the GOLDPATH. + + +SQUISHDIRECT  (no) + + If enabled, then in Squish areas, if the DIR (direct) attribute is + set on a message, GoldED will automatically set both the CRA + (crash) and HLD (hold) attributes when saving the message. + + According to the Squish Developers Kit, this is the way to tell + SquishMail that a message should be routed direct, because + SquishMail does not recognize the FLAGS kludge where the DIR + attribute is normally found. This keyword should probably only be + used with SquishMail (the mail processor) and then only when used + with Binkley or other so-called "static" mailers. DON'T use it + with FrontDoor! + + +SQUISHSCAN  (quick) + + Specfies whether to use a quick scanning method which only looks + in the .SQI files. This will normally work fine, but may fail + slightly in obscure cases, especially when used with Squish 1.0x + or programs using the old version of the MSGAPI. If you suspect + problems, try to set this keyword to "api", which tells GoldED to + look in the .SQD file for an exact count of active msgs in the + .SQI file. + + NOTE: GoldED does NOT use the original MSGAPI by Scott Dudley. + Since version 2.50, a completely rewritten implementation is used. + + +SQUISHUSERNO  (0) + + This sets the lastread index number for the Squish *.SQL lastread + files. Lowest number is 0 (zero), highest is (in theory) 65534. + + If used, this disables the use of USER.BBS to find the index + number, and will in effect also stop GoldED from creating USER.BBS + or any new entries in it (useful in a single-user point system). + If a Squish msgbase is shared between several users, and you don't + want to have a USER.BBS (recommended in such a case), each user + must have a unique SQUISHUSERNO in their GOLDED/GOLDAREA.CFG. + + +SQUISHUSERPATH [file] + + This keyword defines the path where GoldED can find and use/create + your USER.BBS file, which is used in connection with the Squish + area lastreads. You can also specify the exact filename if not + USER.BBS. + + If this path or filename is not defined, GoldED will instead take + the one specified with AREAFILE Squish or AREAFILE Maximus + (whichever comes first), or failing that, use the MAXIMUS or + SQUISH environment variables. If even that fails, the AREAPATH or + GOLDPATH is used. If AREAFILE Maximus is used, GoldED gets the + filename from MAX.PRM. + + +STATUSLINECLOCK  (yes) + + If enabled, GoldED will display a clock in HH:MM:SS format in the + right side of the statusline. + + You can redefine the clock format with the language keyword + ST_STATUSLINETIMEFMT in GOLDLANG.CFG. See the Language Definition + chapter to details about the date/time codes you can use. + + NOTE: The clock will only run continuously if KEYBMODE is set to + "poll". + + +STATUSLINEHELP  (no) + + If set to YES, GoldED will replace the "logo" in the left side of + the statusline with a text saying "F1 Help". This is for use in + "point package" setups where the user may be a complete novice, + maybe even to computers, and who needs to be guided to the help + screens. The "F1 Help" text is configurable with the + ST_STATUSLINEHELP language keyword (put it in GOLDLANG.CFG). + + If set to NO, GoldED will display it's logo (name and version) in + the left side of the statusline. + + If set to NOLOGO, GoldED will not display anything in the left + side. The middle part is extended to fill the space on the left + side. + + +STYLECODES  (hide) + + If enabled (yes or hide), GoldED will highlight text surrounded by + one of the following characters in a different color: '*' for bold + text, '/' for italic text, '_' for underlined text and '#' for + reversed text. These are commonly used "stylecodes" which add + emphasis to the text, without making it harder to read. Examples: + *This* will be shown in bold color, /this/ in italic color and + _this_ in underlined color. It is also possible to combine styles, + such as */this/*, in bolditalic color. + + The differ in yes and hide is that hide strips surrounding + stylecodes. + + To define the highlight colors, use COLOR STYLECODE. See the color + chapter for details. + + +STYLECODEPUNCT <"charlist"> (" !\"$%&()+,.:;<=>@[\]^`{|}~") +STYLECODESTOPS <"charlist"> ("") + + The STYLECODEPUNCT keyword specifies all the characters that + punctuates words. The stylecode line parser scans forward until it + meets one of these characters and then looks back to see if it + found a word with stylecodes around it. + + The STYLECODESTOPS keyword specifies characters which, if found + within the word to be highlighted, causes the highlight to be + cancelled. + + These keywords were added to allow users to experiment with the + characters for punctuation and stop for stylecode sequences. This + is mostly to illustrate the point that it is almost impossible to + make stylecodes work in every case you want without getting a lot + of false highlights too. Please keep in mind that stylecodes are, + and always will be, a primitive and very error-prone method for + adding highlights to message text. The defaults are: + + STYLECODEPUNCT " !\"$%&()+,.:;<=>@[\]^`{|}~" + STYLECODESTOPS "" + + Note that the double-quote (") must have the backslash (\) in + front of it - the sequence (\") is translated to a single ("). + + +SWAPPATH  (defaults to TEMPPATH) + + Defines where the swap file will be placed in case of disk + swapping in DOS shells. It is recommended that this points to a + RAM disk, if available. GoldED needs 3-500k free disk space for + the swapfile, depending on the overlay buffer size specified with + the -O commandline switch. + + This keyword is only interpreted by the DOS platform version. + + +TAGLINE  + + Defines one or more taglines. A tagline collection filename can be + specified if prepended with an '@' character, like this: TAGLINE + @TAGLINE.LST. If a tagline collection file is used, GoldED will + create an index file for it the first time it is used or any time + the file is edited. The index file has the same name, but + extension ".SDX". The index file is an array of 32-bit long + integers, containing the offset of each line in the tagline + collection file. + + This keyword can be used globally and in a Random System group. + + Taglines defined in the Random System *always* overrides the + default global taglines defined with this keyword. + + +TAGLINECHAR  ('.') + + Defines the character GoldED uses when putting a tagline in your + message. The default is '.'. You should not change this default. + GoldED itself only recognizes taglines with '.' or '_' + (underscore). + + +TAGLINESUPPORT  (yes) + + Allows you to turn off the internal tagline support, in case it + turns out to be too buggy or if you want to use one of the many + good external tagline utilties out there instead. + + +TASKTITLE  (@longpid) + + Sets window title in Win32 and OS/2 versions, ignored in other. + + +TEARLINE  (@longpid @version) + + Here you can define your default tearline. The tearline can be up + to 76 chars long (excluding the leading "--- "), but beware that + policies (such as FidoNet ECHOPOL1) may set a significantly lower + limit (around 30). + + This keyword can be used globally and in a Random System group. + + Tearlines defined in the Random System *always* overrides the + default tearline defined with this keyword. + + If your tearline does not contain at least the string "GoldED" or + "GED", GoldED will automatically insert it's PID kludge. See also + description of USEPID keyword. + + +TEMPLATE ["desc"] [match-address] (GOLDED.TPL) + + You can define many different template files. The templates can be + switched using the READchangetemplate (Ctrl-T) popup menu or the + EDITMENU. + + The optional "desc" can be used to give the templates more + meaningful names like "International template" instead of + non-obvious names like "GOLDED.TPL". If a description is used, it + must appear before the match-address. It must always be enclosed + in quotes, even if it is only one word. + + The match-address is an address mask (wildcards allowed) which can + be used to tell GoldED to select that template if the destination + address on a message you write matches the match-address. The + matching will only take place if the TEMPLATEMATCH keyword has + been enabled. + + This keyword can be used globally and in a Random System group. In + Random System groups, only the parameter can be used. + + Templates defined in Random System groups always override the + globally defined templates, except when selected from the EDITMENU + or when automatic template matching is in effect. + + To override the automatic template matching, start by selecting a + template manually using the READchangetemplate (Ctrl-T) command or + the EDITMENU. + + Currently only one match-address per template can be specified, + but you can specify several TEMPLATE keywords for the same file. + + Example: + + // Use DANSK.TPL for messages to Danish nodes/points. + TEMPLATE DANSK.TPL "Danish" 2:23/* + TEMPLATE DANSK.TPL "Danish" 2:234/* + TEMPLATE DANSK.TPL "Danish" 2:235/* + TEMPLATE DANSK.TPL "Danish" 2:236/* + TEMPLATE DANSK.TPL "Danish" 2:237/* + TEMPLATE DANSK.TPL "Danish" 2:238/* + + // Use INTERNET.TPL for messages to the WinBoss gateway + TEMPLATE INTERNET.TPL "Internet" 2:230/9316 + + // Use ENGLISH.TPL for messages to everywhere else + TEMPLATE ENGLISH.TPL "English" * + + +TEMPLATEMATCH  (no) + + If enabled, GoldED will select a template which matches the + destination address on messages that you write. This keyword can + be used globally or in random system groups. + + +TEMPLATEPATH  (defaults to the GOLDPATH) + + Defines the default path for msg templates. Use this if you want + to place templates in a path separate from the GOLDPATH. + + +TEMPPATH  + + Defines the directory where temporary files are placed by GoldED + and GoldNODE. + + This path should *NOT* point to a RAM disk or other volatile + media! + + GoldNODE uses this path to store a temporary file which can become + as large as the largest index file (GOLDNODE.GXN), so again, don't + point it to a small RAM disk. If GoldNODE cannot find a TEMPPATH, + it will use the NODEPATH instead. + + +TIMEOUT  (0) + + Similar to the screen blanking (SCREENBLANKER) feature, GoldED can + auto-exit after a specified period of time. Useful if you are in a + hurry (or didn't get enough sleep last night ;-), and run GoldED + from your mailer shell. The timeout value can be overridden with + the -T commandline option. + + NOTE: This feature only works if KEYBMODE is set to "poll". + + +TIMEOUTSAVEMSG  (yes) + + If set to YES, GoldED behaves as usual: It saves the (perhaps + partially written) msg text in the internal editor to the msgbase + and exits. If set to NO, GoldED will save the msg text in + GOLDED.MSG just as if EDITAUTOSAVE function was in use and the + power went out. Next time you started GoldED and entered a msg, it + would detect the "lost" msg and ask you if it should be continued. + + ++TITLESTATUS  (yes) + + If enabled then brief status will be added to title. (Win32 and + OS/2 versions only) + + +TWITMODE  (Blank) + + In GoldED you can define several "Twit" names, addresses or + subjects. With this keyword you can specify the action taken when + a Twit message is encountered. + + The can be one of the following: + + Show Show twit messages. + Blank Blank twit messages. + Skip Skip twit messages, unless to your USERNAME's. + Ignore Skip twit messages, always. + Kill Deletes twit messages, *without* confirmation! + + This keyword can be used globally and in a Random System group. + + +TWITNAME  + + With this keyword, you can specify "Twit" names and/or addresses. + When a Twit name/address is detected, the TWITMODE setting will + determine the action taken. + + +TWITSUBJ <"string"> + + With this keyword, you can specify "Twit" subjects. When a Twit + subject is detected, the TWITMODE setting will determine the + action taken. The subject string is searched in the entire subject + text, so you can specify a partial twit subject. Twit subjects are + limited to maximum 35 characters. + + +TWITTO  (no) + + If enabled, GoldED will check both from- and to-names when + checking for twitnames. By default only the from-names are + checked. + + This is a global keyword and won't work as intended if used in a + random system group. + + +USECHARSET  (yes) + + If set to no then GoldEd will not generate @CHRS and @CHARSET + kludges. + + +USEFLAGS  (yes) + + If enabled, GoldED inserts the FLAGS kludge for certain extended + attributes, as defined in FSC-0053 by Joaquim H. Homrighausen, and + supported by FrontDoor, D'Bridge, IMail and other modern software. + GoldED uses FLAGS to emulate the Hold and Freq attributes which + are not defined in the Hudson message format. + + +USEFWD  (yes) + + If enabled, GoldED inserts the FSC-0092 kludges introduced by the + author of FleetStreet, Michael Hohner. These are + + FWDFROM The original From-Name + FWDORIG The original From-Aka + FWDTO The original TO-Field + FWDDEST The original TO-aka (only in netmails) + FWDSUBJ The original subject + FWDAREA The original areatag + FWDMSGID The original MSGID (useful for reply-linking) + + When forwarding, GoldED now adds these kludges, unless the + original message already contains them, in which case they are + preserved. When doing a normal reply (Alt-Q or Alt-R) to a message + with the FWD kludges, GoldED replies to the forwarder. To reply to + the from-name in the forwarded message, use the comment-reply + function (Alt-G). If the message contains the FWDAREA kludge, you + can reply to the forwarder in the original area (Alt-N) or reply + to the from-name in the original area (Alt-B). Note that it is not + possible to reply to the to-name of a message with the FWD + kludges, and it is also not possible to reply to the to-name of + the forwarded message (the FWDTO name). + + +USEINTL  (yes) + + The INTL kludge is normally only inserted in netmail messages, if + the origination zone is different from the destination zone (the + "Auto" setting), but on systems with many AKA's in the mailer, it + might be useful/necessary to add it ALWAYS (the "Yes" setting). + The "No" option should never be used. + + The can be one of the following: + + Auto Only insert in inter-zone netmail. + Yes Always insert. Recommended and default. + No Never insert. + + +USEMSGID  (yes) + + If enabled, the MSGID kludge is inserted in netmail and echomail, + and the REPLY kludge is inserted when replying to a msg with a + MSGID. + + The MSGID kludge is defined in FidoNet document FTS-9. + + +USEPID  (no if GoldEd mentioned in tearline, yes otherwise) + + If disabled then @PID kludge will not be used in your messages + regardless of tearline contents. + + +USERLIST [zone/addr] + + In addition to normal nodelist support, GoldED also supports the + "FIDOUSER.LST" style userlist format. The default zone is defined + by the first ADDRESS or AKA, but can be overridden by adding the + zone number or a full address after the filename. + + Userlist file in FIDOUSER.LST format. + [zone/addr] Default address for the userlist (if no zone info + is present). + + + +USERLISTFILE  (GOLDED.LST) + + GoldED can generate a list of all users in the current area. This + keyword defines the default name of the FIDOUSER.LST style + userlist output file generated with the READmakeuserlist command. + + +USERNAME [[,]< >address] + + You can define many different names/aliases. When GoldED finds an + un-received message to one of your USERNAME's, it is marked as + received. Useful if you use alias names in some conferences. It is + possible to change the current name using the READchangeusername + popup menu. + + For msgbase formats with an associated user database, GoldED uses + the *first* defined USERNAME to look in the user database for + which lastread record to use. If your name is not found, it is + added and a new lastread record created. + + Example: + + USERNAME Odinn Sorensen, 2:236/77.999 + + This keyword can be used globally and in a Random System group. + + +USETZUTC  (no) + + Activates usage of TZUTC kludge in your messages. You should + properly setup timezone information in your OS. For example, + in DOS you should set environment variable TZ to something + like this: + + TZ=MSK-3MSD,M3.5.0/02:00,M10.5.0/03:00 + + This line valid for Moscow, Russia. + + This option could be used in random system groups. + + +UUDECODEPATH  + + Specifies the path where files are placed when using the uudecode + feature. Files are placed in current directory if a path is not + specified. + + The specified path *must* exist ! + + +VIEWHIDDEN  (no) + + Hidden lines are "unknown" kludge lines. If enabled, hidden lines + will be displayed (in a different color) when reading msgs. + + A hidden line is defined as a line which has the FidoNet kludge + char (^a, ASCII 1) as the first char and is not on the list of + internally or user defined known kludges. + + This keyword can be used globally and in a Random System group. + + IMPORTANT NOTE: + + In some conferences the hidden lines are used to give witty + comment "between the lines" in the plain text, but generally it is + considered a bad practice and should be avoided because it may + cause severe technical problems if a witty comment in a hidden + line happens to match a (perhaps experimentally) defined kludge + somewhere. It should also be noted that hidden lines are not kept + in their original places when used in the JAM msgbase. This is due + to the way the JAM specification stores FidoNet kludges. + + +VIEWKLUDGE  (no) + + If enabled, known kludge lines will be displayed (in a different + color) when reading msgs. + + Known kludges are those defined internally in GoldED plus those + defined with the KLUDGE keyword. + + This keyword can be used globally and in a Random System group. + + +VIEWQUOTE  (yes) + + This is an experimental feature. It is similar to the VIEWHIDDEN + and VIEWKLUDGE keywords, but for quoted text. I implemented it + because I was annoyed with the excessive quoting often seen in + Internet newsgroups. When this keyword is set to NO, GoldED + attempts to trim down the quotes so that only the first line of + each quote block is shown. It is not always successful, sometimes + the result is not so useful. + + A key command has been added to supplement this feature: + READtogglequote. Suggested key assignment: Ctrl-V. Example: + + ^V READtogglequote + + Try it out if you are annoyed with excessive quotes. + + This keyword can be used globally and in a Random System group. + + +WHOTO  + + This name is inserted in the TO: name field, when entering new + messages (not replies) in echomail or local areas. + + This keyword can be used globally and in a Random System group. + + +WILDCATUSERNO  + + Defines the lastread set used in the WildCat! 4.x message base. + + +XLATCHARSET  + + This keyword defines character set translation table files. + + Charset import identifier. + Charset export identifier. + Charset translation table file. + + See the Character Translation chapter for details. + + +XLATESCSET  + + This keyword defines escape sequence translation table files. + + Escset import identifier. + Escset export identifier. + Escape sequence translation table file. + + See the Character Translation chapter for details. + + +XLATEXPORT  + + Defines the export charset for your messages. See the Character + Translation chapter for details. + + This keyword can be used globally and in a Random System group. + + It can also be used in templates (the @xlatexport token). + + +XLATIMPORT  (IBMPC) + + Defines the local charset for your machine. See the Character + Translation chapter for details. + + This keyword can be used globally and in a Random System group. + + +XLATLOCALSET  (IBMPC) + + Use this keyword to specify the actual physical charset in effect + for text screen display. This was previously the hardcoded value + IBMPC, corresponding to the IBM codepage 437 (or the nordic + edition 865). + + NOTE: All charset translation files must translate from and to the + charset identified with the XLATLOCALSET keyword! + + +XLATPATH  + + This is the path where GoldED tries to find the XLATCHARSET and + XLATESCSET files. + + +ZONEGATING  (ask) + + When writing a netmail message to a destination in another zone, + you can either send the message directly (No) or via the local + ZoneGate (Yes). You can also be consulted each time (Ask). GoldED + won't ask if Cra or Hld attribute is set. + +#page +#--------------------------------------------------------------------- +#chapter Obsolete Keywords + +This is a list of keywords which were used in various older versions. +These keywords are now obsolete, either because they have been renamed +or replaced, or if they no longer have any function. Most of the +keywords are still active and remapped to the new names. + +To check if you have obsolete keywords in your setup, run GoldED with +the -F -D commandline parameters. Then if you get a number of "Unknown +keyword" warnings, you should replace the old keywords with the new +ones or remove them. + + Old keyword: New keyword: + + AREAAUTOFREQ AREAFREQTO + AREABADMSGS SOUPBADMSGS + AREASORT AREALISTSORT + ASSIGNTO MEMBER + AUTOATTACH EDITAUTOATTACH + BEEPFACTOR (removed) + BLANKTIME SCREENBLANKER + BOARDNOS (removed) + CCATTRIB ATTRIBSCC + CCLIST CARBONCOPYLIST + CFMATTRIB ATTRIBSCFM + CHANGEDATE EDITCHANGEDATE + CHANGEPROMPT (removed) + CHARSET XLATCHARSET + CLEARKEYS (removed) + COLOUR COLOR + COMMENTNOISE BEEPCOMMENT + COOKIEFILE (removed) + CRLFTERM EDITCRLFTERM + DELORIG ASKDELORIG + DISPMSGLIST MSGLISTFIRST + DISPMSGLISTFAST MSGLISTFAST + DISPSTYLECODES STYLECODES + ECHOATTRIB ATTRIBSECHO + ECHOINFO CTRLINFOECHO + EDITMARGIN (removed) + EDITORVERSION (removed) + ELIMSNOW (removed) + ESCSET XLATESCSET + EXCLAREA AREAEXCL + EXPORTCHARSET XLATEXPORT + EXTKEYS (removed) + FIDOLASTREADNO FIDOUSERNO + FIELDCLEAR EDITFIELDCLEAR + FILECHECK (removed) + FILECHECKALL (removed) + FREEAREA (removed) + FREETEAR (removed) + GOLDEDCFM CONFIRMFILE + GOLDEDLOG LOGFILE + GOLDEDLST USERLISTFILE + GOLDEDMSG EDITORFILE + GOLDEDNAM NAMESFILE + GOLDEDPRN OUTPUTFILE + GOLDHELP (no longer documented) + GOLDKEYS (no longer documented) + GOLDLANG (no longer documented) + GOLDRAND (no longer documented) + GOLDXLAT (no longer documented) + HARDLINE EDITHARDLINE + HARDLINES EDITHARDLINES + HWMARKS (removed) + INCLAREA AREAINCL + INTERNALEDITOR EDITINTERNAL + LASTREAD FIDOLASTREAD + LASTREADUSER FIDOUSERNO + LISTWRAP (removed) + LOCALATTRIB ATTRIBSLOCAL + LOCALCHARSET XLATIMPORT + LOCALHIGHLIGHT (removed) + LOCALINFO CTRLINFOLOCAL + LOCALNOISE (removed) + MAPDRIVE MAPPATH + MATCHAKA AKAMATCH + MAXCOLS SCREENMAXCOL + MAXMSGSIZE EDITMSGSIZE + MAXROWS SCREENMAXROW + MIXCASE EDITMIXCASE + MULTIQBBS (removed) + NETATTRIB ATTRIBSNET + NETINFO CTRLINFONET + NETTEAR CTRLINFONET performs similar function + NEXTAREA AREANEXT + NEXTMSGS (removed) + NODELISTPAGEBAR (removed) + NOISEFACTOR (removed) + OVERLAYEMS OVERLAY performs similar function + OVERLAYEXT OVERLAY performs similar function + PAGEBAR (removed) + QBBSINCRESCAN (removed) + QBBSPATH HUDSONPATH + QBBSREBUILD (removed) + QBBSSCAN (removed) + QMSGPATH HUDSONPATH + REALMSGNO (removed) + REBUILD (removed) + RENAREA AREARENAME + REPLYRE EDITREPLYRE + RIGHTMARGIN DISPMARGIN + SAVEMENU EDITSAVEMENU + SAVETIME EDITAUTOSAVE + SAYBIBI (removed) + SCANAREA AREASCAN + SCREENELIMSNOW (removed) + SCREENUSEANSI (removed) + SHADOWS (removed) + SHARE SHAREMODE + SHOWTWITS TWITMODE + SIGNALFILE SEMAPHORE + SOUNDDEVICE (removed) + SPACEQUOTES (removed) + SPELLCHECKER EDITSPELLCHECK + STACKKEYS KEYBSTACK + STARTECHO AREASTART + SWAPALL DOSSWAP + SYSOP USERNAME + TABSIZE DISPTABSIZE + TAGLINEFILE (removed) + TIMESLICE (removed) + TIMEZONEOFFSET USETZUTC performs similar function + UNDELETELINES EDITUNDELETE + USEBIOS SCREENUSEBIOS + XPLIST CROSSPOSTLIST + +#page +#--------------------------------------------------------------------- +#chapter Location Dependent Configuration Keywords + +The following configuration keywords are location dependent and should +be placed in a particular order in the configuration file(s). Keywords +that are *not* listed can be placed anywhere you want. + +The keywords are listed in groups of those that depend on each other. +They are listed in the recommended order within each group. The order +between the groups is not important, with one noted exception. + +Name/Address/Areas: + USERNAME + ADDRESS + AKA + ATTRIBSNET Specifies default attributes for AREAFILE etc. + ATTRIBSECHO As above. + ATTRIBSLOCAL As above. + FIDOMSGTYPE + PCBOARDPATH Recommended if you use PCBoard. + MAPPATH + AREARENAME Rename occurs before AREAEXCL/INCL. + AREAEXCL + AREAINCL + AREAISEMAIL + AREAISNEWS + AREAPATH Default path for the AREAFILE's. + AREAFILE + RA2USERSBBS Overrides AREAFILE RemoteAccess. + AREADESC Add description and more to some AREAFILE's. + AREA Overrides areas in AREAFILE's. + AREADEF As above. + +Paths: + GOLDPATH + TEMPPATH MUST be in GOLDED.CFG. Used only by GoldNODE. + SWAPPATH + +Nodelists: MUST be below ADDRESS/AKA and ONLY in GOLDED.CFG! + NODEPATH + NODELIST + USERLIST + EXCLUDENODES Remember to replace "ALL" with '*'. + INCLUDENODES As above. + +Colors: + INTENSECOLORS Selects a default intense colorset if enabled. + COLORSET Selects a default colorset. + COLOR + +External utils: + EXTERNOPTIONS + EXTERNUTIL + +Character translation: + XLATPATH + XLATCHARSET + XLATESCSET + +Random System: + GROUP Starts a group. + MEMBER Defines areas that are members of the group. + See the Random System chapter for a list. + ENDGROUP Ends a group. + +#page +#--------------------------------------------------------------------- +#chapter Message Attributes Reference + +This is a list and description of all message attributes that are +supported by GoldED in the keywords that accept attribute settings or +can be displayed in the header. + +A/S Archive/sent. +ARQ Audit request. +ATT File attached. +CFM Confirmation receipt requested. +COV Fax cover letter. +CRA Crash - high priority mail. +DEL Deleted. +DIR Direct. Don't route this message. +FAX Fax image attached. +FRQ File request. +GRP Group message. +HIR Fax hi-resolution image. +HLD Hold for pickup. +HUB Host- or Hub-route message. +IMM Immediate - Send message NOW! +K/S Kill/sent. Delete message automatically after it is sent. +KFS Kill/file/sent. Delete attached files after they are sent. +LET Fax letterhead. +LOC Local. Message was written on your system. +LOK Lock. Prevents send/delete/purge/editing. +ORP Orphan. Could not be sent because destination node is unknown. +PRN Msg has been printed. Specific for Squish (bitvalue 00040000h). +PVT Private. Message may only be read by the addressee and author. +R/O Read only. Used in area definitions to prevent writing. +RCV Received. Read by the addressee. +RRC Return receipt. +RRQ Return receipt requested. +RSV FTS-1 reserved (unused) attribute. +SIG Fax signature. +SNT Sent. Message has been sent or exported from the msgbase. +TFS Truncate/file/sent. Truncate files to zero length when sent. +TRS Transit. Message passing through, not for you. +UNS Unsent message. +URQ Update file request. +XMA Xmail. Attach does not conform to the ARCmail 0.60 standard. +ZON Zonegate. Route through zonegate if possible. + +#page +#--------------------------------------------------------------------- +#chapter Area Configuration + +GoldED offers a wide variety of methods for defining message areas. +You can define each area manually in the GOLDED.CFG file (or an +INCLUDE'ed GOLDAREA.CFG file), or you can tell GoldED to read the area +setup files of many popular BBS/mailer/mail processor packages. + +For manual definition of areas, use the AREA or AREADEF (recommened) +keywords. + +For external area configuration, the general syntax for the AREAFILE +keyword is: + + AREAFILE [path or filename(s)] [-options] + +Available options: + +-NoChk + + Normally GoldED will check the areafile timestamps when starting + up, and recompile the configuration if a file was changed. If this + option is given for any AREAFILE, those areafiles will not be + checked. This can be useful in cases like TosScan, GEcho, IMail + and several others which "touch" their files every time they run. + + +-S + + If you are *not* using the global AREALISTSORT keyword for sorting + all the areas, you can sort the areas of each AREAFILE separately. + See the AREALISTSORT keyword for the definition of . + + +If no path is specified, the appropriate environment variable or the +AREAPATH is used to find the files. + +The can be one of the following: + +AdeptXBBS + + Reads the AdeptXBBS configuration files. + + Looks for the ADEPTXBBS environment variable. + + +AreasBBS + + GoldED is can handle a wide variety of AREAS.BBS type files. It + can read and distinguish between the old CONFMAIL style with paths + for *.MSG areas, the Hudson/Goldbase style with board numbers, the + Squish style with "$basename" and the JAM style with "!basename". + + The disadvantage of using an AREAS.BBS is that there are no area + descriptions. The echoid is used as description instead. However, + GoldED will use any text behind a semicolon on definition lines as + description. This may or may not be compatible with mail + processors, so be careful. A better solution may be to use the + AREAFILE Echolist to add descriptions from a separate file. + + One or more AREAS.BBS files may be specified on the same line. + + +Concord + + Support is planned but not yet implemented. + + +D'Bridge + + Reads the DBRIDGE.AA1/.AA2 files (for version 1.30) or the + DBRIDGE.ADF of the later versions. + + Looks for the "DBRIDGE" and "DB" environment variables. + + +Dutchie + + Reads the DUTCHIE.ARE file. + + Looks for the "DUTCHIE" environment variable. + + +Echolist + + Reads a simple ascii-text file containing an echolist in this + format: + + + + or DZ-format (requires -DZ switch): + + [Status], Tag, Comment, Moderator's Name, Address,[Flags] + + This feature adds descriptions to already existing areas in + GoldED. Example: + + AREAFILE AreasBBS AREAS.BBS + AREAFILE EchoList ECHOLIST.TXT + AREAFILE EchoList echo5020.lst -dz + + Descriptions for unknown echoids are ignored. Blank lines and + lines beginning with characters which are illegal in echoids (such + as ';') are also ignored. + + Additional switch -SqaFix could be used to read echolist and groups + from SqaFix configuration file: + + AREAFILE Squish C:\SQUISH\ + AREAFILE EchoList C:\SQUISH\SQAFIX.CFG -SqaFix + + +Ezycom + + Reads CONFIG.EZY and MESSAGES.EZY. Supports Ezycom 1.02 and 1.10g, + but not 1.01. + + Looks for the "EZY" and "TASK" environment variables. + + +FastEcho + + Reads the FASTECHO.CFG file. Supports version 1.10 up to 1.46. + + Looks for the "FASTECHO" environment variable. + + +Fidoconfig + + Reads fidoconfig (used in Husky Project software). Supports + version 0.15. Used parser is more powerful than original from + fidoconfig, due to it strictly follows specification from proposal + and implements all features from there. Additionaly it implements + groups not described in proposal but used in in library. + + Looks for the "FIDOCONFIG" environment variable. + + +FidoPCB + + Reads FIDOPCB.CFG. Supports version 1.x. + + Looks for the "FIDOPCB" environment variable. + + +FMail + + Reads FMAIL.CFG and FMAIL.AR. Supports versions 0.92, 0.98, 1.0g, + and 1.20. + + Looks for the "FMAIL" environment variable. + + +FrontDoor + + Reads the SETUP.FD/FD.SYS and FOLDER.FD/FOLDER.SYS files. If you + want the real echoid's attached to the areas, you will also need + to supply the filename of the relevant AREAS.BBS file(s). Supports + versions 1.99c and 2.xx. + + Looks for the "FD" environment variable. + + +GEcho + + Reads SETUP.GE and AREAFILE.GE. Supports versions 1.00, 1.02, + 1.10, 1.11 and 1.20. + + Looks for the "GE" environment variable. + + +IMAIL + + Reads the IMAIL.CF and IMAIL.AR files. Supports version 1.60, + 1.7x and 1.8x. + + Looks for the "IMAIL" environment variable. + + +InterMail + + Reads the FD.SYS/IMSYS.CFG and FOLDER.CFG/IMFOLDER.CFG files. + Supports version 2.26 and newer. + + Looks for the "IM" environment variable. + + +LoraBBS + + Reads the CONFIG.DAT and SYSMSG.DAT files. Supports version 2.33, + 2.40 and possibly others. + + Looks for the "LORA" and "LORABBS" environment variables. + + +Maximus + + Reads the MAX.PRM and AREA.DAT or MAREA.DAT files. Compatible (or + should be) with both the old (1.xx) and (2.xx) and new (3.xx) + formats. If your AREA.DAT is named differently, you must supply + the correct filename. + + Looks for the "MAXIMUS" environment variable. + + +ME2 + + Reads the old ME2 editor AREADESC.ME2 file and AREAS.BBS file(s). + You must supply the names of both files. + + +Opus + + Reads the Opus 1.1x SYSTEM??.DAT files or the Opus 1.7x SYSMSG.DAT + file. + + Looks for the "OPUS" environment variable. + + +ParToss + + Reads the ParToss configuration file. + + +PCBoard + + Reads the PCBOARD.DAT, CNAMES.@@@ and CNAMES.ADD files. Supports + version 14.x and 15.x, up to and including 15.22. Note that, + depending on the version, echoid's may not be read from this + format. If the echoid is not available, the description is used as + echoid, after conversion to uppercase and spaces to underscores. + + Looks for the "PCBOARD" environment variable. + + +Portal + + Reads the PORTAL*.CFG and PORTAL.ARE files. + + Looks for the "POPCMDLINE" environment variable. + + +ProBoard + + Reads MSGAREAS.PB. Supports version 2.0. + + Looks for the "PB" environment variable. + + +QEcho + + Reads /etc/qecho/AreaList. Supports version patched by Eugene + Sorochinsky for JAM message base support. + + +QFront + + Reads QORIGIN.DAT and QECHOS.DAT. Supports version 1.13b. + + Looks for the "QFRONT" environment variable. + + +QuickBBS + + Reads the CONFIG.BBS or QUICKCFG.DAT and MSGCFG.DAT files. To get + the real echoid's, you must also supply the filename of the + relevant AREAS.BBS. + + Looks for the "QUICKBBS" and "QBBS" environment variables. + + +RaEcho + + Reads AREAS.RAE. Supports version 1.00 and 1.01. + + Looks for the "RAECHO" environment variable. + + +RemoteAccess + + Reads the MESSAGES.RA file. To get the real echoid's, you must + also supply the filename of the relevant AREAS.BBS. Supports + versions 0.xx, 1.xx, 2.0x and 2.5x. + + Looks for the "RA" environment variable. + + +Squish + + Reads SQUISH.CFG and AREAS.BBS (if used). Supports version 1.0x + and 1.1x. The "Include " feature of Squish 1.10 is also + supported. + + The optional /G switch specifies the default group of the imported + areas, i.e. /g=G or /g=#103. + + Looks for the "SQUISH" and "MAXIMUS" environment variables. + + +SuperBBS + + Reads CONFIG.BBS, SCONFIG.BBS and BOARDS.BBS. Supports version + 1.16 and 1.17. + + Looks for the "SUPERBBS" and "SBBS" environment variables. + + +timEd + + Reads TIMED.CFG and any included file. Also reads the + configuration from other mail software defined in TIMED.CFG. + + Looks for the "TIMED" environment variable. + + +Termail + + This is for the Terminate Mail system (Termail). GoldED does + currently only support Termail 4.00 und 5.xx style .CFG-files. + + Reads TM.CFG and any AREAFILE (an AREAS.BBS type file) defined + there. + + NOTE: If you use this, you must start GoldED in the Termail + directory, because the standard TM configuration files use + relative paths. + + Looks for the "TM" environment variable. + + +TosScan + + Reads the FD.SYS/SETUP.FD and AREAFILE.FD files. Supports version + 1.00 and FrontDoor 1.99c and 2.xx. + + Looks for the "FD" environment variable. + + +WaterGate + + Reads the WTRCFG.TDB and AREABASE.TDB files. Supports version + 0.93. + + +WMail + + Reads the WMAIL.PRM and AREAS.PRM files. Supports version 2.2. + + Looks for the "WMAIL" environment variable. + + +XMail + + Reads the AREAS.XM file. Supports version 1.00. + + Looks for the "XM" environment variable. + +#page +#--------------------------------------------------------------------- +#chapter The Random System + +With the Random System, you can define area-specific sets of origins, +netnames, tearlines, templates, usernames and many other items. If +more than one item of each type is specified, a random one is picked - +a Random System. This is a very useful feature when (for example) +participating in conferences with different languages. + +The Random System is built on the idea of "groups". A group is a +collection of "items", belonging to the group. You can assign one or +more echomail areas, designated by their echoid's to a group. Groups +can also be specified for just a single echo, and DOS/4DOS-style +wildcards can be used to simplify the assignment of echoes with common +strings in their name, such as *.DK, SIG.* and so on. In this way, you +could for example setup one group for all national echoes, another for +special local echoes, a third for international echoes etc. + + +Defining Groups + +The general syntax of a group definition is: + +GROUP [:] + ; items go here + [Member ] +ENDGROUP + +The Group can be one of three things: + +1. A group letter or #number, matching the group letters or numbers + used in the AREAFILE's of D'Bridge, GEcho, IMAIL, TosScan and many + others. To use this feature, you need to enable the AREAFILEGROUPS + keyword. + +2. An individual echoid or echoid mask (wildcards can be used). The + items are then simply defined below the Group line. + +3. A group label, terminated by a colon (:). The group items are + defined below the Group line. Echoes are assigned to the group by + adding one or more Member statements. + +You can't assign a group to another group. It will not harm, but it +also won't work :-) + +The order of groups is very important. GoldED scans the groups from +the top down. This means that the most general groups must be placed +at the bottom and exceptions (individual areas for example) must be +placed at the top. + + +Defining Random Items + +The random items are defined much like in the main GoldED +configuration file. + +If more than one of each item is defined within a group, those items +will be picked randomly (hence the name "Random System"), while GoldED +collects items when entering an area. + +Random Item Keywords: + AKA + AKAMATCHING + AREACOPYDIRECT + AREACOPYTO + AREAFREQDIRECT + AREAFREQTO + AREAREPLYDIRECT + AREAREPLYTO + AREAYOUWROTETO + ATTRIBUTES + CTRLINFO + EDITHARDTERM + EDITMIXCASE + EDITREPLYRE + FORCETEMPLATE + INPUTFILE + INTERNETADDRESS + INTERNETGATE + INTERNETMSGID + INTERNETRFCBODY + LOADLANGUAGE + MSGLISTDATE + MSGLISTFAST + MSGLISTFIRST + MSGLISTHEADER + MSGLISTWIDESUBJ + NETNAME + NICKNAME + ORGANIZATION + ORIGIN + OUTPUTFILE + PLAY + QUOTEBUFFILE + QUOTECHARS + QUOTESTRING + QUOTEWRAPHARD + SEARCHFOR + TAGLINE + TAGLINECHAR + TEARLINE + TEMPLATE + TEMPLATEMATCH + TWITMODE + USEFWD + USERNAME + USETZUTC + VIEWHIDDEN + VIEWKLUDGE + VIEWQUOTE + WHOTO + XLATEXPORT + XLATIMPORT + +See the Configuration Keyword Reference chapter for details about each +keyword. + + +Random System Example + +Below is an example of how a Random System could be setup. Note how +the letter group 'D' goes first, followed by the explicit group +definitions for the NERDS and FOO echoes. Then comes the more general +groups (those with Label:'s), where the echoes are assigned with one +or more Member statements. At last there is the catch-all "Group *", +which works as the default group. + + +=== Cut, GOLDRAND.CFG === + +Group NERDS ; For the NERDS echo. + Origin "I am a Nerd. Take me to your Loser!" + +Group FOO ; This group is *only* for the FOO echo. + Tearline FooED @rev + Origin "Foo-ing my day away" + +Group FooEchoes: + Member *FOO* ; Use wildcards to catch any other foo echo. + Tearline FooED @rev + Origin "This is a Foo-lish origin" + +Group FidoNet: + Member NET_DEV, WORLDPOL, INTERCOOK + Member GREEN.029, C_ECHO, C_PLUSPLUS + Origin "Fight-O-Net? Good name..." + Template FIDONET.TPL + Whoto Everyone + +Group SigNet: + Member SIG.* ; The wildcard is VERY handy here ;-) + Origin "To SIG or not to SIG..." + Template SIGNET.TPL + +Group D ; Letter D for Danish echoes. + Template DANSK.TPL + +Group * ; This is default group + Origin "Yet another forgotten echo" + +=== Uncut === + +See the example GOLDRAND.CFG in the ADVANCED archive for a real-life +setup similar to the one I use myself. + +#page +#--------------------------------------------------------------------- +#chapter Color Configuration + +Color configuration in GoldED is a bit complicated, and you probably +have to experiment quite a bit, if you want make your own setup. For +your convenience, I have added a number of example color setups, +provided by some of my many good users. I suggest you try them all and +use the one that suits you best, perhaps tuning it a bit to your +taste. + +The COLOR keyword uses the following syntax: + +COLOR  + + AREA, ASK, BACKGROUND, BRAG, HEADER, HELP, INFO, MENU, + READER, SHADOW, STATUS. + + BLOCK, BORDER, BTYPE, EDIT, HIDDEN, HIGHLIGHT, INPUT, + KLUDGE, NOSELECT, ORIGIN, QUOTE, SELECTOR, TEARLINE, + TITLE, WINDOW. + +The are composed of [blinking] [on ]. + + Black, Blue, Green, Cyan, Red, Magenta, Brown, LGrey, + DGrey, LBlue, LGreen, LCyan, LRed, LMagenta, Yellow, + White. + + Black, Blue, Green, Cyan, Red, Magenta, Brown, LGrey. + +For monochrome setups we instead have: + + Normal, Highlight, Reverse, Underline. + +The SHADOW color does not need a , because it is global. + +The paper color always defaults to Black if not specified. + +If is "BTYPE", the is a value in the range 0-3, which +defines the type of lines used when drawing menus and windows: + +BTYPE 0 is single horizontal and single vertical lines. +BTYPE 1 is double horizontal and double vertical lines. +BTYPE 2 is single horizontal and double vertical lines. +BTYPE 3 is double horizontal and single vertical lines. + +The default border type is always BTYPE 0. + +The following is a description of the different window parts: + +Various general color items + + SHADOW Shadow below windows and menus. + STATUS WINDOW Status line at the bottom. + BACKGROUND WINDOW Background for the startup window. + BACKGROUND BORDER Overscan color (currently DOS only). + + PAGEBAR Pagebar (scrollbar). + + The PAGEBAR color specifially sets the color of the pagebars + (scrollbars) in GoldED. A pagebar color can currently be set for + AREA, READER and MENU. Note that BORDER will set both the BORDER and + PAGEBAR colors, so remember to place the PAGEBAR color below the + BORDER color. + +Startup screen / logo window + + BRAG WINDOW The Copyright window. + BRAG BORDER Lines around the Copyright window. + BRAG TITLE The logo text. + BRAG HIGHLIGHT The inner logo lines. + BRAG BLOCK The outer logo lines. + BRAG BTYPE Copyright window border type. + +Area Selection Menu + + AREA WINDOW Descriptions, the top line (inc. search). + AREA BORDER Lines. + AREA TITLE Titles on the border. + AREA SELECTOR Selection bar. + AREA HIGHLIGHT The color for the area marks. + AREA BTYPE Window border type. + +Message Header + + HEADER WINDOW Header text. + HEADER BORDER Lines. + HEADER TITLE Titles on the border. + HEADER INPUT Message number input field. + HEADER EDIT Header input fields. + HEADER HIGHLIGHT Marks. + HEADER BTYPE Window border type. + HEADER FROM Header From field. + HEADER TO Header To field. + HEADER SUBJECT Header Subject field. + + The FROM/TO/SUBJECT colors supplement the HEADER WINDOW color. Note + that WINDOW will also set the FROM/TO/SUBJECT colors, so remember to + place the new colors below it. + +Message Text + + READER WINDOW Normal message text. + READER BORDER The Pagebar. + READER QUOTE (Odd) Quoted lines. + READER QUOTE2 (Even) Quoted lines. + READER CURSOR Character at cursor pos. (int. editor). + READER KLUDHIDD Kludges and hidden lines. + READER TEARORIG Tearline and Origin. + READER BLOCK Block color (internal editor). + READER BTYPE Window border type. + READER HIGHLIGHT Search highlight in the message text. + READER KLUDGE Known kludges. + READER HIDDEN Hidden lines. (Unknown kludges). + READER SIGNATURE Internet-Style signatures ("-- "). + READER TAGLINE Taglines. (Only the one just above tearline). + READER TEARLINE Tearline. + READER ORIGIN Origin. + + The KLUDGE/HIDDEN colors replaces the old KLUDHIDD color. Note that + KLUDHIDD will set both the KLUDGE and HIDDEN colors, so remember to + place the new colors below it if you keep the old definition. + + The TAGLINE color is the color of taglines. GoldED detects a tagline + if it starts with "..." or "___" and is just above the tearline or + origin. + + The TEARLINE/ORIGIN colors replaces the old TEARORIG color. Note + that TEARORIG will set both the TEARLINE and ORIGIN colors, so + remember to place the new colors below it if you keep the old + definition. + +Miscellaneous Smaller Menus + + ASK WINDOW Menu items. + ASK BORDER Lines. + ASK TITLE Menu title. + ASK SELECTOR Selection bar. + ASK NOSELECT Non-selectable menu items. + ASK HIGHLIGHT Hotkeys. + ASK BTYPE Window border type. + +Miscellaneous Larger Menus (Browser Windows) + + MENU WINDOW Menu items. + MENU BORDER Lines. + MENU TITLE Menu title. + MENU SELECTOR Selection bar. + MENU NOSELECT Non-selectable menu items. + MENU HIGHLIGHT Hotkeys/marks. + MENU UNREAD When a msg is unread. + MENU UNREADHIGH Additional highlight of to/from. + MENU UNSENT When a msg is unsent. + MENU UNSENTHIGH Additional highlight of to/from. + +Help Screens + + HELP WINDOW Help text. + HELP BORDER Lines. + HELP SELECTOR Current keyword. + HELP HIGHLIGHT Other keywords. + HELP BTYPE Window border type. + +Pop Up Information Windows + + INFO WINDOW Window text. + INFO BORDER Lines. + INFO TITLE Info title. + INFO BTYPE Window border type. + +Stylecodes + + STYLECODE ALL All stylecodes at once. + STYLECODE B *Bold* + STYLECODE I /Italic/ + STYLECODE BI /*BoldItalic*/ + STYLECODE U _Underline_ + STYLECODE BU _*BoldUnderline*_ + STYLECODE IU /_ItalicUnderline_/ + STYLECODE BIU _/*BoldItalicUnderline*/_ + STYLECODE R #Reverse# + STYLECODE RB *#ReverseBold#* + STYLECODE RI /#ReverseItalic#/ + STYLECODE RBI /*#ReverseBoldItalic#*/ + STYLECODE RU _#ReverseUnderline_# + STYLECODE RBU _*#ReverseBoldUnderline#*_ + STYLECODE RIU _/#ReverseItalicUnderline#/_ + STYLECODE RBIU _/*#ReverseItalicUnderline#*/_ + + Note that stylecode color definitions must be placed below COLOR + READER WINDOW, because it overrides the COLOR STYLECODE definitions. + +See the GEDCOL*.CFG and GEDMON*.CFG files for examples of color +configuration. + +#page +#--------------------------------------------------------------------- +#chapter The Message Template + +The message template gives you a ready-made skeleton for writing your +messages in the editor. The template is one of GoldED's many strong +features. With this, you can eliminate the tedious typing of greetings +etc etc. GoldED also provides a number of replacement strings, +"tokens", to dynamically add message specific information to the +template. + +As in the configuration file, a semicolon (;) first on the line makes +the line a comment. Any other line is put into the editor file, after +token expansion. Tokens are not case sensitive. + +The following is a list of the tokens available: + + +Conditional tokens (these are replaced with a null string) + +@changed Line is only inserted in Changed msgs (from others). +@comment Line is only inserted in Reply-Comments. +@echo Line is only inserted in Echomail. +@forward Line is only inserted in Forwarded messages. +@local Line is only inserted in Local messages. +@moderator Line is only inserted if substring "moderator" appeared in + from line. +@moved Line is only inserted in Reply-Moved messages. +@net Line is only inserted in Netmail. +@new Line is only inserted in New messages (not replies). +@position Specifies the starting line for the editor cursor. +@quotebuf Line is only inserted in Quotebuffered msgs. +@quoted Line is only inserted in Quoted replies. +@reply Line is only inserted in Non-Quoted Replies. + + +Insert tokens (anything else on the line is ignored) + +@attrib - Adds specific message attributes. +@include - Inserts the file. +@forcefrom <"from"> - sets message FROM: field, even if non-empty + (see @setfrom) +@forcesubj <"subject"> - sets message SUBJ: field, even if non-empty + (see @setsubj) +@forceto <"to"> - sets message TO: field, even if non-empty + (see @setto) +@loadlanguage Loads a partial language config file. +@message Inserts the original message (in Forward & Change). +@quote Inserts a quote of the original message. +@random [random.txt] - Inserts random text. +@setfrom <"from"> - Sets the message FROM: field. +@setsubj <"subject"> - Sets the message SUBJ: field. +@setto <"to"> - Sets the message TO: field. +@xlatexport - Sets the export charset. + + +Replacement tokens (replaced with message specific data): + +@c3daddr Current user 3D (boss) address. +@caddr Current user address. +@cdate Current date. +@cdesc Current area description. +@cecho Current echoid. +@cfname Current user first name. +@clname Current user last name. +@cname Current user name. +@cpseudo Current pseudonym given by NICKNAME keyword, or @cfname. +@ctime Current time. +@ctzoffset Current timezone offset (if available and enabled). +@d3daddr Destination 3D (boss) address. +@daddr Destination address. +@dfname Destination first name. +@dlname Destination last name. +@dname Destination name. +@dpseudo Destination pseudonym (see addressbook), or @dfname. +@f3daddr Current from 3D (boss) address. +@faddr Current from address. +@ffname Current from first name. +@flname Current from last name. +@fname Current from name. +@fpseudo Current from pseudonym (see addressbook), or @ffname. +@longpid Long program id. "GoldED", "GoldED/2" or "GoldED/386". +@o3daddr Original 3D (boss) address. +@oaddr Original address. +@odate Original date. +@odesc Original area description if moved, else current. +@oecho Original echoid if moved, otherwise current. +@ofname Original first name. +@ofrom Original RFC "From" headerline. +@olname Original last name. +@omessageid Original RFC "Message-ID" headerline. +@omsgid Original MSGID kludge content. +@oname Original name. +@opseudo Original pseudonym (see addressbook), or @ofname. +@origin The current global or Random System origin. +@os2slash "/2" if running GoldED/2. Empty otherwise. +@osslash same as above. +@otime Original time. +@otzoffset Original timezone offset (if available and enabled). +@oto Original RFC "To" headerline. +@pid Short program id. "GED", "GED/2" or "GED386". +@pseudo pseudonym (see addressbook), or @tfname. +@rev The revision number (in the form mmdd). +@serialno Emptiness. +@subject The message subject line. +@t3daddr Destination to 3D (boss) address. +@taddr Destination to address. +@tagline The current global or Random System tagline. +@tearline The current global or Random System tearline. +@tfname Destination to first name. +@tlname Destination to last name. +@tname Destination to name. +@tpseudo Destination to pseudonym (see addressbook), or @tfname. +@ver The simple version number (in the form x.yy) +@version The complete release version number of GoldED. +@_caddr Current user address (fixed width: 19 chars). +@_cname Current user name (fixed width: 34 chars). +@_daddr Destination address (fixed width: 19 chars). +@_dname Destination name (fixed width: 34 chars). +@_oaddr Original address (fixed width: 19 chars). +@_oname Original name (fixed width: 34 chars). +@_taddr Destination to address (fixed width: 19 chars). +@_tname Destination to name (fixed width: 34 chars). + + +Tokens dealing with names may optionally have two parameters (each +parameter enclosed in curve brackets): your name and opponent name, +destination name additionally accepts third parameter - WhoTo name. +Here is example on how this feature could be used: + + @oname{I}{You} wrote to @dname{me}{you}{everyone}: + + +The template text begins at the first non-comment line. + +See the included GOLDED.TPL for example usage. + +If you need to put some text which contains one of these tokens into a +template file, use an extra '@' in front of the token. + +Example: + + Internet: somebody@veryhot.com + +would produce + + Internet: somebody2.51yhot.com (because @ver is a token) + +so write it like this instead: + + Internet: somebody@@veryhot.com + +The double '@' will then be translated to a single, and token +translation skips past the @token. + +#page +#--------------------------------------------------------------------- +#chapter The Online Help System + +GoldED has a built-in context sensitive help system, tied to the +key (one of the very few keys that cannot be reconfigured). It +contains a complete keyboard reference and help for most situations. +It is current not as complete or sophisticated as I'd like it myself, +but this may be improved in future versions. + +You can completely redefine the help screens if you wish - the +GOLDHELP.CFG file is a plain ASCII text file which contains all help +definitions. The help file is split into several help categories. Here +is an example of a couple of defined help categories: + + *B 1,Help Category 1 + help text help text help text + help text help text help text + *P + help text help text help text + help text help text help text + *E + + *B 2,Help Category 2 + help text help text help text + help text help text help text + *P + help text help text help text + help text help text help text + See also: ^Help Category 1^ + *E + +The "*B" indicator specifies the beginning of a help category. The +format is "*B helpcatnumber[,helpcatname]". In GoldED the help +categories are numbered 1000-9999, split into more or less logical +groups. See the help file for assignments. There should be only one +space between the "*B" and the help category number. The help category +name is only required for cross-references. If there are no +cross-references to that help category, then you can leave the +helpcatname parameter out. + +The "*P" indicator specifies a page break and is optional. You may +have as many page breaks as you'd like. The "*E" indicator specifies +the end of the help category. The "*B", "*P", and "*E" indicators must +all begin in the first column. These indicators and the help category +name are case insensitive (can be in lowercase, uppercase, or mixed). + +In the definition of Help Category 2, you will notice the +crossreference to Help Category 1. All cross-referencing is done by +embedding the cross- reference category name (not number) inside +carats (^). If you need to display a carat inside the help file, use a +double carat (^^). + +Any text contained outside of the "*B" and "*E" is treated as +comments. If an "*E" is not found, then the end-of-file will be +treated as an "*E". + +Not all of the help categories in this help file are actually used in +the current version of GoldED. The ones not used are empty, except for +a two-line "header". + +The usable dimensions of the help window are 60 columns by 16 lines. +In the help file there is a model of the actual window. + +#page +#--------------------------------------------------------------------- +#chapter Character Translation + +GoldED implements several different proposals for character +translation in imported and exported messages: + +FSC-0050 "Charset Identifier" by Thomas Sundblom. +FSC-0051 "I51" by Thomas Gradin. +FSC-0054 "CHARSET proposal" by Duncan McNutt. +No FSC "Composed Characters" by Andre van de Wijdeven. + +FSC-0050 is currently known to be implemented in the OPMED 3.xx +message editor, and in Opus 1.7x. It uses the same identifier as +FSC-0054 (a ^aCHARSET kludge), but is a lot simpler (but not +necessarily better). + +The "I51" and "CHARSET" proposals are in the process of being merged +to one proposal, which should combine the advantages of both. They are +both based on using the LATIN-1 (also known as ISO 8859-1) character +set for extended ASCII. The LATIN-1 set is the same set used by +Windows 3.xx, Amiga and many other non-PC computers. In addition to +LATIN-1, I51 defines a set of so-called escape sequences for +characters not found in the LATIN-1 set. + +"Composed Characters" became quite popular in Holland, but the author +decided to drop his proposal because it relied on escape sequences +using the so called "soft-cr" (141d, 8Dh) character. GoldED will +continue to support Composed as long as it seems necessary. + +If you want to know more about the details, I suggest you read the +proposals or contact the authors. + +GoldED currently supports two types of translation tables, the *.ESC +files and the *.CHS files. + + +The ESC translation tables + +The *.ESC files are used for import translation of the escape +sequences defined in I51 and Composed Characters. + +In the ESC files, the semicolon is used for comments. The *first* +non-comment line defines the charset the escape code are mapped TO. +This is normally IBMPC, and should not be changed. Any other +non-comment line is treated as an escape sequence definition with this +syntax: + + [; comment/description] + +Leading spaces are *not* allowed in ESC files. and are +the two characters that define the escape sequence. is ignored +and can be used to make the table look better. defines the +local representation of the escape sequence, up to three characters. +Normally you would only map to one extended ascii character. The map +chars can be either the characters themselves, or decimal or +hexadecimal numbers of the form "\d" or "\x" (like in the C +programming language). + + +The CHS translation tables + +The *.CHS files are used for import and export translation of the +CHARSET type character sets, and export of I51 and Composed escape +sequences. + +The CHS files uses the format of the raw text files provided in the +CHARSET3.ZIP example implementation of FSC-0054. Study some of the +files provided if you want to know how to define them. + +The two keywords XLATESCSET and XLATCHARSET are used to define which +files belong to what import and export set. You can define more than +one import and export set for each file. + +The keyword XLATIMPORT defines which charset you have on your own +machine - this would normally be "IBMPC". It can be useful to change +this (using the Random System) in areas where another character set +than IBMPC is the dominant (like Amiga or MacIntosh, whatever). + +The keyword XLATEXPORT defines the charset your messages should be +exported to, if any. + +Confused? Yeah, I know - this is a confusing subject, and my +implementation and documentation is not perfect. Normally you will not +have to worry about it. Turn it off completely if you don't understand +it. + +#page +#--------------------------------------------------------------------- +#chapter Keyboard Command Reference + +Most of the GoldED keyboard commands can be reached with just one +keystroke. To ease operation for experienced users of other message +editors, GoldED comes with several sets of keys for each of the +keyboard commands - direct non-shifted keys, Alt/Ctrl-keys and +function keys. Many of these key assignments will be familiar for +users of Msged, Msged/Q, ME2 and FM. + +The following is a list of all keyboard commands, sorted by type and +alphabetically, using the format + + + +This list is also available in the context-sensitive help system on +the key. + +It is possible to almost completely redefine the keyboard - this in +done in the GOLDKEYS.CFG file, which also handles macro definition +(see later). + + +Arealist commands: + +AREAabort Abort the arealist. +AREAaskexit Exit GoldED, prompt for final decision. +AREAboardnos Toggle sequential areas vs. board numbers. +AREAcatchup Point the lastread pointer to the last message + in the current area. +AREAdosshell Shell to DOS. +AREAdropmsgmarks Unmark all msgs in selected areas. +AREAgotofirst Move selection bar to first area. +AREAgotolast Move selection bar to last area. +AREAgotonext Move selection bar to next area. +AREAgotoprev Move selection bar to previous area. +AREAheat Heat highwatermarks. +AREAjump Move selection bar to next marked area. +AREAjumpnextmatch Move selection bar to next matching area. +AREAquitnow Exit immediately, no questions asked. +AREAscan Scan areas. +AREAscanpm Scan areas for personal mail. +AREAselect Enter the reader for the selected area. +AREAselectmarks Select which set of area marks should be used. +AREAsoundkill Stops currently played sound file. +AREAtoggle Toggle mark on the selected area. +AREAtouchnetscan Touches the SEMAPHORE NETSCAN file. +AREAwritegoldlast Write a fresh copy of GOLDLAST.LST +AREAzap Zap highwatermarks. + + +Internal editor commands: + +EDITabort Abort editing this message - ask first. +EDITanchor Set a block "anchor" on the current line. +EDITaskexit Exit from GoldED - ask first. +EDITblockdown Extend block area one line down. +EDITblockend Extend block area to the end of line. +EDITblockhome Extend block area to the beginning of line. +EDITblockleft Extend block area one character left. +EDITblockpgup Extend block area one screen up. +EDITblockpgdn Extend block area one screen down. +EDITblockright Extend block area one character right. +EDITblockup Extend block area one line up. +EDITcleardeletebuf Clears the undelete buffer. +EDITclearpastebuf Clears the cut'n'paste buffer. +EDITcopy Copies the block to the cut'n'paste buffer. +EDITcopyabovechar Inserts character same as in the same position + in previous line. +EDITcut Cut the block to the cut'n'paste buffer. +EDITdelchar Delete the char at the cursor position. +EDITdelete Delete the block. +EDITdeleteeol Delete from cursor position to end of line. +EDITdelleft Delete the char to the left of the cursor. +EDITdelline Delete the current line. (Copied to the +EDITdelltword Delete the word to the left of the cursor. +EDITdelrtword Delete the word to the right of the cursor. +EDITdosshell Shell to DOS. +EDITdupline Duplicates the current line. +EDITexitmsg Drop this message - NO ASKING! DANGEROUS! +EDITexporttext Exports the current block to a file. +EDITgobegline Move cursor to beginning of line. +EDITgobotline Move cursor to the bottom line in the display. +EDITgobotmsg Move cursor to the last line in the message. +EDITgodown Move cursor down to next line. +EDITgoeol Move cursor to the end of the line. +EDITgoleft Move cursor one position left. +EDITgopgdn Move cursor one page of lines down. +EDITgopgup Move cursor one page of lines up. +EDITgoright Move cursor one position right. +EDITgotopline Move cursor to the top line in the display. +EDITgotopmsg Move cursor to the first line in the message. +EDITgoup Move cursor up to the previous line. +EDITgowordleft Move cursor to the previous word. +EDITgowordright Move cursor to the next word. +EDITheader Edit the message header, attributes etc. +EDITimportquotebuf Imports the current quote buffer. +EDITimporttext Import text file into this message. +EDITkillquotes (ignored) +EDITloadfile Load the message file saved with EDITsavefile. +EDITlookupcursor Lookup name/node at cursor position. +EDITlookupdest Lookup TO: node. +EDITlookuporig Lookup FROM: node. +EDITnewline Terminate paragraph and/or add a new line. +EDITpaste Paste a previously cut block at the cursor. +EDITquitnow Quit GoldED immediately - no asking. +EDITreflow Reflows the current text or quote paragraph. +EDITsavefile Saves the current message as a file. +EDITsavemsg Save this message. +EDITsoundkill Stops currently played sound flie. +EDITspellcheck Calls an external spell checker for the msg. +EDITtab Add spaces to the next tab-stop. +EDITtabreverse Remove spaces to the prev tab-stop. +EDITtogglecase Toggle the case of the cursor character. +EDITtoggleinsert Toggle insert mode. +EDITtolower Change the cursor character to lowercase. +EDITtoupper Change the cursor character to uppercase. +EDITundelete Undelete previously deleted lines. +EDITzapquotebelow Deletes quotes below. + + +File selection commands: + +FILEabort Abort file selection. +FILEaskexit Exit GoldED - ask first. +FILEdosshell Shell to DOS. +FILEgotofirst Go to first file. +FILEgotolast Go to last file. +FILEgotonext Go to next file. +FILEgotoprev Go to previous file. +FILEmark Mark file. +FILEmarkall Mark all files. +FILEquitnow Quit GoldED immediately. +FILEselect Select the marked file(s). +FILEtogglemark Toggle file mark. +FILEunmark Unmark file. +FILEunmarkall Unmark all files. + + +Message lister commands: + +LISTabort Abort message lister. +LISTaskexit Exit GoldED - ask first. +LISTdosshell Shell to DOS. +LISTgotobookmark Go to BookMark message. +LISTgotofirst Go to first message. +LISTgotolast Go to last message. +LISTgotonext Go to next message. +LISTgotoprev Go to previous message. +LISTmarkingoptions Marking menu. +LISTquitnow Quit GoldED immediately. +LISTselect Go to reader at the selected message. +LISTtogglebookmark Toggle BookMark on the selected message. +LISTtoggledate Toggle date column content. +LISTtogglemark Toggle Mark on the selected message. +LISTtogglewidesubj Toggle between wide and short subject. + + +Nodelist browser commands: + +NODEabort Abort nodelist browsing. +NODEaskexit Exit GoldED - ask first. +NODEdosshell Shell to DOS. +NODEgotofirst Go to first node. +NODEgotolast Go to last node. +NODEgotonext Go to next node. +NODEgotoprev Go to previous node. +NODEquitnow Quit GoldED immediately. +NODEselect Select node. + + +Message reader commands: + +READaddressbookadd Add current/marked mail writer(s) to + addressbook. Ask first. +READaskexit Exit GoldED, prompt for final decision. +READchangeaka Change default AKA address for current area. +READchangeattrs Change the attributes of the current message. +READchangemsg Change current message. +READchangeorigin Change default origin for the current area. +READchangetagline Change default tagline. +READchangetemplate Change default template. +READchangeusername Change default username. +READchangexlatimport Change default import charset. +READcommentmsg Comment-Reply to message. (Reply to TO name). +READcopymoveforward Enter the Copy/Move/Forward function menu. +READdecreasemargin Decrease message margin. For test purposes. +READdeletemsg Delete current/marked message(s). Ask first. +READdosshell Shell to DOS. +READfidorenumber Renumber Fido/Opus *.MSG files. +READfilerequest Generate a filerequest from the current msg. +READfindall Find string(s) in message header and text. +READfindheader Find string(s) in message header. +READgotobookmark Go to the "BookMark" message. +READgotofirstmsg Go to the first message in the area. +READgotolastmsg Go to the last message in the area. +READgotomsgno Go to a specific message number. +READgotonextarea Go directly to the next area. +READgotonextmsg Go to the next message. +READgotonextunread Go to the next unread message. +READgotoprevarea Go directly to the previous area. +READgotoprevmsg Go to the previous message. +READgotoprevunread Go to the previous unread message. +READgotoreplies Choose from the next messages in the replylink. +READgotoreply1st Go to the first reply to this message. +READgotoreplynext Go to the next reply to this message. +READgotoreplyprev Go to the parent message in the replylink. +READincreasemargin Increase message margin. For test purposes. +READlookupdest Lookup TO: node. +READlookuporig Lookup FROM: node. +READmakeuserlist Generate FIDOUSER.LST of users in the area. +READmakepathreport Added "path report" feature. The output file + can be processed by a RDDT (Route Diagram + Drawing Tool) utility. +READmarkingoptions Enter the marking menu. +READmessagelist Enter the message lister. +READmovecommentmsg Comment-Reply in another area. +READmovequotemsg Quote-Reply in another area. +READmsgcontinue Page down or go to next message. +READmsgend Display last part of current message. +READmsghome Display first part of current message. +READmsglinedown Scroll message display. +READmsglineup Scroll message display. +READmsgpgdn Page message display. +READmsgpgup Page message display. +READnewarea Enter the area selection screen. +READnewmsg Start a new message. +READquitnow Exit GoldED immediately, no questions asked. +READquotebuf Append quote of the msg to the quotebuffer. +READquotemsg Quote-Reply to message. (Reply to FROM name). +READreplymsg Reply to the current message, without quoting. +READsearch Launches the search engine. +READsoundkill Stops currently played sound file. +READthreadtree Enter the Message Threading lister. +READtogglebookmark Toggle a "BookMark" on the current message. +READtogglehexdump Toggle hexdump mode. For debugging purposes. +READtogglehiddklud Toggle display of Hidden and Kludge lines. +READtogglehidden Toggle display of Hidden lines. +READtogglekludge Toggle display of Kludge lines. +READtogglemark Toggle a message mark on the current message. +READtogglemarkread Toggle "Read Marked" mode. +READtogglepagebar Toggle the "PageBar" feature. +READtogglequote Toggle display of quoted lines. Experimental. +READtogglerot13 Toggle ROT13 encryption for the current msg. +READtogglerealmsgno Toggle between seq. or real message numbers. +READtogglestyles Toggle Disable/Show/Show+Strip of STYLECODES. +READtoggletwits Toggle Twit display - Show/Blank/Skip/Ignore. +READtouchnetscan Touches the SEMAPHORE NETSCAN file. +READtouchsemaphore Popup touch a manually entered semaphore file. +READuserbase Launches the addressbook. +READuudecode UUdecodes the current message. +READwritemsg Write message(s) to file or printer. + + +Key undefine commands: + +AREAundefine +EDITundefine +FILEundefine +LISTundefine +NODEundefine +READundefine + +The undefine commands can used to undefine any of the built-in default +keyboard definitions. + + +See the Key Reference below for a list of the key symbols you can use +in keyboard redefinition. + +#page +#--------------------------------------------------------------------- +#chapter Macros and Keystacking + +GoldED has a simple keyboard macro facility, which you can use to +automate certain common operations. In addition, a "keystacking" +facility allows you to create simple automatic macros on the fly. + + +The macro definition syntax is modelled after the syntax used in the +QEdit text editor: + + Macro + AreaMacro + EditMacro + FileMacro + ListMacro + NodeMacro + ReadMacro + +Macros are defined in the GOLDKEYS.CFG file, where you can also find +several examples. + +By using the word "Auto" as , you can even define a +special macro which will be automatically executed when you start +GoldED. + + +Keystacking is a special form of auto-macros. You simply specify a +bunch of keys to be "stacked" in the (special internal) keyboard +buffer for sequential execution. + +You can either specify a default set of keystacking in the .CFG +configuration file, or override any default keystacking by typing the +keystack definitions at the GoldED commandline or the GEDCMD +environment variable. + +See the Key Reference chapter for a list of the key symbols you can +use in macros and keystacking. + +#page +#--------------------------------------------------------------------- +#chapter Key Reference + +Below is the list of key symbols recognized by GoldED for +keyboard/macro definition and keystacking. + +Unshifted function keys + + F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 + +Shift-function keys + + #F1 #F2 #F3 #F4 #F5 #F6 #F7 #F8 #F9 #F10 #F11 #F12 + +Alt-function keys + + @F1 @F2 @F3 @F4 @F5 @F6 @F7 @F8 @F9 @F10 @F11 @F12 + +Ctrl-function keys + + ^F1 ^F2 ^F3 ^F4 ^F5 ^F6 ^F7 ^F8 ^F9 ^F10 ^F11 ^F12 + +Alt-Numbers + + @0 @1 @2 @3 @4 @5 @6 @7 @8 @9 + +Alt-Letters + + @A @B @C @D @E @F @G @H @I @J @K @L @M + @N @O @P @Q @R @S @T @U @V @W @X @Y @Z + +Ctrl-Letters + + ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M + ^N ^O ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z + +Insert/Delete + + Ins ^Ins @Ins + Del ^Del @Del + +Home/End + + Home ^Home @Home + End ^End @End + +Page up/down + + PgUp ^PgUp @PgUp + PgDn ^PgDn @PgDn + +Cursor left/right + + Left ^Left @Left + Right ^Right @Right + +Cursor up/down + + Up ^Up @Up + Down ^Down @Down + +Misc other keys + + Esc ^Grey* Key5 Space Tab #Tab @Tab BackSpace ^BackSpace + @BackSpace Enter ^Enter @Enter + +Note that some of the Alt-keys, especially the cursor-related keys and +the F11/F12 keys, are "extended" keys normally only available on +systems with an extended keyboard bios. However, GoldED uses a few +tricks to make some the extended keys available on non-extended +systems. + +#page +#--------------------------------------------------------------------- +#chapter Language Definition + +GoldED allows you to almost completely redefine the language dependent +text in the program. + +The language dependent text in GoldED is defined in the plain ASCII +text GOLDLANG.CFG file. + +See the example language file for the actual method and format of +language redefinition. + +If you are planning to translate the text in GoldED, you should also +look into the definition of the help screens. + +You do not need permission from the author before announcing or +distributing your own modified language files. + + +Date/Time Substitution Codes + +A few of the language texts can contain special date/time substitution +codes. The keywords for those are: MS_DateTimeFmt, MS_DateFmt, +MS_TimeFmt and ST_StatuslineTimeFmt. + +Here are the valid substitution codes: + + %a Abbreviated weekday name (Mon, Tue, Wed, ...). + %A Full weekday name (Monday, Tuesday, Wednesday, ...). + %b Abbreviated month name (Jan, Feb, Mar, ...). + %B Full month name (January, February, March, ...). + %d Day of month (01-31). + %e Day of month, with leading space for single digits (1-31). + %E Day of month (1-31). + %H Hour (00-23) (24-hour clock). + %I Hour (01-12) (12-hour clock). + %j Day of the year (001-366). + %m Month (01-12). + %M Minute (00-59). + %p AM or PM according to 12-hour clock. + %S Second (00-59). + %U Week number (00-52) where sunday is first day of the week. + %w Weekday (0-6) where 0 is sunday. + %W Week number (01-53) where monday is first day of the week. + %y Year without century (00-99). + %Y Year with century. + %% Character '%'. + +The %a, %A, %b and %B codes substitute to the current language setup +loaded using the LOADLANGUAGE keyword. + + +*** NOTE *** + + +In the continuing development of GoldED, it is impossible to +completely maintain backward compatibility of the language format or +the text defined there. New features may add and/or obsolete some +definitions, or may change the format of others. + +The existing language file may contain definitions which are already +obsolete, but which I haven't had time to search for and remove, as +well as there may be some texts in GoldED which are not yet definable. +All this will of course be corrected in future versions. If you find +inconsistencies, please report them, because I may have overlooked +them. + +#page +#--------------------------------------------------------------------- +#chapter Message Kludge Lines + +Kludge lines are special control lines, that begin with a ^a (ASCII 1) +as the first character of the line, followed by a unique identifying +name and the relevant control information. + +GoldED is aware of a lot of these kludges, and supports a number of +them, if you want to have them inserted in your messages. + +Some kludges are useless junk and more or less commercials for this +and that software, but a few are useful for miscellaneous purposes. In +the following, I will list (some of) the known and supported kludges, +and a short description of what they are used for. + +ACUPDATE: + + This kludge is a feature of Squish 1.10: Message Broadcast + Modify/Delete. Read the docs for Squish 1.10 for details. + +AREA: + + This is not really a kludge, and it doesn't begin with a ^a, but I + included it on the kludge list because it sometimes turned up in + echomail areas where it should have been stripped off by the mail + tosser. + +CC:
 + + When GoldED produces carbon copies, it adds to each message a full + list of the persons who get a copy. One version of this list is + hidden behind the CC: kludge. + +CHARSET: + + Proposed in FSC-0050 and FSC-0054, this kludge is an attempt to + find a solution to the problem of the high-bit characters (like + the IBM PC vs Amiga vs Mac etc. national chars) in messages. + GoldED can recognize, use and generate this kludge. + +CHRC: + + Proposed in FSC-0054, this is a kludge for changing fonts, + underlining and other stuff. + +CHRS: + + Alternative FSC-0054 version of the CHARSET kludge. + +DESTADDR: + + This one is not proposed anywhere, but it looks like it gives the + address of the intended recipient. GoldED takes the address for + the dest field. + +DOMAIN  + + Proposed in FSC-0038, this tries to solve the problem of mail + crossing domain boundaries. GoldED takes both addresses. + +EID: [replycrc16]  + + Proposed in FSC-0031, this is used for dupe checking and reply + linking. The EID is today generally considered as garbage, but a + lot of older mail processors such as QMail still generate it. + +ENC: + + Signifies that the message contains encrypted data. GoldED will + add this kludge if it detects that the message has been encrypted + with PGP. + +EOT: + + End Of Text. See SOT. + +FLAGS  + + Proposed in FSC-0053, this is a special netmail kludge used by the + FrontDoor and D'Bridge mailers and the IMail mail processor. It + provides extra attributes not found among the standard attributes + in the normal message/packet headers. GoldED uses and generates + this kludge, if you set the attributes. + +FMPT  + + Defined in FTS-0001, this tells the Point number of the + originator. Netmail only. GoldED can generate this line. + +FWDAREA  + + FSC-0092: The original area in forwards. See USEFWD and FSC-0092 + for a more detailed description. + +FWDDEST  + + FSC-0092: The original To-aka in forwards. See USEFWD and FSC-0092 + for a more detailed description. + +FWDFROM  + + FSC-0092: The original From-Name in forwards. See USEFWD and + FSC-0092 for a more detailed description. + +FWDMSGID  + + FSC-0092: The original MSGID in forwards. See USEFWD and FSC-0092 + for a more detailed description. + +FWDORIG  + + FSC-0092: The original from-aka in forwards. See USEFWD and FSC-0092 + for a more detailed description. + +FWDSUBJ  + + FSC-0092: The original subject in forwards. See USEFWD and FSC-0092 + for a more detailed description. + +FWDTO  + + FSC-0092: The original TO-field in forwards. See USEFWD and FSC-0092 + for a more detailed description. + +GATECHK: + + Some sort of gating kludge? Don't know what it's for. + +GIF: + + Invented by Henk Wever and used in his Dutchie software. The + filename (which does not have an extension) indicates a .GIF + picture of the author of the message. If you have the GIF file on + your system, you can setup an external utility to view the gif at + the press of a key. + +GROUP: + + I think this one comes from stray Groupmail messages. Similar to + the AREA: kludge. + +I51 (no parameters) + + Proposed in FSC-0051, this indicates that the message text + conforms to the ISO 8859-1 (LATIN-1) character set, and may + contain certain escape codes. The ISO 8859-1 set is used in Amiga + and Windows 3.xx. GoldED can recognize, use and generate this + kludge. + +INTL  + + Defined in FTS-0001, this one solves the problem of crossing Zone + boundaries. Netmail only. GoldED can generate this line. + +MSGID:  + + Defined in FTS-0009, this is a method for unique identification of + a message. It can be used for dupe checking and replylinking. + GoldED can generate this line. + +MSGTO:  + + This one is not proposed anywhere, but it looks like it gives the + address of the intended recipient. GoldED takes the address for + the dest field. + +Original:  + + Generated by the FrontDoor FM editor when it produces carbon + copies. + +PATH:  + + Defined in FTS-0004, this is a valuable tool for finding dupe + links and other structural faults in the net structures. + Unfortunately the list of nodes is 2D (net/node), and this creates + problems when exporting echomail across zones. + +PTH:  + + Not yet a FSC (or is it?), this is a 5D-version of the PATH + kludge, which sticks to the top of the msg. + +PID: [serialno] + + Proposed in FSC-0046, this takes a stab at the tearline abuse, and + puts "safe" information about the first mail processing software + in the line. This could be message editors, mail scanners and + other stuff. + +Realname:  + + This kludge was probably born in Russia because of some software + was not able to properly handle high ASCII in headers. Name should + be written in national codepage. Otherwise it lose any sence. + I don't know any software that generate this kludge. + +RFD:  + + Received For Distribution. A kludge inserted by one of the file + announcement programs. + +REPLY:  + + Defined in FTS-0009, this is the MSGID: counterpart. When replying + to a message with a MSGID:, the MSGID: of the original is renamed + to REPLY:. + +RID: + + Unknown kludge which looks suspiciously like the EID. + +ROUTE  + + Specifies route path. Currently supported by Unimail and S\Tosser. + +SEEN-BY:  + + Defined in FTS-0004, this is a tool for finding dupe links and + other structural faults in the net structures. Depending on the + mail tosser, the seen-by's may or may not have a preceding ^a + character. Unfortunately the list of nodes is 2D (net/node), and + this can create problems when exporting echomail across zones. + +SN: + + Serial number inserted by the Dutchie message editor. + +SOT: + + Start Of Text. See EOT. + +SPLIT: + + Defined in FSC-47. A method for splitting large msgs so that some + mail processors don't choke on them. + + +TCL1:, TCL2:  + + Old obsolete swedish dupecheck/replylink kludge. + +TID: + + Tosser ID. Similar to the PID, but specifically for mail + processors. + +TOPT  + + Defined in FTS-0001, this tells the Point number of the + destination. Netmail only. GoldED can generate this line. + +TZ  + + Specifies the time to *add* to the header time to get the UTC + (Universal Time Coordinated) time. Generated by newer versions of + the TrackMail netmail processor. + +TZUTC + + See TZ. GoldED can generate this line. + +Via:  + + Routed netmail messages usually gets a Via line for each node it + passes through. This can be used for tracing faults in the netmail + routing structure. + +XID: + + Unknown kludge which looks suspiciously like the EID. + +#--------------------------------------------------------------------- +#end +#--------------------------------------------------------------------- diff --git a/manuals/gold_usr.txt b/manuals/gold_usr.txt new file mode 100644 index 0000000..39a214c --- /dev/null +++ b/manuals/gold_usr.txt @@ -0,0 +1,2543 @@ +#--------------------------------------------------------------------- +# GoldED Users Guide Manual +# $Id$ +#--------------------------------------------------------------------- +#manualfile GOLDUSR.TXT +#pagelength 60 +#pagewidth 80 +#leftmargin 8 +#rightmargin 2 +#--------------------------------------------------------------------- + + + + + + + + + + + + + + + + + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + + Ú¿ Ú¿ Ú¿ + ³³ ³³ ³³ + ³³ ³³ ³³ + ³³ ³³ ³³ + ÚÂÄÄ¿ ÚÂÄÄ¿ ³³ ÚÂÄÄ´³ ÚÂÄÄ¿ ÚÂÄÄ´³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³ÃÄÄÁÙ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ + ³³ ³³ ³³ ³³ ³³ ³³ ³³ ³³ Ú¿ ³³ ³³ + ÀÁÄÄ´³ ÀÁÄÄÁÙ ÀÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ ÀÁÄÄÁÙ + ³³ + ³³ + Ú¿ ³³ GoldED 3.0.0 + ÀÁÄÄÄÄÄÄÁÙ ÄÄÄÄÄÄÄÄÄÄÄÄ + + + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ + + + + Users Guide Manual + + + Program and manual written by Odinn Sorensen + + + Copyright (C) 1990-1998 by Odinn Sorensen + +#page +#--------------------------------------------------------------------- +#header +#--------------------------------------------------------------------- +#heading ______________________________________________________________________ +#heading +#heading
+#heading ______________________________________________________________________ +#heading +#--------------------------------------------------------------------- +#footer ______________________________________________________________________ +#footer +#footer GoldED Users Guide, Page +#--------------------------------------------------------------------- +#tocbegin +#chapter Table of Contents +#tocline ...................................................................... +#tocindent 4 +#tocpagenumber i +#toc +#tocend +#--------------------------------------------------------------------- +#pagenumber 1 +#chapternumber 1 +#--------------------------------------------------------------------- +#chapter Notes About This Manual + +The organization of this manual is not so good, sorry about that. + +If you find spelling, grammatical or factual errors, please let me +know. + +If you think the wording is bad or confusing in some parts, please +send me your improved version of the parts. + +If you would like to write entirely new chapters (especially for the +Users Guide), please do and send them to me. Screen shots may be +included, but should be edited to fit a 70 char wide page. + +I have limited time and would be very grateful for any help which can +improve the quality and usefulness of the manual. + +TO TRANSLATORS: This manual is produced from ASCII text files with +special codes and compiled to the release manual using a manual +compiler I wrote myself (gmanual). If you want to translate the GoldED +manuals to any language, please copy the manual source, translate the +copy and compile it using gmanual for distribution to others. +You must also contribute your translated manual source to the +community for futher use and improvement. + +NOTE: The manual source should be transformed into SGML, so we can get +ASCII, HTML, PostScript or whatever versions. Any takers? + +Odinn Sorensen, The GoldED Author. + +#page +#--------------------------------------------------------------------- +#chapter Legal Notes + +GoldED and the Goldware Utilities are covered by the GNU General +Public License (GPL). For details see the file COPYING. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#page +#--------------------------------------------------------------------- +#chapter Support and Development Philosophy + +Besides working on GoldED, I am studying to become an electrical +engineer. For this and other reasons, I don't have much time for +individual support, particularly not for helping beginners with setup +problems etc. Please seek help in the support conferences on FidoNet +or Internet or ask your friends. + +I will do my best to be available in the support conferences, but I +can't guarantee replies to all questions. There may even be times when +apparently urgent or important questions seem to be ignored. Please +don't take this personally. It may be that I simply have no time in +those periods. And later when I do have time, it may be several weeks +later and I may decide to skip lightly over the hundreds of messages +that piled up in the echoes. In that case, try to repeat your question +regularly and eventually you should be able to get a reply from me. + +GoldED was a closed-source user-supported shareware program until +november 1998, when it was transformed into an open source GPL'ed +program with myself as primary maintainer and final judge of official +patch acceptance. In addition to myself, there is a core team of +developers, currently consisting only of Dirk A. Mueller, but +hopefully soon others, which have full access to committing changes +directly to the development CVS tree. + +I was very happy about every single registration I got in the past, +because it gave me incentive to keep on working on GoldED, and +gave me additional economical freedom - something which is important +to anyone who studies without other economical backing. In the summer +of 1998 I was fortunate enough to get a job (currently as part of my +studies, but will likely continue for quite some time), which gave me +economical independence of shareware income from GoldED. This gave me +the opportunity to fulfill a promise I made myself long ago - that I +would not allow GoldED to die, just because I lacked the time to +support it properly. I would rather release the source code and let +interested users carry it onwards at their own pace. So after careful +examination of the variety of open source compliant licenses out +there, I chose GPL and LGPL. + +Thank you for your support and understanding. + +Odinn Sorensen. + +#page +#--------------------------------------------------------------------- +#chapter Entering Messages + +The process of entering a message deserves some description, because +there are a number of steps that may be a bit hard to figure out +directly. + +You start a message by using one the following commands: + + Key Command keyword Description + + Ins READnewmsg Start a blank new message. + Alt-Q READquotemsg Quote-reply the current msg. + Alt-G READcommentmsg Quote-reply the current msg to TO person. + Alt-N READmovequotemsg Quote-reply in another area. + Alt-B READmovecommentmsg Quote-reply in another area to TO person. + Alt-R READreplymsg Reply to current msg, but don't quote. + +The first thing that happens is that the header display comes to life, +and allows you to change the names and addresses of destination and +origination. In netmail areas, the userlist lookup feature is in +effect for the destination name field. You move around in the header +with the arrowkeys. Pressing or moves to the next field. +Pressing in the subject field or anywhere, ends +the header editing. Pressing drops the message. While editing +the header, you can use the Alt-keys to toggle message attributes. + +After the header editing is done, a menu appears, allowing you to +change the message attributes, origin, template, start the internal or +external editor or quit it. + +When you select to start the editor, the template is processed and +prepared for use. + +Safely back from the editor, you are presented with a menu where you +can select to save the message, drop the message, continue editing, +view the message, change origin or ROT13 crypt it. + +#page +#--------------------------------------------------------------------- +#chapter Userfile Considerations + +GoldED will by default always use the first entry in the userfile and +the first lastread in the lastread file(s). + +In older versions GoldED would seek through the userfile for your name +and use the lastread pointers that corresponded to the index of the +userfile entry. This would normally work, but under some +circumstances, GoldED might fail to find your name and therefore add +you to the userfile. This could cause lastreads to suddenly appear to +be reset to the first or last message in all areas. + +The solution of always using the first lastread is effective for +single-user setups, but for users sharing the same msgbase using +GoldED, each user MUST setup different user numbers if they want to +keep their lastread pointers separate. These keywords are used to set +the lastread pointer user number: + + EZYCOMUSERNO + FIDOUSERNO + GOLDBASEUSERNO + HUDSONUSERNO + PCBOARDUSERNO + SQUISHUSERNO + WILDCATUSERNO + +There is no JAMUSERNO, because the JAM format is cleverly designed +to be independent of userfiles. + +The defaults to 0 (zero). Set it to 1, 2, 3 etc. for each +additional user that shares the same msgbase using GoldED. +Alternatively, set to -1 (minus one), which will tell GoldED +to return to the old method of searching the userfiles to get the +lastread indexes. + +#page +#--------------------------------------------------------------------- +#chapter Using the Search Functions + +The search function is activated using the Alt-F (header and body) or +Alt-Z (header only) keys. This will bring up a popup entry field where +you can enter several strings, separated by the '|' search string +separator character like this: + + Odinn|GoldED + +By default, GoldED searches forward (next messages), but by preceeding +the search string with a '-', the search goes backwards (previous +messages). + +Besides the backward search, there are a number of other search +command characters. Here is the complete list: + + - Search backward. + + Search forward. (Just for completeness). + < Search the From: field. + > Search the To: field. + : Search the Subj: field. + = Case-sensitive search. + ! Reverse - Stop/mark when the search string(s) are NOT found. + & Separator - Reserved for future use with logical "and" searches. + +By default the '<', '>' and ':' search commands are enabled, so that +GoldED searches all header fields. However, when one of these options +are actually used, the search is limited to those only. + +Examples: + + Odinn Searches in From: and To:, but not Subj:. + :tagline Search for "tagline" in the Subj: field only. + +The search command characters are stripped before the search is +started. If you need to search for a string that begins with a search +command character, you must precede it with the search string +separator, like this: + + -|++ Search for the string "++". + +All this also applies to the marking search function (Alt-S). + +#page +#--------------------------------------------------------------------- +#chapter Using External Editors + +Like all message editors that allows the use of external text editors +for writing messages, GoldED must deal with the problem of +free-flowing text paragraphs versus hard-cr-terminated lines. + +Most text editors terminate *all* lines with a carriage return (CR, +13d, 0Dh). Unless you use a fairly short right margin in the text +editor, those lines can be very annoying to quote if the quotemargin +is shorter. This usually results in "ragged" quotes, with a long +quoteline alternating with a short leftover. This looks bad, and +requires a lot of work to edit to a respectable shape. + +To solve this problem, GoldED treats the file from the text just as if +text blocks doesn't have any hard-cr's in them - it "reflows" the +text. Of course, this immediately creates another problem: If you +include a cut from a log file, source code, table or other stuff that +*requires* the text block to be aligned with itself. Those blocks +would become scrambled and unreadable. + +GoldED recognizes a special control string, that tells the reflowing +code to put hard-cr's on single lines or groups of lines. You define +the string with the keyword "Hardline" in the configuration file. Here +is an example of the use of the hardline string (in the example "<<"): + + << + ==== Log Cut ==== + + 22.24.31 Event 0-@ + - 22.24.42 Preparing outbound mail + = 22.58.47 RING + = 22.58.55 CONNECT 2400 + + 22.59.02 Incoming call at 2400 baud + ==== Log Cut ==== + << + +In this example, the hardline string on the lines before and after the +cutting tells the reflower that all those lines must the hard-cr +terminated. The hardline string must be the only characters on the +line, and it must be placed on the *first* position. The reflow code +looks for . The hardline string works as a "toggle". + +The hardline string also has another use: If you put the string as the +last characters on a line, that line will also be hard-cr terminated. + +Example: + + Greetings...<< + Odinn Sorensen<< + +The last << in this example was not really necessary, because a blank +line always ends the preceding line or paragraph with a hard-cr. In +any case, the hardline string is stripped off before the message is +saved. + +Some lines are by definition always hard-cr terminated, and does not +need hardline strings. Those lines are quoted lines and control lines +such as kludges, tearlines and originlines. In addition, three +identical characters at the beginning of a line also terminates the +preceding paragraph. + +#page +#--------------------------------------------------------------------- +#chapter Quote Reflow + +When you quote a message that already contains quoted lines, those +lines may be too long for your quotemargin. Most message editors would +then just cut a bit off the end and put it on a line below. GoldED +does it differently - it determines the quotestring of the line, and +then "reflows" all the following lines with the same quotestring and +puts the quotestring back on the reflowed lines. This usually works +great and looks good. It can also fail miserably in some +circumstances. + +The reflowing is in effect in both the message displaying and in +quoting. If you want to observe the effects, try executing the +READdecreasemargin or READincreasemargin commands (they don't have any +default key assignments though). + +#page +#--------------------------------------------------------------------- +#chapter Carbon Copy and Crossposting + +Carbon Copying + +Carbon copy (CC) is a way to send the same message to a number of +people without the trouble of manually entering and copying a message +for each of them. The CC works only in netmail or local areas. You can +send any message, including fileattaches (in netmail) with the CC +function. + +Carbon copies are created by putting the string "CC:" followed by one +or more names or addresses, separated by commas, on one or more lines +at the beginning of the message. The names and addresses must follow +the same rules as when using the lookup function in the netmail +header. + +Example: + + CC: 16, Joergensen, #236/512 + +If you put a "#" in front of a name or address, that node will be left +out of the list, but will still receive a carbon copy. + +You can also use address macros (see the NAMESFILE keyword) instead of +names or addresses. + +If you often send carbon copies to the same people, it can get a bit +tedious to type (and remember) every time. Therefore you can also +specify a file with the names and addresses: + + CC: @TESTERS.LST + +Files names and addresses can be mixed on the same line. The lines in +the file must be the same format as above. No nesting is allowed: You +can't specify files within files. + +When you save the CC message, GoldED will scan the message text to +find and process the CC: lines. When this is done, a menu will pop up +and allow you change the format of the CC: lines, the attributes of +the CC messages or drop the copies. + +When processing the CC list, GoldED will check each node in the +nodelist and pop up the nodelist browser in case of more than one +match or if the node was not found. + + +Crossposting + +Crosspost is similar to Carbon Copy, except that instead of sending +copies to a list of persons, it posts copies of a message in several +different conferences. Typical usage is announcement of files, vital +BBS information and other general interest info. + +To crosspost a message is simple - just add lines in this format: + + XC: [echoid] [..] + +The "XC:" must be the first three characters on the line. The +must be valid echoid's defined in GoldED. Example: + + XC: GOLDED, NEWFILES_R23.PRO, ENET.SOFT + +This would produce the following output in the message: + + * Crossposted in GOLDED + * Crossposted in NEWFILES_R23.PRO + * Crossposted in ENET.SOFT + +And post it in the conferences. + +Please moderate your use of this feature - it adds duplicate +information to the mail flow, and excessive use may be frowned upon by +cost-sensitive individuals. + +TIP: If you want to keep copies of your messages in a separate +"outbox" echo, add this line to your message template(s): + + xc: #@cecho, #outbox + +This will automatically crosspost your msg to the OUTBOX area (you +must define or have an area with that echoid). The '#' tells GoldED +that you don't want the crosspost to be noted in the msgs. The +"@cecho" is a template token which is replaced with the current +echoid. + +The only drawback to this tip is that there is no way to see what area +the original msg was posted in when looking at the msgs in the OUTBOX +area. + +#page +#--------------------------------------------------------------------- +#chapter Using the Tagline Support + +GoldED directly supports the popular taglines, which look something +like this in messages: + + ... tagline + --- GoldED 2.51 + * Origin: whatever (2:236/77) + +Taglines are usually one-liner jokes or wisdom or whatever. They serve +absolutely no technical function and are considered by some to be +waste of diskspace and modem time. In some conferences, they may even +be forbidden by the moderator, so if you want to use this feature, +check the conference rules first! + +The tagline support in GoldED is currently not very advanced. You can +define some global taglines and manually select them from a menu, like +you can with origins. Taglines can also be defined in random system +groups, where they will be chosen randomly. For those with existing +tagline collections, you can specify the filename of the tagline +collection. Then a random tagline will be picked from the collection. + +Taglines in messages are detected and displayed in a different color +(definable with COLOR READER TAGLINE). + +Here are the keywords for tagline support: + + TAGLINE or @ Defines a tagline or file + TAGLINECHAR Defines the tagline character + TAGLINESUPPORT Disable internal tagline support. + +If you define taglines globally, GoldED automatically adds extra menu +items to the EDITMENU and EDITSAVEMENU, to allow you to manually +select the tagline either before entering a message or when saving it. + +Like for origins, it is also possible to change the default tagline by +using the READchangetagline command. Default key assignment is Ctrl-I. +Example for GOLDKEYS.CFG: + + ^I READchangetagline + +Future plans for the tagline function include: Command to "steal" +taglines. Tagline collection file browser. Tagline "filters". Please +note, however, that tagline features are generally low priority. So +don't hold your breath. + +#page +#--------------------------------------------------------------------- +#chapter Using the ISO 8859-1 ("Latin-1") charset + +This chapter describes how to setup GoldED to use the ISO 8859-1 +character set in all or selected mail areas. + +The ISO 8859-1 character set seems to be the preferred standard for +accented (highbit) characters in the Internet. It is also basically +the same character set used in MS-Windows (code page 1252) and the +Amiga. + +Add the following lines to the Random System groups you want to setup +charset translation for. They can also be used globally in the main +configuration if you want to ISO 8859-1 to be the default character +set for all your mail areas. + + XLATIMPORT LATIN-1 + XLATEXPORT LATIN-1 + +XLATIMPORT/EXPORT are used to translate characters to and from the IBM +PC 8-bit (above ASCII) character set. + +The following lines need to be added to the main configuration: + + XLATPATH + +If your codepage is CP437 or CP865, use these two: + + XLATCHARSET IBMPC LATIN-1 IBM_ISO.CHS + XLATCHARSET LATIN-1 IBMPC ISO_IBM.CHS + +Or if your codepage is CP850, use these three: + + XLATCHARSET CP850 LATIN-1 850_ISO.CHS + XLATCHARSET LATIN-1 CP850 ISO_850.CHS + XLATLOCALSET CP850 + +The two .CHS files must be present in the XLATPATH. You can find them +in the XLAT archive inside the advanced setup archive. + +GoldED will put a kludge "^aCHRS LATIN-1 2" or "^aCHARSET LATIN-1 2" +into your messages so that other mail readers can translate to their +native character set if necessary. + +That's it. + +#page +#--------------------------------------------------------------------- +#chapter Converting your highbit characters to ASCII + +If a conference moderator or network policy forbids the use of highbit +characters such as your national accented letters, you must configure +GoldED so that these characters are converted to acceptable ASCII. +Fortunately there are at least three ways of doing this with GoldED. + +Let's say that you want to convert the characters ’‘›† (the most +commonly used Danish national characters in codepages 865 and 850). + +You can convert the characters using EDITmacros by putting these lines +in the GOLDKEYS.CFG file: + + ’ EDITmacro "AE" + EDITmacro "OE" + EDITmacro "AA" + ‘ EDITmacro "ae" + › EDITmacro "oe" + † EDITmacro "aa" + +An alternative way of doing this is by using the EDITCOMPLETION +keyword like this in GOLDED.CFG: + + EDITCOMPLETION "’" "AE" + EDITCOMPLETION "" "OE" + EDITCOMPLETION "" "AA" + EDITCOMPLETION "‘" "ae" + EDITCOMPLETION "›" "oe" + EDITCOMPLETION "†" "aa" + +If you use one of these two methods to convert your highbit +characters, that's it. There is no way to switch it to allow the +highbit characters in some areas. + +The best method to convert characters is by using the character +translation system and enabling it in just those areas where it is +required. Setting this up is a bit more elaborate. When the character +translation system is in effect, you simply enter your message using +your national highbit characters. Then when you save the message, +GoldED automatically converts it to ASCII. + +Add these lines in GOLDED.CFG: + + XLATPATH + XLATCHARSET IBMPC ASCII IBM_ASC.CHS + +And add this line either globally in GOLDED.CFG or in specific groups +in the random system: + + XLATEXPORT ASCII + +The IBM_ASC.CHS file can be found in the XLAT.ZIP archive within the +manual and advanced cfg archive. + +It should be noted that the IBM_ASC.CHS translation table converts +from codepage 437 (actually 865) to ASCII. If your normal codepage is +850, you should use the following XLATCHARSET instead: + + XLATCHARSET CP850 ASCII 850_ASC.CHS + +You will also need this line: + + XLATLOCALSET CP850 + +The XLATLOCALSET keyword tells GoldED which codepage your computer is +configured to use. + + +#page +#--------------------------------------------------------------------- +#chapter Encrypting Messages + +GoldED allows you to en/decrypt messages encoded with the ROT13 +encryption method. ROT13 is very simple: It just swaps the letters +"A-M", "a-m" with "N-Z", "n-z" and vice-versa. + +ROT13 is mostly used in Internet newsgroups where it is used as a +"spoiler warning", so that game solutions, joke punchlines and other +stuff is not read by accident. In those networks, most message readers +have ROT13 de/crypting capabilities. + +In FidoNet, not all message readers have ROT13 capability, and the +current policy (Policy 4) states: + + 2.1.4 Encryption and Review of Mail + + FidoNet is an amateur system. Our technology is such that the + privacy of messages cannot be guaranteed. As a sysop, you have the + right to review traffic flowing through your system, if for no + other reason than to ensure that the system is not being used for + illegal or commercial purposes. Encryption obviously makes this + review impossible. Therefore, encrypted and/or commercial traffic + that is routed without the express permission of all the links in + the delivery system constitutes annoying behavior. + +You will be able to encrypt your messages with ROT13, but you should +not use the crypting facility of GoldED, unless your network allows +it, and *never* in international echoes. + +See also the chapter about how to setup GoldED with PGP. + +#page +#--------------------------------------------------------------------- +#chapter Using the UUDECODE feature + +GoldED contains a built-in uudecode feature. It is keycommand +READuudecode, which defaults to Ctrl-X. + +The uudecoder in GoldED is based on (but heavily modified from) some +very old ('88), but good, C source (available as UUENUUDE.ZIP on my +system), which claims to be based on the Berkeley original. + +No error checking is done during the uudecode. + +GoldED currently cannot handle uuencoded data which is split in +multiple sections and/or multiple messages. Only uuencoded data is +supported, not MIME Base64 or other encodings. + +#page +#--------------------------------------------------------------------- +#chapter Using the UUENCODE feature + +GoldED contains a built-in uuencode feature, which is available when +importing a file in the internal editor. + +To uuencode a file while importing it, simply put a '#' character in +front of the filename. + +Example: #WHATEVER.ZIP - Will import as: + + begin 644 WHATEVER.ZIP + [uuencoded data] + end + +NOTE: This is a very simple implementation of uuencode. It cannot +split large files over several messages. The file mode number 644 is +hard-coded and has nothing to do with the actual file mode. + +WARNING: Due to memory constraints, the standard 16-bit DOS version of +GoldED is usually not able to deal with messages much larger than +about 10-16k. You can very quickly reach that size when uuencoding +files. For this reason, you should not use this feature unless you are +running one of the 32-bit versions (DOS-386, OS/2 or Win32). + +GoldED currently only supports the uuencoding type, not MIME Base64 or +other encodings. + +#page +#--------------------------------------------------------------------- +#chapter Nodelist Browse and Lookups + +When you write a netmail message, you must know the name and net +address of the recipient. Unless you have a remarkable memory, this +information can be a bit hard to remember. Therefore GoldED supports +several different nodelist indexes: GoldNODE (a proprietary format), +FrontDoor, Version 7 and FIDOUSER.LST. + +When you enter a name or address in the header (the TO: field) and +press , GoldED looks in the nodelist index to find the missing +data. You can enter the address in the name field. Names to be +searched for must be entered last name first (because of the way the +index is structured). If you enter a partial name or address, GoldED +will find the closest match. Addresses can be entered in short form, +based on the current AKA, like .3 for the address of your third Point, +or 33 for node 33 in your net. + +Before the nodelist is searched, the list of address macros are first +scanned, and if a match is found there, the information there is used +instead. + +When GoldED has found a match, it looks a bit further to see if there +are more matches. If not, the matching data is inserted in the header, +and you can continue editing. If more than one match was found, it +starts the nodelist browser. Here you can browse around and find the +correct destination node. When found, you select it with . The +full name and address of the node you selected is then placed in the +appropriate fields in the header. Pressing in the browser quits +it without inserting any node information. While in the browser, you +can press to switch between name and address lookup. + +The list of nodes in the browser is sorted differently, according to +what you entered. If you entered a name, the list is sorted +alphabetically by last name. If you entered an address, the list is +sorted ascending by address. + +The nodelist browser can also be accessed in other ways. The keys F10 +and Shift-F10 brings up the browser at the FROM and TO names (nodes) +respectively, to let you inspect their nodelist data. It's quite +handy, you will wonder how you could do without it - I did :-) + +The nodelist lookup feature can also be used when in the internal +editor, but an even more useful key is available there. By pressing +Alt-L, the browser will pop up for the name or address at the editor +cursor position! + +#page +#--------------------------------------------------------------------- +#chapter User Database Lookup + +GoldEd has a special user database lookup feature for BBS sysops. + +In Hudson, Ezycom, Squish (and *.MSG, if you are using Maximus) type +areas, GoldED can perform an additional type of name lookup, using +wildcards. + +This form of lookup is triggered by using DOS/4DOS-style wildcard +characters in the name you want to lookup. Examples: + + To: Joe* Finds any name beginning with "Joe". + To: *Blow Finds any name ending with "Blow". + To: Od?n* Finds "Odinn", "Oden" etc. + +Depending on the size of your user database and the speed of your +computer, the lookup may take a little while. + +As currently implemented, this user database lookup is only good for +simple one-shot lookups - you can't bring up a browser to pick the +user, or see his/hers other user data. + +#page +#--------------------------------------------------------------------- +#chapter Marking Messages + +GoldED has a message marking system, which allows flexible +manipulation with selected messages. + +You can either mark messages manually one by one using the +READtogglemark command , or use the READmarkingoptions menu +. With the marking menu, you can for example mark all messages +in a particular thread (replychain), or all messages that match a +certain string or a number of other criteria. + +When you have marked the messages, you can then Copy, Move, Delete or +Write them. Or you can switch to reading only the marked messages. + +The marks stay in position until removed (unmarked) or you exit +GoldED. Marks are kept even if you leave the current area and do +business in another for a while. + +Another, more volatile, form of mark is the "bookmark". Bookmarks can +be used for returning to a certain position after a stroll out a long +reply chain and stuff like that. There is only one bookmark, and it is +reset when you leave the area. Using the Find function leaves a +bookmark at the current message. + +#page +#--------------------------------------------------------------------- +#chapter The File Request Feature + +Often when you see a msg where new files are announced, you wish you +could simply press a key and select files to request. Well, with +GoldED you can! + +The file request function (default key Ctrl-F) will scan the current +message and present you with a list of the requestable files it found. +GoldED will even show the file descriptions if it can find one. + +You select the files by toggling marks with the Space key. A '+' will +show in front of the selected files. The selections can be discarded +by pressing Esc. When done with the selections, press Enter to +continue. + +Now the destination area must be selected from the list. You have to +pick a netmail area of the *.MSG type, since the Hudson and Squish +netmail areas are currently not supported by most mailers today. + +After selecting the area, check that the header data (TO name etc) is +correct. You can now go on to perhaps write a thank you note in the +accompanying msg, or you can save (empty) your msg immediately (if you +have the EDITMENU keyword set to Yes). + +At the moment you start editing the header, the filenames and +descriptions are written to a FILES.BBS in the INBOUNDPATH. This can +be very helpful if you are getting files for your own BBS and are +tired of inventing or finding descriptions for all those files.. The +fact that the FILES.BBS is written to disk before you even save you +msg, can be used to get "free" descriptions later from the response +msgs some mailers send back when you do a file request. + +There are currently a couple of limitations in the file request +function: + +* You can only request as many files as can fit in the subject line + of one msg. + +* GoldED recognizes several different types of file announcement + formats, but some may not be fully supported. This means that + legitimate descriptions may not be found by GoldED, or that some + files are not recognized as requestable. + +* If a msg does not conform to a known announcement format, it is + instead (actually it is _also_) scanned for a number of standard + archive extensions. These extensions are configurable with the + FRQEXT keyword, which comes pre-defined with many common file + extensions. Only one such file per line can be found by GoldED, + and only if it is "straight" - no spaces between name and + extension, and no "funny" characters in the filename. The + description is simply the rest of the line. + +#page +#--------------------------------------------------------------------- +#chapter Using the Personal Mail Scan feature + +GoldED can scan for your personal mail (messages addressed to the name +defined with the USERNAME keyword). + +NOTE: Personal mail scan is a very new feature in GoldED (introduced +in 2.50.Beta4) and is likely to have plenty of rough edges, quirks and +bugs. The current implementation is not set in stone. Please give me +your comments on any problems or suggestions for improvements. + +The personal mail scan feature can be activated in two different ways: + +1. Manually from the arealist using the personal mail scan menu on + Alt-P (keycommand AREAscanpm). The menu contains the same items + as the regular Alt-S scanning menu. Here you can scan all, marked, + current, matching or unscanned areas for personal mail. + +2. Automatically using the PERSONALMAIL keyword with the Startup + parameter. + +If personal mail scan is activated from the menu in the arealist, then +when the scan is completed, GoldED shows a window with a simple +statistic about the personal mail (xx mails found in yy areas). The +window will go away after a few seconds or by pressing a key. + +Areas with personal mail will be marked with a '+' after the message +count in the Msgs column. In the statusline, the exact number of +personal mails is shown for each area when you move the selection bar. + +To remove the personal mail mark from an area without reading the +mail, re-scan the area with the normal area scan (Alt-S). + +To read personal mail, simply enter an area marked '+'. GoldED will +automatically switch to "Read Marked" mode so that you only read the +personal mail. When you exit the area after reading your mail, GoldED +remembers the original lastread and sets it back where it was (this +will only work when in Read Marked mode with personal mail). + +You can automatically sort areas with personal mail to the top of the +arealist by adding the sort spec 'P' in front of your current +AREALISTSORT string. Example: AREALISTSORT PTUE. + +Only messages after the lastread are scanned. The scan ignores +messages that are marked received. + +The keywords AREAPMSCAN, AREAPMSCANEXCL and AREAPMSCANINCL work for +personal mail like the AREASCAN, AREASCANEXCL and AREASCANINCL do for +normal mail scans. + +The PERSONALMAIL keyword specifies options for the personal mail scan +feature. With it you can tell GoldED to automatically scan for +personal mail at startup and to look for mail to all your USERNAMES +(if you have more than one spelling of your name for example). + +Personal mail scan is currently only implemented for the JAM, Squish, +Hudson, Goldbase and PCBoard msgbase formats. Personal mail scan +support for *.MSG and Ezycom will be added in a future release. + +#page +#--------------------------------------------------------------------- +#chapter Using the Internet Features + +This chapter (which is not complete!) discusses how to use the +Internet compatibility features in GoldED, implementation details, +limitations etc. + +See also the "Using the SOUP feature" chapter. + +If you access Internet via a gateware running the GIGO gate program, +you should ensure that the gate operator has the following lines in +the GIGO HEADERS.CFG file: + +Allow_To: +Allow_From: +Allow_Newsgroups: +Allow_Subject: +Allow_Date: +Allow_Message-ID: +Allow_References: +Allow_In-Reply-To: +Allow_Organization: +Allow_MIME-Version: +Allow_Content-Type: +Allow_Content-Transfer-Encoding: +Allow_Sender: +Allow_X-Newsreader: +Allow_X-Mailreader: +Allow_X-To: + +These are the Internet RFC header control lines that GoldED can put in +your messages if you set INTERNETRFCBODY YES in your GoldED setup for +your Internet areas. + + + + +#page +#--------------------------------------------------------------------- +#chapter Using PGP as an External Utility + +This chapter describes how to can install PGP as an external utility +in the GoldED setup. The examples assume that PGP 2.3 or higher is +installed in the directory C:\PGP. + + +Add the following to your GOLDED.CFG: + + --- Cut --- + EXTERNUTIL 1 -nokeepctrl -wipe c:\pgp\pgp.exe +force -sa @tmpfile -u + "@oname" -o @file + EXTERNUTIL 2 -nokeepctrl -wipe c:\pgp\pgp.exe +force -sta + +clearsig=on @tmpfile -u "@oname" -o @file + EXTERNUTIL 3 -nokeepctrl -wipe c:\pgp\pgp.exe +force -ea @tmpfile + "@dname" "@oname" -u "@oname" -o @file + EXTERNUTIL 4 -nokeepctrl -wipe c:\pgp\pgp.exe +force -eas @tmpfile + "@dname" "@oname" -u "@oname" -o @file + EXTERNUTIL 5 -nokeepctrl -wipe c:\pgp\pgp.exe +force @tmpfile -o + @file -u "@dname" + EXTERNUTIL 6 -noreload c:\pgp\pgp.exe +force -ka @file -u "@dname" + EDITSAVEMENU Yes + EDITSAVEUTIL 1 "S PGP Sign the msg" + EDITSAVEUTIL 2 "l PGP Clear-Sign the msg" + EDITSAVEUTIL 3 "E PGP Encrypt the msg" + EDITSAVEUTIL 4 "p PGP Encrypt & Sign the msg" + EXTERNOPTIONS -Pause + --- Cut --- + +NOTE: Some of the configuration lines were split in two due to the +document margin. They must of course be on one line in the actual +GOLDED.CFG. + + +Add the following to your GOLDKEYS.CFG: + + --- Cut --- + F11 ExternUtil03 ; F11 -> Encrypt message + F12 ExternUtil05 ; F12 -> Decrypt message + #F12 ExternUtil06 ; Shift-F12 -> Add public key to keyring + --- Cut --- + +You need to have KEYBEXT Yes (the default) in GOLDED.CFG if you want +to use the F11/F12 keys. You can of course assign other keys, just +make sure they don't clash with already defined keys. + +The PGP commandlines are set up for multiple recipients, the TO: name +and your own FROM: name. Otherwise you would not be able to decrypt +your own msgs, and that could get a bit unpractical ;-) + +HOW TO USE IT: + +To sign, clearsign or encrypt a msg, simply select the appropriate +menu item in the save menu. Another method is described below. + +To decrypt an encrypted msg, Press F12 while viewing the msg in the +reader. After decryption, you can write the msg to disk/printer, reply +to it, copy it, etc. The decrypted text will revert as soon as you +move away from the msg, or after you perform any operation on it. To +make a decrypted msg permanent (saved to disk in decrypted form), use +the Change Msg command after decryption and then save the msg +immediately, or use the copy function if you want to keep the original +untouched.. + +One thing to be aware of, is that the encrypted msg text does NOT +contain kludges if it was encrypted from the EDITSAVEMENU. If you make +such a text permanent, you would loose the kludges. Currently the only +way to keep kludges in the encrypted text is to encrypt it "manually" +after saving it, using F11, Change Msg, save immediately. If you do it +this way, you should be careful in a multitask/network environment, +where a mail scanner could scan out the unencrypted msg before you get +a chance to encrypt it... I plan to fix this problem in a future +release. + +#page +#--------------------------------------------------------------------- +#chapter Using the GIF Features + +This chapter discusses how to use the GIF features in GoldED. + +If the GIF kludge is found in a msg, the @gif token is filled with the +filename from the GIF kludge. You can setup an external utility to +view the GIF (if you have the file) like this: + + (In GOLDED.CFG:) + EXTERNUTIL XX c:\utl\vpic.exe @gif + + (In GOLDKEYS.CFG:) + key ExternUtilXX + +If the GIF kludge is found, the text "[GIF:filename]" is added in the +lower-right corner of the header display so that you know that it is +there without looking in the kludges. + +If you don't have the GIF, you can file request it by hitting Ctrl-F +(the READfilerequest command). + +A note about the @gif token: It is replaced by the filename from the +GIF kludge, if any. If a GIFPATH is defined, the path is prepended to +the filename. A file extension is NOT added. This is so that you can +convert the .GIF's to a smaller format with a different extension. + + Example: EXTERNUTIL XX c:\utl\vpic.exe @gif.jpg + +You can configure GoldED so that it inserts the GIF kludge in your own +messages. See the GIF keyword for details. + +NOTE: The GIF kludge is not in wide use, and there is a very real +possibility that some people might be annoyed about "yet another +useless kludge" which increases the size of msgs (not much, max 16 +bytes). So I recommmend that you only use it in a few echoes and +perhaps in netmail, if at all. It might be a good idea to ask the +moderator of an echo before starting to use it in that echo. Use the +GIF keyword in Random System groups instead of globally. See also the +Message Kludge Lines chapter for information about the kludge. + +Planned: + +* A specific GIFVIEWER keyword and READgifviewer command instead of + having to use the external utility feature. GIFVIEWER would work + like EDITOR and SPELLCHECKER - there will not be a built-in + viewer. + +* A menu to select the GIF just like origins etc. + +#page +#--------------------------------------------------------------------- +#chapter Using the QWK features + +GoldED supports import and export of the QWK offline packet format for +BBS conferences and Internet e-mail and newsgroups. Using this +feature, you can use GoldED as QWK offline reader. + +A QWK packet consists of the files CONTROL.DAT, MESSAGES.DAT and +possibly a number of other files. GoldED uses only the two files +mentioned, other files are ignored. + +A QWK reply packet generated by GoldED consists of the file +.MSG, which contains the messages that you wrote with GoldED. + is the QWK BBS identification name of the BBS you use. + +GoldED currently doesn't support unpacking and packing of compressed +.QWK and .REP packets. You must unpack and pack your QWK/REP packets +manually or using a batchfile. + +When exporting message to QWK reply packetfiles, GoldED will +*overwrite* any existing reply packet (.MSG), so you should not +export until you are actually ready to upload your packet. + +After processing the CONTROL.DAT file, GoldED writes a file named +.GLD in the GOLDPATH. The file is used by GoldED to store the +relationship between conference numbers and conference names, for use +when later replying or entering new messages. For QWK export to work, +you must have previously imported a QWK packet so that the .GLD +file is created. + +The QWK import/export features are currently activated from a submenu +the arealist scan menu (Alt-S). The submenu item is only present if +QWKIMPORTPATH and/or QWKEXPORTPATH is defined. + +Below are the keywords that are relevant for the QWK support as +currently implemented: + + QWKIMPORTPATH + Path where incoming QWK packet files (CONTROL.DAT and + MESSAGES.DAT) can be found. + + QWKEXPORTPATH + Path where outgoing QWK reply files (BBSID.MSG) can be placed. + + QWKBADMSGS + Specifies the area where messages in unknown conferences are + put. If you get messages tossed here by accident, you must move + them manually to the correct area. If the badmsgs area is not + defined, the messages will silently disappear. Messages tossed + to the badmsgs area will have the control line + "AREA:_" at the top of the message. + + QWKCONFMAP ["]["] + Defines the mapping between the BBSID and conference names in + the QWK packets and the echoid name of the conference as + required by GoldED. You MUST define a mapping for every + conference that you subscribe to. If you don't, the messages + will be tossed to the area defined by QWKBADMSGS or disappear. + The is the name listed on line 5 in CONTROL.DAT after + the comma. The is the conference names listed on line + 13 and on alternate lines onwards in CONTROL.DAT. If a + conference name contains embedded spaces, the must be + enclosed in double quotes, like this: "Main Board". The area + must be already defined either in an AREAFILE or using + the AREADEF or AREA keywords. + + QWKTOSSLOG + Name of a file where GoldED puts the echoids of each area where + articles have been imported. The tosslog file is intended to be + used with a replylinker. If no path is given, it defaults to the + GOLDPATH. + + QWKREPLYLINKER + Commandline for a replylinker program to call after QWK import. + + QWKOPTIONS + Defines various options for the QWK support. + + INTERNETRFCBODY + Enable this in areas with Internet RFC headerlines at the top of + messages. See the "Using the SOUP features" chapter for details. + + CTRLINFO + Enables or disables tearline and/or origin in random system + groups. + +In areas where INTERNETRFCBODY is enabled, or RFC headers are present +as FTN kludges, GoldED will convert the RFC headers Message-ID, +References and In-Reply-To to MSGID and REPLY kludges, so that +MSGID/REPLY replylinkers can be used instead of dumb subject linkers. +GoldED will also get the full-length To/From/Subject lines and store +them in the messages instead of the short 25 character QWK fields. +Finally if the INTERNETGATE keyword is defined, GoldED will add the +FSC-35 kludges REPLYTO and REPLYADDR in the messages. + +Example setup in GOLDED.CFG: +(for Internet setup, see also the SOUP chapter). + + // Basic QWK setup + QWKIMPORTPATH C:\QWK\ + QWKEXPORTPATH C:\QWK\ + QWKBADMSGS BAD_QWK + + // Replylinking when using GEcho and Hudson areas: + QWKTOSSLOG C:\GECHO\IMPORT.HMB + QWKREPLYLINKER C:\GECHO\MBUTIL Link + + // Replylinking when using GEcho and JAM areas: + QWKTOSSLOG C:\GECHO\IMPORT.JAM + QWKREPLYLINKER C:\GECHO\MBUTIL Link + + // Replylinking when using Squish and Squish areas: + QWKTOSSLOG C:\SQUISH\QWKTOSS.LOG + QWKREPLYLINKER C:\SQUISH\SQUISH LINK -fC:\SQUISH\QWKTOSS.LOG + + // QWK conference mapping + QWKCONFMAP GOLDWARE GoldED GOLDED + QWKCONFMAP GOLDWARE "GoldED Beta" GOLDED.BETA + QWKCONFMAP GOLDWARE "BBS Users" BBS.USERS + QWKCONFMAP WHOKNOWS EMail EMAIL + QWKCONFMAP WHOKNOWS dk.chat DK.CHAT + QWKCONFMAP WHOKNOWS dk.test DK.TEST + + // Area definitions for the QWK conferences + AREADEF BAD_QWK "Bad QWK msgs" 0 Echo Opus C:\QWK\CONF\BADQWK + AREADEF GOLDED "GoldED support" 0 Echo JAM C:\QWK\CONF\GOLDED + AREADEF GOLDED.BETA "GoldED beta" 0 Echo JAM C:\QWK\CONF\GOLDBETA + AREADEF BBS.USERS "BBS Users" 0 Echo JAM C:\QWK\CONF\BBSUSERS + AREADEF EMAIL "E-Mail" 0 EMail Opus C:\QWK\CONF\EMAIL + AREADEF DK.CHAT "dk.chat" 0 News JAM C:\QWK\CONF\DKCHAT + AREADEF DK.TEST "dk.test" 0 News JAM C:\QWK\CONF\DKTEST + + // Group for the EMAIL area + GROUP EMAIL + CTRLINFO NO + EDITHARDTERM YES + TEMPLATE INTERNET.TPL + INTERNETADDRESS odinn@whoknows.where + INTERNETMSGID YES + INTERNETRFCBODY YES + ENDGROUP + + // Group for the Internet newsgroups + GROUP Newsgroups: + MEMBER dk.* + CTRLINFO NO + EDITHARDTERM YES + INTERNETADDRESS odinn@whoknows.where + INTERNETMSGID YES + INTERNETRFCBODY YES + QUOTECHARS ":;|" + TEMPLATE INTERNET.TPL + WHOTO All + ENDGROUP + + +Planned QWK features: + +* Support for BlueWave and perhaps other offline packet formats. +* Support for compressed .QWK and .REP packets. +* Built-in replylinker. +* Your suggestions :-) + +#page +#--------------------------------------------------------------------- +#chapter Using the SOUP features + +GoldED supports import and export of the Internet SOUP packet format +for e-mail and newsgroups. Using this feature, you can use GoldED as +an offline reader for Internet. The SOUP packet format, version 1.2, +is documented in the SOUP12.DOC document by Rhys Weatherley +. + +A SOUP packet consist of a number of packet files with an extension of +.MSG plus an AREAS file which tells where each .MSG packet belongs. +Other files may be found in a SOUP packet, but they are not supported. + +A SOUP reply packet generated by GoldED consists of a GOLDMAIL.MSG +packet file for e-mail and/or a GOLDNEWS.MSG packet file for +newsgroups plus a REPLIES file which lists the .MSG packets. + +The SOUP import/export features are currently activated from a submenu +the arealist scan menu (Alt-S). The submenu item is only present if +SOUPIMPORTPATH and/or SOUPEXPORTPATH is defined. + +Below are the keywords that are relevant for the SOUP support as +currently implemented: + + SOUPIMPORTPATH + Path where incoming SOUP packet files (AREAS and *.MSG) can be + found. + + SOUPEXPORTPATH + Path where outgoing SOUP reply packet files (REPLIES and + GOLD*.MSG) can be placed. + + SOUPEMAIL + Specifies the area where e-mails are placed. + + SOUPBADMSGS + Specifies the area where articles in unknown newsgroups are put. + If you get articles tossed here by accident, you must move them + manually to the correct area. If the badmsgs area is not + defined, the articles will silently disappear. + + SOUPNEWSRCFILE + Name with full path of the NEWSRC file which lists the + newsgroups you are connected to. GoldED uses the list to mark + the matching areas as newsgroups. These will then be scanned for + outgoing mail when starting a SOUP export. + + SOUPTOSSLOG + Name of a file where GoldED puts the echoids (newsgroup names) + of each area where articles have been imported. The tosslog file + is intended to be used with a replylinker. If no path is given, + it defaults to the GOLDPATH. + + SOUPREPLYLINKER + Commandline for a replylinker program to call after SOUP import. + + INTERNETADDRESS + Specifies your Internet address. This must be the address only, + no name. The INTERNETADDRESS and USERNAME will be combined to a + standard "From: internetaddresss (username)" headerline when you + write e-mail or articles. + + INTERNETGATE [gatename<,>] + Specifies an FTN address which is used as the destination + address in the FTN message header. It is also the address used + in the FSC-35 REPLYTO/REPLYADDR kludges that are inserted in + mail and news imported from SOUP packets. + + INTERNETMSGID + Specifies whether the FTN MSGID kludge should contain an RFC1036 + compatible Message-ID or the normal FTS-9 format. Note that + using the RFC1036 format in MSGID breaks the FTS-9 (version 001) + specification, so please don't use this feature in FidoNet + netmail or echomail. As a safeguard, GoldED will only use the + RFC1036 format in areas specifically marked as e-mail or + newsgroups, using the SOUPEMAIL and SOUPNEWSRCFILE keywords or + using the Email and News area types with the AREADEF keyword, + even when INTERNETMSGID is set to YES globally. + + INTERNETREPLY + If set to yes (the default), GoldED uses the FSC-35 reply + method, which puts UUCP in the to-field and a To: line at the + top of the message. For use with SOUP, this is ugly, so it is + recommended to set this keyword to NO. Note however, that due to + limitations of the header field editor, there is currently a + limit of 35 characters for the from and to headerfields. + + INTERNETRFCBODY + Tells GoldED whether to look for and process RFC headerlines at + the top of the message body, before the first empty line. Also + tells GoldED to insert its own RFC headerlines at the top of the + message body instead of as kludge lines. This option should only be + used when receiving Internet mail as QWK packets where the + RFC headerlines are usually found at the top of the messages, or + when sending Internet mail via FTN packet to a gateway running + GIGO. GIGO does not recognize RFC header in kludges, but it does + recognize them at the top of the messages, if it is properly + configured (with lines of "Allow_Xxx:" in GIGO's HEADERS.CFG, + where Xxx are the RFC headerlines the gate administrator wants + to allow). + + MAILINGLIST [contribution address] + Defines one or more mailing lists. When importing e-mail from a + SOUP packet, GoldED will look at the Internet address in the + "Sender" header and if it matches one of the MAILINGLIST's, the + e-mail will be tossed to the defined area. Note that GoldED + supports only participation in, not hosting of mailing lists. + The contribution address is the destination Internet address for + mail you write to the mailing list - the address is typically + given to you when you subscribe to a list. If the contribution + address is not specified, the senderaddress is assumed. + +There are six different SOUP packet encoding formats. Four of those +are supported by GoldED. + + u USENET news articles (import only) + m Unix mailbox articles (import only) + M Mailbox articles in the MMDF format (not supported) + b Binary 8-bit clean mail format (import and export) + B Binary 8-bit clean news format (import and export) + i Index file only (not supported) + +The 'M' format is not yet supported. If you need support for this +format, please let me know, and send along an example SOUP packet +which uses the 'M' format. There are no plans to support the 'i' +format in the near future. + +Articles are imported to the area matching the newsgroup name (for +example "rec.humor.funny" is imported to an area with the echoid +REC.HUMOR.FUNNY). E-mails are imported to the area named with the +SOUPEMAIL keyword. If no matching area can be found, the articles are +tossed to the area named with the SOUPBADMSGS keyword, with the +newsgroup name in an AREA: line at the top. If no badmsgs area is +defined, the articles will be silently thrown away. + +After import, the AREAS, *.MSG and *.IDX files are deleted from the +SOUPIMPORTPATH. Be sure to keep backup copies when experimenting with +the SOUP feature. Note that there is currently no dupe check. + +In the imported articles, the RFC headerlines are converted to +kludges. The real names (if any) in the From: and To: headerlines are +put into the message from/to header fields. If no To: line is found, +"All" is used. + +When you write or reply to e-mail and articles, GoldED adds the echoid +(newsgroup name) and message number to a file named GOLDSOUP.LST in +the GOLDPATH. This file is used exclusively by GoldED to find outgoing +mail when starting the SOUP export. + +There are three Internet specific template tokens: + + @oto Original RFC "To:" headerline. + @ofrom Original RFC "From:" headerline. + @omessageid Original RFC "Message-ID:" headerline. + +With these tokens, it is possible to create templates which look like +one of the defacto standard attribution lines used by other +newsreaders. See the example NEWSGRPS.TPL file for examples. + +In e-mail and newsgroups, the ORIGIN keyword can be used to set the +content of the "Organization:" headerline. + +The Martin Junius MSGID.DOC document is +supported. This means that the Message-ID headerline is converted to a +MSGID kludge and the References headerline is converted to one or more +REPLY kludges. This makes MSGID/REPLY based replylinking possible +using existing FTN-based utilities. The original Message-ID and +References headerlines are preserved in the messages along with the +MSGID/REPLY kludges. + +SOUP import and export is currently quite slow and a some things are +hardcoded that should be made into options. There is a lot of room for +improvements, but this is a nice start for those who want to read +their Internet mail and news with their favorite program instead of +the various SOUP offline readers out there. + +For people with the IBM OS/2 Internet Access Kit, I can recommend the +"Souper" program which can make SOUP packets for offline consumption +instead of the expensive online reading with NewsReader/2 and +Ultimedia Mail/2. At the time of writing, the latest version was +SOUPER12.ZIP, ftp'd from hobbes.nmsu.edu. + +The SOUP features SHOULD NOT be used with the GoldED DOS version. Use +the 386 or OS/2 versions. The current implementation uses memory like +a pig, and in any case, it is common that very large messages (>64K) +are seen in Internet e-mail and newsgroups, and the DOS version does +not handle very large messages well at all. + +It is recommended to use either the JAM or the Squish msgbase formats +to store the Internet newsgroups. These two formats support tree-like +replylinking. JAM supports it best, with unlimited links. Squish only +supports up to 9 links. GoldED currently also only supports up to 9 +links, even for JAM. + +GoldED understands several character translation standards and +non-standards for Internet e-mail and newsgroups. Please see the next +chapter for details. + +PLEASE NOTE: GoldED can be used purely for Internet use as a SOUP +packet reader, but there are still some FidoNet-specific keywords +which must be setup for GoldED to operate correctly. The ADDRESS and +INTERNETGATE keywords must be set to a FTN-compatible address. If you +don't know or care about any such address, just use this: +"2:236/77.999" (leave out the quotes). + + +Example setup in GOLDED.CFG: + + // Minimum FTN setup + USERNAME Odinn Sorensen + ADDRESS 2:236/77 + + // Basic Internet setup + INTERNETADDRESS odinn@ibm.net + INTERNETGATE 2:236/77 + INTERNETMSGID YES + INTERNETREPLY NO + + // Basic SOUP setup + SOUPIMPORTPATH C:\SOUP\IMPORT\ + SOUPEXPORTPATH C:\SOUP\EXPORT\ + SOUPNEWSRCFILE C:\SOUP\NEWSRC + SOUPEMAIL NET_EMAIL + SOUPBADMSGS BAD_NEWS + + // Area definitions for e-mail and bad newsgroups + AREADEF NET_EMAIL "E-Mail" 0 EMail Opus C:\SOUP\NETMAIL + AREADEF BAD_NEWS "Bad Newsgroups" 0 News Opus C:\SOUP\BADNEWS + + // Replylinking when using GEcho and JAM areas: + SOUPTOSSLOG C:\GECHO\IMPORT.JAM + SOUPREPLYLINKER C:\GECHO\MBUTIL Link + + // Replylinking when using Squish and Squish areas: + SOUPTOSSLOG C:\SQUISH\SOUPTOSS.LOG + SOUPREPLYLINKER C:\SQUISH\SQUISH LINK -fC:\SQUISH\SOUPTOSS.LOG + + // Setup of some mailing lists + MAILINGLIST LIST.EMX emx-list@eb.ele.tue.nl + MAILINGLIST LIST.GIGO gigo-owner@gigo.com gigo@gigo.com + + // Area definitions for the mailing list areas + AREADEF LIST.EMX "EMX mailing list" 0 EMail Opus C:\SOUP\EMX + AREADEF LIST.GIGO "GIGO mailing list" 0 EMail Opus C:\SOUP\GIGO + + // Setup of character translation + XLATPATH C:\GOLDED\XLAT\ + XLATESCSET MNEMONIC IBMPC MNE_IBM.ESC + XLATCHARSET LATIN-1 IBMPC ISO_IBM.CHS + XLATCHARSET LATIN1QP IBMPC IQP_IBM.CHS + XLATCHARSET MAC IBMPC MAC_IBM.CHS + XLATCHARSET IBMPC IBMPC IBM_IBM.CHS + XLATCHARSET IBMPC LATIN-1 IBM_ISO.CHS + XLATCHARSET IBMPC LATIN1QP IBM_IQP.CHS + XLATCHARSET IBMPC MNEMONIC IBM_MNE.CHS + + // Main group for Internet newsgroups + GROUP Newsgroups: + MEMBER alt.*, comp.*, misc.* news.* + MEMBER rec.*, soc.*, sci.*, talk.* + MEMBER bad_news + EDITHARDTERM YES + QUOTECHARS ":;|" + TEMPLATE INTERNET.TPL + WHOTO All + ENDGROUP + + // Main group for e-mail, mailing lists and some danish newsgroups + // with character translation + GROUP EMail: + MEMBER net_email, list.* + MEMBER pingnet.*, dknet.*, dk.* + EDITHARDTERM YES + TEMPLATE INTERNET.TPL + WHOTO All + XLATIMPORT LATIN-1 ; Assume ISO-8859-1 is in use + XLATEXPORT LATIN1QP ; Use MIME quoted-printable encoding + ; XLATEXPORT LATIN-1 ; Use MIME 8bit encoding + ; XLATEXPORT MNEMONIC ; Use RFC1345 character mnemonics + ENDGROUP + + +Example INTERNET.TPL: + + @moved* Replying to an article in @oecho. + @moved + @changed* Changed by @cname, @cdate @ctime. + @changed + @forward* Forwarded from @oecho by @cname. + @forward* Originally by: @ofrom, @odate @otime. + @forward* Originally to: @oto. + @message + @forward + @new + @reply@ofrom wrote: + @reply@position + @comment@ofrom wrote: + @comment@position + ;@quotedIn article @omessageid, @ofrom wrote: + @quoted@ofrom wrote: + @quoted@position + @quotebuf + @quotebuf@ofrom wrote: + @quotebuf + @quote + + -- + Signature Signature Signature Signature Signature Signature + Signature Signature Signature Signature Signature Signature + + +Planned Internet/SOUP features: + +* Killfile. +* Addressbook. +* Article cancel. +* Improved thread navigation. +* Built-in replylinker/threader. +* Elimination of FTN-requirements, for pure Internet use. +* Msgbase format designed optimally for Internet and threading. +* Your suggestions :-) + +#page +#--------------------------------------------------------------------- +#chapter Notes About Internet Character Translation + +Character Translation Issues: + +* MIME: From RFC1341/1521, charset=ISO-8859-1 and encoding + quoted-printable or 8bit is supported both for ingoing and outgoing + messages. The RFC1342/1522 header extensions are currently not + supported. + +* X-Charset and X-Char-Esc: These experimental headers are supported + for both ingoing and outgoing messages, using RFC1345 character + mnemonics and escape character ASCII 29. + + +Unresolved Issues: + +* In e-mail (netmail) areas, the charset translation features do not + yet work correctly. Please avoid using non-ascii characters in + message headers (to/from/subject). + + +Using MIME Character Translation (RFC1341/1521) + + You must have these lines in your GOLDED.CFG: + + XLATCHARSET IBMPC LATIN-1 IBM_ISO.CHS + XLATCHARSET IBMPC LATIN1QP IBM_IQP.CHS + XLATCHARSET LATIN-1 IBMPC ISO_IBM.CHS + + The IBM_ISO.CHS, IBM_IQP.CHS and ISO_IBM.CHS files must be present in + the XLATPATH. + + To use MIME charset ISO-8859-1 and encoding 8bit in your messages, + you must have these lines in the appropriate group(s): + + XLATEXPORT LATIN-1 + XLATIMPORT LATIN-1 + + This will add the following headers in your messages: + + MIME-Version: 1.0 + Content-Type: text/plain; charset=iso-8859-1 + Content-Transfer-Encoding: 8bit + + Note that 8bit encoded messages usually won't get through unharmed + in e-mail, because the SMTP protocol is 7bit. In newsgroups the + problem apparently isn't so bad. If you want your 8bit characters to + get to the destination unharmed, you should use the quoted-printable + encoding (see below). + + To use MIME charset ISO-8859-1 and encoding quoted-printable in your + messages, you must have these lines in the appropriate group(s): + + XLATEXPORT LATIN1QP + XLATIMPORT LATIN-1 + + This will add the following headers in your messages: + + MIME-Version: 1.0 + Content-Type: text/plain; charset=iso-8859-1 + Content-Transfer-Encoding: quoted-printable + + When quoted-printable encoding is used, 8bit characters are + translated to a three-character code starting with ASCII 61 ('='), + followed by two hexadecimal characters that together form the + hexadecimal value of the original character in the charset specified + by the Content-Type header. + + Users must be aware that not all reader software recognize and + support the quoted-printable format. The reader software may display + the entire three-character code untranslated, or translate the code + imcompletely. If the code is untranslated, the displayed result is + usually not pretty. + + +Using Character Mnemonics Encoding (RFC1345) + + You must have these lines in your GOLDED.CFG: + + XLATESCSET MNEMONIC IBMPC MNE_IBM.ESC + XLATCHARSET IBMPC MNEMONIC IBM_MNE.CHS + XLATCHARSET LATIN-1 IBMPC ISO_IBM.CHS + + The MNEMONIC.ESC, IBM_MNE.CHS and ISO_IBM.CHS files must be present + in the XLATPATH. + + To use character mnemonics in your messages, you must have these + lines in the appropriate group(s): + + XLATEXPORT MNEMONIC + XLATIMPORT LATIN-1 + + This will add the following headers in your messages: + + X-Charset: ISO_8859-1 + X-Char-Esc: 29 + + When character mnemonic encoding is used, 8bit characters are + translated to a three-character code starting with ASCII 29, + followed by two characters that together form a standardized + mnemonic of the original 8bit character. + + Users must be aware that not all reader software recognize and + support this encoding format. The reader software may display the + entire three-character code untranslated, omit only the escape + character or translate the code incompletely. If the code is + untranslated, the displayed result is usually not pretty. + + +Choosing Between MIME and Character Mnemonics + + The safest choice for both e-mail and newsgroups is MIME with + quoted-printable encoding. + + MIME is a fully documented standard (see RFC1522 or the older + edition RFC1341) using standard headers. It is fairly widely + supported by (newer) reader software. + + The character mnemonics are documented in RFC1345, but the "X-" + headers are not documented (to the authors knowledge). The existence + of the X-Charset/X-Char-Esc headers and the encoding method was + found and deduced from sending e-mails with 8bit characters back and + forth between different addresses and looking at the e-mail at the + destination. The translation of 8bit e-mails and addition of the X- + headers appears to be done by routing software before sending them + using 7bit transfer protocols like SMTP. It is unknown what, if any, + reader software that supports the character mnemonics. + + The main disadvantage of MIME 8bit and quoted-printable is that the + character set is limited to the US-ASCII 7bit or ISO-8859-1 8bit + sets. The character mnemonics support most or all of the 16bit + unicode character set. + +#page +#--------------------------------------------------------------------- +#chapter Sound Support in DOS - The Goldware Sound API + +The DOS and 386 versions of GoldED support sound via sound cards by +calling functions in the Goldware Sound API. + +The Goldware Sound API is a set of functions provided by an interrupt +service function installed on the Alternate Multiplex Interrupt (AMI) +2Dh. For full details on the Alternate Multiplex Interrupt, please see +Ralf Brown's Interrupt List (INTER46*.ZIP), his AMI specification +(ALTMPX35.ZIP) and/or his AMIS library (AMISL091.ZIP). + +I have implemented a program loader which provides the interrupt +service function with the Goldware Sound API. The current version of +the program loader is named GCTVSAPI 1.00 and may be found in the +archive GCTV100.ZIP. The current version of GCTVSAPI loads the +Creative Labs CT-VOICE.DRV file for playing of .VOC files. Full public +domain C++ source code and the Goldware Sound API specification is +included in the archive. + +I hope that others will write program loaders or TSR's that implement +the Goldware Sound API for other sound cards than the Sound Blasters, +or even an implementation that does not require CT-VOICE.DRV. + +If you have written a Goldware Sound API implementation, please let me +know, so that I and the reg.sites can make it available for other +users. + +#page +#--------------------------------------------------------------------- +#chapter Sound Support in the OS/2 Version + +To support sound in the OS/2 version, GoldED requires the MMPM/2, the +OS/2 MultiMedia Presentation Manager to be installed. + +GoldED sends commands to MMPM/2 using the mciSendString API function. +Basically it send the following commands to play a sound file: + + open alias noise wait + seek noise to start + play noise + (do other things until playing is complete) + close noise wait + +These commands require that there is an association between the sound +file and the appropriate sound device (typically waveaudio or +sequencer). If you can't seem to get GoldED/2 to play your files, you +should check in the Multimedia Setup if the Association tabs under +Digital Audio and MIDI look correct. + +It works perfectly here. If GoldED/2 doesn't play your files, you have +a setup problem somewhere. Try if entering "PLAY FILE=" at +the OS/2 commandline works. The REXX program PLAY.CMD sends commands +to MMPM/2 in almost the same way as GoldED/2. + +If you are trying to make GoldED/2 play .VOC files and it doesn't +work, convert them to .WAV and try again. + +#page +#--------------------------------------------------------------------- +#chapter Replacing DOS/4GW with PMODE/W in GoldED/386 + +The standard release of GoldED/386 requires the Rational Systems +DOS/4GW DOS extender runtime file DOS4GW.EXE. Many other programs use +the same extender. However there is an alternative extender which can +be used with GoldED. The alternative extender replaces a "stub" in +GED386.EXE and eliminates the requirement of the big DOS4GW.EXE file +as well as reducing memory requirements and increases speed. + +The alternative DOS extender is PMODE/W by Charles Scheffold and +Thomas Pytel. At the time of writing, the latest version I know of is +version 1.23, distributed in the archive PMW123.ZIP (132k), dated june +24, 1996. By now there is probably already a newer version. Try +checking their website at http://www.dorsai.org/~daredevi/pmw. + +If you want to replace DOS/4GW with PMODE/W, simply use the PMWBIND +utility that comes with the PMODE/W archive, like this: + + PMWBIND /R GED386.EXE + +That's it! + +The PMODE/W manual recommends using the PMWSETUP program to adjust +some PMODE/W parameters in the new GED386.EXE, but in my very short +test period it worked fine without any adjustments, at least in a DOS +box under OS/2 Warp. + +So, if PMODE/W is so great, why don't I use it in the standard release +of GoldED/386? There are several reasons: + +1. For use in commercial/shareware programs, they want USD 500. I + can't afford that. + +2. During the beta test of GoldED 2.50 I tried to use version 1.12 of + PMODE/W, but it turned out there were too many problems with it. I + haven't checked if the newer versions are better. + +If you do replace DOS/4GW with PMODE/W and later experience odd +problems, please don't report anything to me before you have tried +going back to the standard release. You can do that by simply running +GoldED/386 like this: + + DOS4GW.EXE GED386 [whatever parameters, if any] + +Good luck with it! + +#page +#--------------------------------------------------------------------- +#chapter The Message Database Formats + +GoldED supports many different message database formats. The following +is a list of them all, with notes about their characteristics and what +special quirks to look out for with each of them. + + +Opus/FTS1 (*.MSG) + + These are two variants of the same type of msgbase. It works by + using one physical file per message (1.MSG, 2.MSG etc.), + collecting them in a directory for each area. Depending on the + clustersize on the harddisk, this can be a very wasteful and slow + way to store messages. With a clustersize of about 512 bytes, the + waste may be acceptable, but the access speed can be dramatically + slow if there are many *.MSG files, due to the DOS file system. + Caches and BUFFERS adjustments can improve it, but there are + limits. + + In echomail areas, this format has a special quirk: The first + message (1.MSG) is normally used to store the so-called + "highwatermark". The highwatermark tells the echomail processor + where it should start scanning for new messages entered by users. + By deleting (Zapping) the highwatermark, you can make the echomail + processor re-scan the whole area again. This may cause messages to + be sent out as "dupes", so this should be used sparingly and + carefully, if at all! The highwatermark can also be "Heated" - + which means that it is set to the last msg in the area. This + prevents the echomail processor from finding newly entered + unscanned msgs. Use with care. + + The variants: The "Opus" format originated in the Opus BBS system. + It put some Fido undocumented(?) fields to use as date/time + stamps. The "FTS1" (defined in FTS-0001, revision 12 and later) + format uses the undocumented fields to set the zone/point + information for the msg. To the authors knowledge, the Opus + variant is the dominant, and the FTS1 variant is doomed to + oblivion. If in doubt, use the Opus format. + + +Hudson + + This msgbase format was invented by Adam Hudson, and was first + used in his QuickBBS package. Later several other BBS'es were + cloned from QuickBBS (like RemoteAccess and SuperBBS). + + The basic format is built around 7 main files: + + MSGTXT.BBS This contains the message text of all msgs in all + areas. + MSGHDR.BBS The headers for all the msgs in MSGTXT.BBS. + MSGIDX.BBS Index to MSGHDR.BBS. + MSGINFO.BBS Tells how many msgs there are in each area. + MSGTOIDX.BBS Index that contains all the TO names. + LASTREAD.BBS Lastreads for all areas for each user in USERS.BBS. + USERS.BBS Contains a record for each user. Also the index to + LASTREAD.BBS. + + The format limits the total size of MSGTXT.BBS to a maximum of + 16MB, which translates to about 16000 msgs of "average" length. + GoldED automatically warns you if the limit is close to being + reached, and advises you to pack the msgbase. + + The first incarnations of QuickBBS did not support "sharing" of + the msgbase. This became more and more important in later years as + multitaskers and networks got cheaper. RemoteAccess BBS was the + first to implement a useful method, and later a better method was + evolved (known as "RA 1.01 or RA 1.1x"), which is now the standard + for all modern software that supports msgbase sharing. GoldED + fully supports the new standard of course. + + The main virtue of this format is that it is very fast to access + the msgbase. + + The main disadvantage is that it can be very sensitive to disk + problems, and it is a common horror story that people loose their + entire msgbase because the disk developed bad clusters or some + program went berserk and messed up the msgbase files. + + +Goldbase + + This is an enhanced version of the Hudson format, introduced in + QuickBBS 2.80 by the QuickBBS group. + + The Goldbase format removes the 16MB size limit and allows up to + 500 message areas instead of the 200 in Hudson. The filenames are + the same, except that the extension is .DAT instead of .BBS. + + +Squish + + The Squish format is relatively new. It was invented by Maximus + BBS author Scott Dudley in 1991, and was first used in Maximus + CBCS v2.00. Soon after, GoldED was among the first message editors + to support this new format. + + Squish uses three files per area: A header/message text file + (*.SQD), an index file (*.SQI) and a lastread file (*.SQL). The + SquishMail echomail processor uses a fourth file (*.SQB) to hold a + dup-database. + + The use of a database for each area - instead of one file per msg, + or all msgs in one big database - makes this format fast, very + safe and resistant to disk problems. Even if something messed up a + Squish area, it can almost always be fixed and recovered, using + the SQFIX or SQREIDX utilities that come with the Squish echomail + processor. + + A special feature of Squish areas is that they can be + self-maintaining. You can setup a Squish area so that it may only + contain a maximum of so-and-so many msgs, and then it will + automatically re-use the space used by old msgs when the limit is + reached, and so it will practically stop growing. It will still + need packing, but not nearly as often as a Hudson msgbase has to. + + +Ezycom + + + + +JAM + + The JAM format was invented by Joaquim Homrighausen, Andrew + Milner, Mats Birch and Mats Wallin. + + JAM uses four files for each area: A header file (*.JHR), a + message text file (*.JDT), an index file (*.JDX) and a lastread + file (*.JLR). Most echomail processors support two additional + files to aid scanning out messages: NETMAIL.JAM and ECHOMAIL.JAM. + They are "global" files, located in the JAMPATH. + + See also the chapter "JAM Implementation Notes". + + +PCBoard + + + + See also the chapter "PCBoard Implementation Notes". + +#page +#--------------------------------------------------------------------- +#chapter JAM Implementation Notes + +This chapter describes details about the implementation of the JAM +messagebase format in GoldED. Should be read in conjunction with the +JAM specs for better understanding. A lot of technical terms will be +used, so if you are not the technical type, just skip over it. + + +General notes + +The first release of the JAM messagebase specifications (JAM-001, +rev.1, dated 93-07-01) included an example implementation in the C +language of a "JAM API". + +For the purpose of use in GoldED, the JAM API C implementation was +both too complete and not complete enough. Therefore I developed my +own specialized JAM msgbase handling code. My own code was of course +designed be compatible with the original JAM API as well as the +specifications, but some things are done slightly differently for +various reasons. + + +File I/O checks + +Reads and writes to the msgbase files are generally NOT checked for +errors in GoldED. In contrast, the original JAM API checks everything +and stores error values in the API, for the user to use or ignore. + +Full checking degrades performance a bit, adds more code to the EXE +file, and most importantly, GoldED just doesn't have a safe way to +recover from the detection of such errors anyway at this time. +Assuming that your system is working well, there are no harddisk +errors etc., this will normally not be a problem. + + +Message header revisions + +The JAM message headers contain a field to indicate the revision +number of the header structure. + +GoldED currently ignores this field and assumes that future revisions +will remain backward compatible. When creating new msgs, GoldED uses +the revision 1 header structure. + +When new revisions of the JAM specs are released, GoldED will be +updated to handle these as quickly as possible. + + +Passwords + +The JAM specs contain fields for passwords to access the msgbase +and/or indiviual messages. + +GoldED currently doesn't support these passwords. When creating a new +JAM msgbase and/or new JAM msgs, GoldED sets the password to +FFFFFFFFh. If you change an existing msg which has a password, the +password is NOT preserved, but reset to FFFFFFFFh. + + +Lastreads + +The JAM lastread file is designed such that is has to be searched for +a userid/usercrc, because one cannot assume that the records are in a +specific order. + +The JAM API searches the userid field. However it seems more +reasonable to search for the usercrc, because that is a value the +program can calculate from the username without looking in other +files. I'm not sure why the JAM API chooses to look in the userid +field instead. GoldED searches for the usercrc, not the userid. In any +case, it seems that RemoteAccess 2.x sets both the userid and usercrc +to the same value. + +The specs state that the user's lastread record must be searched for +both when retrieving it and storing an updated record. However, the +JAM API seems to implemented slightly differently, because when it +stores an updated record, it stores it at the same position as it was +read *without* first searching for it. + +GoldED has been implemented to work in a similar manner. It searches +for the user's lastread record when the msgbase is opened, and it +assumes that it will remain in the same position as it was found, +until the msgbase is closed. + +This is normally a quite reasonable assumption. The only circumstance +where the lastread records might be re-ordered is when a msgbase +maintentance utility cleans up or sorts, and such a utility is +normally designed to open the msgbase files in exclusive mode, which +it can't do when the files are already open. If it tries to re-order +without exclusive access, the utility is badly designed and +potentially dangerous in multitask/networking environments. + + +Size limits + +The JAM specs allow msgbases and msgs of really huge sizes. The 16-bit +DOS version of GoldED cannot handle the full extremes of this. The +32-bit OS/2 and 32-bit protected mode DOS versions of GoldED can +handle any size, only restricted by memory, disk space or unknown +compiler or operating system limits. + +The internal limits for the 16-bit versions of GoldED means that they +can only handle msgbases containing a maximum of 8191 msgs (including +deleted msgs), and msgs a maximum of about 64k long. In theory at +least. In practice the limits may be smaller due to lack of memory. + + +ASCII 7-bit escaping + +GoldED currently doesn't support the escaping described in the JAM +specs. The specs state that the current revision of JAM does not +support it either, so I guess it's no great loss. + + +Date fields + +GoldED currently doesn't display the DateReceived field, but it is +updated on disk when a message is received (read) by the recipient. + +The DateProcessed field is set to the current date when a msg is +writtten or changed with GoldED. + +All new dates are set to the system time and are not adjusted for +timezone. + + +Subfields + +The concept of the JAM subfields is difficult to support easily in a +program like GoldED, which was designed to support the traditional +fixed header formats and kludges in the msg body. Therefore the +implementation in GoldED of the JAM subfields is not currently as +complete as one might wish. + +However, it should be adequate for most purposes. I will of course do +what I can to improve the JAM subfield support in future releases. The +following is a list of the current limitations of the JAM subfield +support in GoldED: + +* Subfields are converted internally to the equivalent kludges for + easy viewing, and to make it possible to copy JAM msgs to areas + with other msgbase formats. Some subfields do not have equivalent + known kludges defined. They are converted to kludges with names I + have invented for the purpose. All subfields can be viewed if you + hit the Alt-I key to display a hexdump of the message. + +* The subfields with size limits (typically 100 chars) are not + specifically checked for size. Since all other msgbase systems + have much lower limits for the fields in question, this should not + be a problem. + +* Only one OADDRESS/DADDRESS is supported. When reading a message, + only the _first_ OADDRESS/DADDRESS is used. + +* None of the file attach or file request subfields are supported at + this time. File attaches or file requests are stored in the + subject field in a manner similar to other msgbase formats. This + might not be supported by a fully JAM compliant mail processor, + but IMHO a mail processor should use the subject field if it finds + the file attach/request attributes set, but can't find any + subfields for them. + +* If you change a JAM message which is not from you, and save it, + all unsupported subfields will be missing in the saved message, + and some supported subfields may be changed in content (like the + PID subfield). + +* Currently unsupported message attributes: + + MSG_FPU "Force pickup" + MSG_NODISP "Msg may not be displayed to user" (always displayed) + + +Deleted msgs + +The original JAM specs has a fairly major problem when it comes to the +specification for deleting msgs and in particular about _detecting_ +deleted msgs. The original specs do not define a fast way to detect +deleted msgs from the index file alone. + +This may not be so important for a BBS or a mail processor, but it is +absolutely vital for mail readers such as GoldED, which need a fast +way to find out how many active msgs there are, and where the lastread +is, and to calculate how many unread msgs there are. If GoldED had +scan the header file to check a single bit in each header the area +scanning would slow down dramatically, because the header file can +easily grow to many megabytes and thousands of msgs. + +Fortunately there is a way out. The specs state that if the usercrc +and header offset values in the index are both -1 (FFFFFFFFh), then +"there is no corresponding header". Such a situation is IMHO highly +unlikely, so I have proposed to use this to signify a deleted msg +instead. This should be backward compatible with almost all JAM +compatible programs, with the possible exception of msg undelete +utilities. + +With the header offset set to -1 (FFFFFFFFh), there is of course no +fast way to find the header of a deleted msg. A msg undelete utility +would have to scan through the entire header file to locate the +deleted header (or rather the last occurrence of it, because there can +easily exist more than one deleted header with the same message +number). This is IMHO a price worth paying for the performance gained +by using by changing the specs to specify a deleted msg instead of a +hypothetical non-existing header. + +When I brought up this subject in the JAMDEV echo, the developers who +replied generally agreed that this was a good idea. At the time of +writing, I don't know for certain that it will be changed in the +specs, but I think so. + +GoldED optionally (since version 2.50.B0822) follows my proposed +method when deleting msgs. The configuration keyword JAMHARDDELETE +specifies which method to use. If set to Yes, my method is used. The +default is No, but I recommend (and use myself) Yes. + + +Scanning files + +The NETMAIL/ECHOMAIL.JAM files are written/updated when new messages +are written or changed in JAM netmail/echomail areas. The files are +written/updated in the JAMPATH. If you don't have a JAMPATH, it +defaults to the HUDSONPATH. If you don't use a Hudson msgbase and +haven't defined a HUDSONPATH, the HUDSONPATH defaults to the GOLDPATH. + +At the time of writing, the NETMAIL/ECHOMAIL.JAM files are not a part +of the official JAM specs, but they are used in RA2 and most JAM +compatible mail processors to specify the msgs that need to be +exported from the JAM msgbase files. + +#page +#--------------------------------------------------------------------- +#chapter PCBoard Implementation Notes + +This chapter describes details about the implementation of the PCBoard +messagebase format in GoldED. + + +Netmail + +GoldED 2.50 supported FidoPCB-style netmail areas, where the first and +second line of the msg had special meaning as FidoNet address or +attributes. This is no longer supported from version 2.51. Instead, +the official method used by PCBoard itself is supported. This should +be transparent to you. + + +Extended Headers + +GoldED is aware of PCBoard v15.x extended headers in the message text. +The TO, TO2, FROM, FROM2 and SUBJECT extended headers are directly +supported and "swallowed" when reading a msg. Other extended headers +are currently treated like normal message text and is therefore not +hidden to the reader. In a later release, I plan to internally convert +the extended headers to kludges. + + +Long Names + +GoldED 2.51 supports the long names that are possible with PCBoard. +You can both enter and edit them. GoldED 2.50 was limited to 35 chars. + + +Password + +Passwords are not supported. + + +Attributes + +The Private, Received, Crash and Direct attributed are supported. + + +Double-Byte Characters (Foreign Systems) + +GoldED reads the PCBOARD.DAT file to determine whether to use E3h or +0Dh (CR) as the line/paragraph termination character when reading and +writing message text. + + +Message Index + +Only the new v15.x .IDX files are suppported. The old .NDX files are +not supported in any way. + + +Userbase + +By default, the first set of lastreads is used. But if you set +PCBOARDUSERNO to -1, GoldED searches the userbase for your name to +find the lastread pointer set. If GoldED does not find you name, it +will NOT add a new userbase record for you, but instead uses the first +set of lastreads. + + +Mail Waiting Flag + +The mail waiting flags are updated when you write to people that are +named in the userbase. + +Changing a Message + +When changing a message, the new edition is saved as if it were a new +message, with a new message number, and then the old edition is +deleted. This behaviour is consistent with the way PCBoard itself +works when changing a message. NOTE: The old edition will still be +visible with the DEL attribute until you exit the area. + +#page +#--------------------------------------------------------------------- +#chapter AdeptXBBS Implemenation Notes + +This chapter describes details about the implementation of the +AdeptXBBS messagebase format in GoldED. The implementation is based on +the documentation in version 1.05, experimentation and questions to +the authors. Thanks go to Frank Jacobberger for the initial testing +and prodding of the authors to answer my questions :-) + +The AdeptXBBS format does not have a quick method of finding deleted +messages via the index file. This means that deleted messages will +still be visible, but marked with the DEL attribute. When GoldED +deletes a message, it will at first seem to be gone, but after the +next scan, it will be back again, with the DEL attribute. + +Mixing of netmail and echomail or other types of mail in the same area +is not directly supported. If an area is setup as both netmail and +echomail, GoldED will treat it as netmail. If an area is neither +netmail nor echomail, GoldED wil treat it as a local area. + +GoldED detects Usenet (newsgroup) and Internet E-Mail areas in +the AdeptXBBS setup and uses them as such, but it has not yet been +tested if GoldED and AdeptXBBS are compatible in the way they store +and process Internet header information. + +The AdeptXBBS personal mail feature (the index in the Personal_Mail +directory) is supported for mails you write to other users on the BBS. +However, personal mail for you via this feature or by other means is +not yet supported. + +The replylinking method used by AdeptXBBS (whatever the method is??!) +is not yet supported. This means that links to other messages are +missing. + +The AdeptXBBS messagebase format is only supported in the OS/2 version +of GoldED, because AdeptXBBS requires HPFS. In the other versions, the +AdeptXBBS code is not included in the EXE file and therefore doesn't +use additional memory or EXE disk space. + +#page +#--------------------------------------------------------------------- +#chapter WildCat! 4.x Implementation Notes + +This chapter describes details about the implementation of the +WildCat! 4.x messagebase format in GoldED. + +The WildCat format does not have a quick method of finding deleted +messages via the index file. This means that deleted messages will +still be visible, but marked with the DEL attribute. When GoldED +deletes a message, it will at first seem to be gone, but after the +next scan, it will be back again, with the DEL attribute. + +WildCat features which are not supported yet: + +- The userbase. +- The message unread chain. +- The message from/to title. +- The message network name. +- The message internal and external attach. + +There is not yet any AREAFILE WildCat. You must define the areas by +hand using the AREADEF keyword, like this: + + AREADEF MYTEST "My Test" 0 Echo WCat etc. + +There is a keyword WILDCATUSERNO, which works just like the other +USERNO keywords. By default GoldED will use the first record +in the lastread file (*.LRD), so if you are not the first person in +the userbase, or you are sharing the messagebase with others, you may +have to change this user number. The userbase is currently not +supported (ie: you can't set the number to -1 to let GoldED find the +correct user and lastread automatically). + +NOTE: The WildCat support is currently not very well-tested, so use +it with caution. In my limited testing, I have not found it to be +damaging the messagebase, but you should probably test it on less +important areas and/or make backups until it is determined that it +is safe. + + + +#page +#--------------------------------------------------------------------- +#chapter Win32 Implementation Notes + +A new Win32 API based console (text) mode version has been added to +the GoldED family: GoldED/W32. It will run under Windows NT and +Windows 95 as a textmode application. Note that the screen update +speed and keyboard response may be slow, especially under Windows 95. +This is because screen and keyboard access has to go through some +fairly complex (Win32) API functions, which are designed to hide the +underlying hardware access method and thus have a lot of overhead +compared to direct hardware access under DOS or even the simpler API +under OS/2. + +Known limitations/problems/bugs in the Win32 version: + +- Can't change the screen mode (like from 25 to 43/50 lines). +- Can't change the border (overscan) color. +- Can't switch between blinking and intense colors. +- Can't change the palette. +- Shelling to the OS may not work. +- Standard beeping effects may not be working under Windows 95. +- Possible minor keyboard quirks. + +On the whole, I am not very happy about the Win32 versions performance +when running on Windows 95. However, I am certain that I can put a lot +of blame on the poor implementation of the console mode in Windows 95. +It runs more smoothly in Windows NT, even the old NT 3.1 that I tested +it on in the beginning. I would like to hear from users how it runs +under NT 4.0. + +Some of the limitations and problems with the Win32 version are caused +by limitations or peculiarities in the Win32 console mode API. + +#page +#--------------------------------------------------------------------- +#chapter Linux Implementation Notes + +There are some things you must know before trying out the Linux +version, especially if you are used to the DOS, OS/2 or Win32 +versions: + +* You should be familiar with GoldED for the other operating systems + and know your way around at least a basic golded.cfg. + +* Linux is an OS with CASE-SENSITIVE file systems. GoldED now uses + lowercase filenames internally, because this is costumary for Unix. + When accessing msgbases on case-insensitive file systems such as FAT + or HPFS under Linux, filenames might not be lowercase on the disk. + If this is the case, you must rename them so that they are (and hope + they stay lowercase). + + This will probably be the part that will give you the most grief if + you try to run a system with a mixture of Linux, DOS, OS/2, and/or + Win32 software. + + IF IT DOESN'T WORK OR COREDUMPS, TRY CHECKING IF ALL FILES ARE + LOWERCASE, BOTH ON THE FILESYSTEM AND IN THE CONFIGURATION FILES. + +* The directory separator (slash) char is '/', not '\'. However, + GoldED automatically translates the "wrong" slash char to the + "right" slash char in most cases, so you probably won't notice it. + +* Unix has no drive letters (C: etc), and GoldED for Linux currently + can't map DOS-style paths to Unix-style paths. This means that + AREAFILE's won't work unless paths are specifically written in + Unix-style. + +* If you want to use the same golded.cfg file for all platforms, you + can use the conditional statement "IF LINUX" or "IF UNIX" around + Linux specific parts of it, typically paths or filenames. + +* I recommend to start with a tiny golded.cfg (see below) with only + the basic setup and a few areas that you have a backup of. The + msgbase support of GoldED for Linux should work exactly as + 3.00.Alpha5, which is NOT known to trash msgbases, but it's compiled + and built with a compiler and tools that I'm not very familiar with, + and there may be compiler quirks and flaws introduced in the porting + which may have affected otherwise working code. + +* Currently only the *.MSG, JAM, Squish and Hudson formats have been + tested, but it should work with the other formats too. + +* There is not yet any support for Unix-style mailboxes or news + spools. If you want to access those, you need to use a utility that + can create/unpack SOUP packets. GoldED can import/export those to + the msgbases that are supported (JAM or Squish is recommended for + this). + +* File attach probably does not work well (it's not been tested). + +* Characters with ASCII values 0-31 are currently remapped to 'x' or a + visually similar character before being written to the screen. + Characters in the range 128-159 are remapped from CP865 to Latin-1. + +* The default XLATLOCALSET is LATIN-1 for the Linux version, as + opposed to IBMPC for the other OS'es. You should setup character + translation between IBMPC and LATIN-1 and use the correct XLATEXPORT + for each echo. See the GoldED manual for details. Most FidoNet + echoes assume IBMPC or another IBMPC-based sets as default if there + is no CHRS or CHARSET kludge. For areas where IBMPC is assumed, you + should set both XLATIMPORT and XLATEXPORT to IBMPC or CP850. + +* Screen color changes and cursor movements are made with ANSI + sequences. GoldED for Linux will also work in X terminals, but this + is not recommended because of keyboard limitations. Telnet sessions + should work, if they support the ANSI sequences and produce usable + keycodes. + +* Standard distributions of Linux do not define all the keys that are + usually available on DOS, OS/2 and Win32. Specifically, cursor + movement (arrows, page, home/end) keys don't have separate keycodes + when combined with the shift, control or alt keys. It is possible + (in the keytable maps in /usr/lib/kbd/keytables) to define + non-standard keycodes to make Ctrl-PageUp, Alt-Left etc. work, but I + haven't had time to do this yet. + +* There may be odd quirks in the keyboard handling. Please report if + you find any. + +* The "DOS shell" probably doesn't work. Not tested. + +* The printing feature prints to "/dev/lp". Not tested. + + +Please report only problems that are specific for the Linux version. +General problems have already been reported to death since april '97 +and may already be fixed in the next versions. + + +=== Cut, a basic golded.cfg === + +username Odinn Sorensen +address 2:236/77 +areadef netmail "Netmail" 0 net opus /usr/ftn/netmailx . (loc) +areadef net.fidoz2 "FidoNet Z2" 0 net squish /usr/ftn/fidoz2 . (loc) +areadef zzz.jtest1 "JAM test" 0 echo jam /usr/ftn/jtest1 . (loc) + +=== Cut === + +#page +#--------------------------------------------------------------------- +#chapter Thank you's, Credits and Acknowledgements + +* All GoldED users, for their endless patience and support through + the years. + +* Dirk A. Mueller has been very helpful in all kinds of ways. I just + can't thank him enough! + +* Squish and Maximus are Copyright 1989, 1995 by Lanius Corporation + (Scott J. Dudley). + +* JAM(mbp) - Copyright 1993 Joaquim Homrighausen, Andrew Milner, + Mats Birch, Mats Wallin. ALL RIGHTS RESERVED. + +* Marcantonio Magnarapa made a manual compiler for the GoldED manual + during the 2.50.beta phase, for which I was very grateful. + However, I have since made my own manual compiler. + +* The EXEC v3.3 swapping spawn function by Thomas Wagner is used in + the DOS version to minimize memory use while shelling to DOS and + running other programs. + +* Sourcecode for doing the WaZOO .REQ thing was kindly provided by + Morten Baun. + +* Udo van den Heuvel made the GoldPGP utility, which inspired me to + make GoldED do the same internally. + +* Nicolai Dufva (2:236/100.28) helped with coding for the sound + support in the OS/2 version. + +* Bob Stouts C/C++ SNIPPETS have been a source and inspiration for a + number of functions and classes in my Goldware library. + +* The Free Software Foundation for GPL and LGPL. + +* Linus Torvalds for Linux. + +[this list is incomplete] + +#--------------------------------------------------------------------- +#end +#--------------------------------------------------------------------- diff --git a/rddt/Makefile b/rddt/Makefile new file mode 100644 index 0000000..92ab0e7 --- /dev/null +++ b/rddt/Makefile @@ -0,0 +1,17 @@ +# -*- makefile -*- + +TOP=.. +SHORTTARGET=rddt +TARGET=rddt +INCS=-I$(TOP)/goldlib/gall +ifeq ($(findstring EMX, $(PATH)), EMX) +STDLIBS=-lstdcpp +endif +ifeq ($(TERM),cygwin) +STDLIBS=-luser32 +endif +GLIBS=gall +CLEANS= + +include $(TOP)/GNUmakef.inc +include $(TOP)/GNUmakef.prg diff --git a/rddt/rddt.all b/rddt/rddt.all new file mode 100644 index 0000000..5d4ee1f --- /dev/null +++ b/rddt/rddt.all @@ -0,0 +1,31 @@ + +## ------------------------------------------------------------------ +## The Goldware Utilities. Copyright (C) Odinn Sorensen. +## ------------------------------------------------------------------ +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +## ------------------------------------------------------------------ +## $Id$ +## ------------------------------------------------------------------ +## Master build file. +## ------------------------------------------------------------------ + +rddt cpp all nov bcd bco bcx djg emx lnx rsx wcn wco wcx cyg + +## ------------------------------------------------------------------ + +rddt all all + +## ------------------------------------------------------------------ + diff --git a/rddt/rddt.cpp b/rddt/rddt.cpp new file mode 100644 index 0000000..655993e --- /dev/null +++ b/rddt/rddt.cpp @@ -0,0 +1,471 @@ + +// ------------------------------------------------------------------ +// Route Diagram Drawing Tool. +// Copyright (C) 1999 Odinn Sorensen +// Copyright (C) 1999-2000 Alexander S. Aganichev +// ------------------------------------------------------------------ +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// ------------------------------------------------------------------ +// Designed to work with the Goldware library. May need some work.. +// ------------------------------------------------------------------ +// $Id$ +// ------------------------------------------------------------------ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int debug = false; + + +// ------------------------------------------------------------------ + +class node { + +public: + + node() { order = 0; depth = 0; used = false; posts = 0; } + + bool used; + int order; + int depth; + int posts; + ftn_addr address; + string name; + vector links; + string display; + + void add(const char* s) { ftn_addr n = s; add(n); } + void add(ftn_addr& addr); + + node& operator=(const node& a); + +}; + + +// ------------------------------------------------------------------ + +typedef list list_node; + +// ------------------------------------------------------------------ + +class nodetree { + +public: + + nodetree() { maxname = 0; maxdisp = 0; order = 0; indent = 2; posts = 0; } + + list_node nodes; + + int order; + int maxname; + int maxdisp; + int indent; + int posts; + + void prepare(ftn_addr& previous, ftn_addr& current, int depth); + void sort(); + void print(); + + void add(node& a); + +}; + + +// ------------------------------------------------------------------ + +node& node::operator=(const node& a) { + + used = a.used; + order = a.order; + depth = a.depth; + address = a.address; + name = a.name; + display = a.display; + links = a.links; + return *this; +} + + +// ------------------------------------------------------------------ + +bool equals2d(ftn_addr& a, ftn_addr& b) { + + if(a == b) + return true; + else if((a.net == b.net) and (a.node == b.node) and (a.point == b.point)) + return true; + return false; +} + + +// ------------------------------------------------------------------ + +void node::add(ftn_addr& addr) { + + if(equals2d(addr, address)) + return; + + for(int l=0; lused) { + if(equals2d(n->address, current)) { + n->order = ++order; + n->depth = depth; + n->used = true; + for(int l=0; llinks.size(); l++) { + //if(not equals2d(n->links[l], previous)) + if(n->links[l] != previous) + prepare(current, n->links[l], depth+1); + } + break; + } + } + } +} + + +// ------------------------------------------------------------------ + +bool compare_nodes(node& a, node& b) { + + int cmp = compare_two(a.order ? 0 : 1, b.order ? 0 : 1); + if(cmp) + return (cmp < 0); + cmp = compare_two(a.order, b.order); + if(cmp) + return (cmp < 0); + return (a.address.compare(b.address) < 0); +} + + +// ------------------------------------------------------------------ + +void nodetree::sort() { + + nodes.sort(compare_nodes); +} + + +// ------------------------------------------------------------------ + +void nodetree::print() { + + list_node::iterator n; + + for(n=nodes.begin(); n != nodes.end(); n++) { + char buf[100]; + strsetsz(strcpy(buf, n->name.c_str()), maxname+indent); + n->display = buf; + list_node::iterator x; + bool above, below; + for(int d=1; ddepth; d++) { + above = false; + below = false; + if(d > 0) { + for(x=n; x-- != nodes.begin();) { + if(x->depth < d) + break; + else if(x->depth == d) { + above = true; + break; + } + } + for(x=n; ++x != nodes.end();) { + if(x->depth < d) + break; + else if(x->depth == d) { + below = true; + break; + } + } + } + + if(above and below) + strcpy(buf, "³"); + else + *buf = NUL; + strsetsz(buf, indent); + n->display += buf; + } + + if(n->depth) { + strcpy(buf, "À"); + strsetsz(buf, indent); + strchg(buf, ' ', 'Ä'); + n->display += buf; + } + + n->display += n->address.make_string(buf); + + maxdisp = maximum_of_two((size_t)maxdisp, n->display.length()); + } + + for(n=nodes.begin(); n != nodes.end(); n++) { + list_node::iterator x=n; + if(++x != nodes.end()) { + const char* p = strchr(n->display.c_str(), 'À'); + if(p) { + int len = p - n->display.c_str(); + if((x->display[len] == '³') or (x->display[len] == 'À')) + n->display[len] = 'Ã'; + } + } + n->display.resize(maxdisp, ' '); + char buf[40]; + sprintf(buf, "%*s[%i]", indent, "", n->depth); + n->display += buf; + } + + for(n=nodes.begin(); n != nodes.end(); n++) + cout << n->display.c_str() << endl; +} + + +// ------------------------------------------------------------------ + +int main(int argc, char** argv) { + + throw_init(); + + // set locale + setlocale(LC_CTYPE, ""); + + cout << "Route Diagram Drawing Tool 1.1" << endl + << "Copyright (C) 1999 Odinn Sorensen" << endl + << "Copyright (C) 1999-2000 Alexander S. Aganichev" << endl + << "----------------------------------------------------------------------" << endl + << endl; + + if(argc < 2) { + cout << "Syntax: RDDT [address or name]" << endl; + return 1; + } + + #if defined(GUTLOS_FUNCS) + g_init_os(0); + #endif + + node anode; + nodetree atree; + ifstream fp(argv[1]); + ftn_addr address; + bool decode_path = false; + char* top = NULL; + ftn_addr ownaddress; + ftn_addr ownuplink; + + for(int argn=2; argn 1) { + anode.links.resize(0); + strchg(&links[0][0], '_', ' '); + anode.name = links[0]; + atree.maxname = maximum_of_two(anode.name.length(), (size_t)atree.maxname); + anode.address = links[1]; + if(links.size() > 2) { + if(decode_path) { + anode.posts++; + atree.posts++; + int n; + address = links[2]; + if(not equals2d(address, anode.address)) + anode.add(address); + for(n=3; naddress.match(match)) { + xnode = *n; + address = n->address; + break; + } + } + } + else { + for(list_node::iterator n=atree.nodes.begin(); n != atree.nodes.end(); n++) { + if(n->name.find(top) != n->name.npos) { + xnode = *n; + address = n->address; + break; + } + } + } + + if(address.valid()) { + + if(debug) { + char buf[50]; + for(list_node::iterator n=atree.nodes.begin(); n != atree.nodes.end(); n++) { + xnode = *n; + cout << xnode.address.make_string(buf) << endl; + for(int l=0; l

[DLE] + Key_C_Q & 0xFF00u, // 0x1011 C [DC1] + Key_C_R & 0xFF00u, // 0x1312 C [DC2] + Key_C_S & 0xFF00u, // 0x1F13 C [DC3] + Key_C_T & 0xFF00u, // 0x1414 C [DC4] + Key_C_U & 0xFF00u, // 0x1615 C [NAK] + Key_C_V & 0xFF00u, // 0x2F16 C [SYN] + Key_C_W & 0xFF00u, // 0x1117 C [ETB] + Key_C_X & 0xFF00u, // 0x2D18 C [CAN] + Key_C_Y & 0xFF00u, // 0x1519 C [EM] + Key_C_Z & 0xFF00u, // 0x2C1A C [SUB] + Key_Esc & 0xFF00u, // 0x011B C <[ {> [ESC] (was: 0x1A1B) + Key_C_Bsl & 0xFF00u, // 0x2B1C C <\ |> [FS] + Key_C_Rbr & 0xFF00u, // 0x1B1D C <] }> [GS] + Key_C_6 & 0xFF00u, // 0x071E C <7 &> [RS] + Key_C_Min & 0xFF00u, // 0x0C1F C <- _> + Key_Space & 0xFF00u, // 0x3920 + Key_S_1 & 0xFF00u, // 0x0221 <1 !> + Key_S_Quo & 0xFF00u, // 0x2822 <' "> + Key_S_3 & 0xFF00u, // 0x0423 <3 #> + Key_S_4 & 0xFF00u, // 0x0524 <4 $> + Key_S_5 & 0xFF00u, // 0x0625 <5 %> + Key_S_7 & 0xFF00u, // 0x0826 <7 &> + Key_Quo & 0xFF00u, // 0x2827 <'> + Key_S_9 & 0xFF00u, // 0x0A28 <9 (> + Key_S_0 & 0xFF00u, // 0x0B29 <0 )> + Key_S_8 & 0xFF00u, // 0x092A <8 *> + Key_S_Equ & 0xFF00u, // 0x0D2B <= +> + Key_Com & 0xFF00u, // 0x332C <,> + Key_Min & 0xFF00u, // 0x0C2D <-> + Key_Dot & 0xFF00u, // 0x342E <.> + Key_Sls & 0xFF00u, // 0x352F + Key_0 & 0xFF00u, // 0x0B30 <0> + Key_1 & 0xFF00u, // 0x0231 <1> + Key_2 & 0xFF00u, // 0x0332 <2> + Key_3 & 0xFF00u, // 0x0433 <3> + Key_4 & 0xFF00u, // 0x0534 <4> + Key_5 & 0xFF00u, // 0x0635 <5> + Key_6 & 0xFF00u, // 0x0736 <6> + Key_7 & 0xFF00u, // 0x0837 <7> + Key_8 & 0xFF00u, // 0x0938 <8> + Key_9 & 0xFF00u, // 0x0A39 <9> + Key_S_Smi & 0xFF00u, // 0x273A <; :> + Key_Smi & 0xFF00u, // 0x273B <;> + Key_S_Com & 0xFF00u, // 0x333C <, >> + Key_Equ & 0xFF00u, // 0x0D3D <=> + Key_S_Dot & 0xFF00u, // 0x343E <. <> + Key_S_Sls & 0xFF00u, // 0x353F + Key_S_2 & 0xFF00u, // 0x0340 <2 @> + Key_S_A & 0xFF00u, // 0x1E41 + Key_S_B & 0xFF00u, // 0x3042 + Key_S_C & 0xFF00u, // 0x2E43 + Key_S_D & 0xFF00u, // 0x2044 + Key_S_E & 0xFF00u, // 0x1245 + Key_S_F & 0xFF00u, // 0x2146 + Key_S_G & 0xFF00u, // 0x2247 + Key_S_H & 0xFF00u, // 0x2348 + Key_S_I & 0xFF00u, // 0x1749 + Key_S_J & 0xFF00u, // 0x244A + Key_S_K & 0xFF00u, // 0x254B + Key_S_L & 0xFF00u, // 0x264C + Key_S_M & 0xFF00u, // 0x324D + Key_S_N & 0xFF00u, // 0x314E + Key_S_O & 0xFF00u, // 0x184F + Key_S_P & 0xFF00u, // 0x1950