From b8f77937735ee1339a62a524bcb0253eed96015f Mon Sep 17 00:00:00 2001 From: Brad Arant Date: Tue, 6 Oct 2026 17:42:01 +0000 Subject: [PATCH] Add global music player, invoicing/payment system, account subpages, mail account admin, and the qualityiron.vegas Jet 2.0 port Jet interpreter (Tag.cpp, __call.cpp, __imap*.cpp/h, __smtpsend.cpp/h, __imapemptyfolder.cpp/h - new): assorted parser/tag fixes found across this work - a stray literal-tag-in-comment and backslash-quote parser corruption class, a dangling-pointer fix, a __call.cpp fd leak, IMAP folder-management tags, multi-account/per-host IMAP support, and a smtpsend Message-ID fix. barant.com site (jetc/barant-site/): - A site-wide persistent music player (header band, playlist/queue, stereo FFT EQ, session-persisted state) fed by new library/ ianslibrary/music song-list subpages. - /account split into info/phones/invoices subpages; a full invoicing and Square payment system (create/edit/copy/pay/email invoice); admin invoice management and mail-account management subpages. - /services split into overview/hosting/siptrunking/documents subpages, retiring the old standalone pages. - SIPPHONE.tag: a Jet 2.0 WebRTC softphone tag. - main.css/spa.js/email.js: the SPA loading indicator, the music player band styling, and assorted fixes accumulated alongside this work. qualityiron-site/: the qualityiron.vegas job/contractor/customer/ document management app, ported from its original Jet 1.4 codebase to Jet 2.0 as barant.coms APIServers second multi-tenant site. wcwc/wcwc.jet: the WCWC site Jet source (wcwc.jtc build output not included). Co-Authored-By: Claude Sonnet 5 --- Tag.cpp | 85 +- __call.cpp | 99 +- __imap.cpp | 29 +- __imap.h | 9 + __imapaccounts.cpp | 62 +- __imapaccounts.h | 37 +- __imapemptyfolder.cpp | 26 + __imapemptyfolder.h | 26 + __smtpsend.cpp | 23 + __smtpsend.h | 1 + jetc/barant-site/assets/images/btglogo.png | Bin 1410423 -> 522240 bytes jetc/barant-site/assets/images/email.js | 70 +- jetc/barant-site/assets/images/main.css | 545 ++++- jetc/barant-site/assets/images/spa.js | 28 + jetc/barant-site/src/SIPPHONE.tag | 421 ++++ jetc/barant-site/src/account-info.subpage | 83 + jetc/barant-site/src/account-invoices.subpage | 18 + jetc/barant-site/src/account-phones.subpage | 4 + jetc/barant-site/src/account.menu | 17 + jetc/barant-site/src/account.page | 114 +- jetc/barant-site/src/admin-email.subpage | 14 +- jetc/barant-site/src/admin-invoice.subpage | 46 + jetc/barant-site/src/admin-invoices.subpage | 121 +- .../src/admin-mailaccounts.subpage | 98 + jetc/barant-site/src/admin.menu | 29 +- jetc/barant-site/src/admin.page | 30 +- jetc/barant-site/src/admin_invoice.page | 11 - jetc/barant-site/src/adminmenu.section | 2 +- jetc/barant-site/src/barant.tag | 4 +- jetc/barant-site/src/copy_invoice.jet | 29 + jetc/barant-site/src/create_invoice.jet | 21 + jetc/barant-site/src/editinvoice.page | 172 +- jetc/barant-site/src/email.jet | 68 +- jetc/barant-site/src/invoice.method | 77 +- jetc/barant-site/src/jukebox.page | 67 - jetc/barant-site/src/login.method | 15 +- jetc/barant-site/src/mail_invoice.jet | 26 + jetc/barant-site/src/mailaccounts.jet | 43 + jetc/barant-site/src/main-ianslibrary.subpage | 7 + jetc/barant-site/src/main-library.subpage | 7 + jetc/barant-site/src/main-music.subpage | 7 + jetc/barant-site/src/main-overview.subpage | 23 + jetc/barant-site/src/main.menu | 26 +- jetc/barant-site/src/main.page | 34 +- jetc/barant-site/src/mainpagetemplate.jet | 753 ++++++- jetc/barant-site/src/menu.bar | 15 +- jetc/barant-site/src/modular1_patches.page | 4 +- jetc/barant-site/src/music.page | 47 - jetc/barant-site/src/payinvoice.page | 15 +- jetc/barant-site/src/payment.method | 50 +- jetc/barant-site/src/phones.section | 7 +- jetc/barant-site/src/selectinvoice.proc | 2 +- .../barant-site/src/send_invoice_email.method | 27 + ...uments.page => services-documents.subpage} | 5 - ...{hosting.page => services-hosting.subpage} | 9 +- .../barant-site/src/services-overview.subpage | 45 + ...runk.page => services-siptrunking.subpage} | 11 +- jetc/barant-site/src/services.menu | 22 + jetc/barant-site/src/services.page | 56 +- jetc/barant-site/src/setplayerstate.proc | 1 + jetc/barant-site/src/setvolume.proc | 1 + jetc/barant-site/src/update_invoice.proc | 9 +- .../assets/ckeditor/CHANGES.md | 1675 +++++++++++++++ .../assets/ckeditor/LICENSE.md | 1420 +++++++++++++ .../assets/ckeditor/README.md | 39 + .../assets/ckeditor/build-config.js | 166 ++ .../assets/ckeditor/ckeditor.js | 1231 ++++++++++++ .../assets/ckeditor/config.js | 38 + .../assets/ckeditor/contents.css | 208 ++ .../assets/ckeditor/lang/af.js | 5 + .../assets/ckeditor/lang/ar.js | 5 + .../assets/ckeditor/lang/az.js | 5 + .../assets/ckeditor/lang/bg.js | 5 + .../assets/ckeditor/lang/bn.js | 5 + .../assets/ckeditor/lang/bs.js | 5 + .../assets/ckeditor/lang/ca.js | 5 + .../assets/ckeditor/lang/cs.js | 5 + .../assets/ckeditor/lang/cy.js | 5 + .../assets/ckeditor/lang/da.js | 5 + .../assets/ckeditor/lang/de-ch.js | 5 + .../assets/ckeditor/lang/de.js | 5 + .../assets/ckeditor/lang/el.js | 5 + .../assets/ckeditor/lang/en-au.js | 5 + .../assets/ckeditor/lang/en-ca.js | 5 + .../assets/ckeditor/lang/en-gb.js | 5 + .../assets/ckeditor/lang/en.js | 5 + .../assets/ckeditor/lang/eo.js | 5 + .../assets/ckeditor/lang/es-mx.js | 5 + .../assets/ckeditor/lang/es.js | 5 + .../assets/ckeditor/lang/et.js | 5 + .../assets/ckeditor/lang/eu.js | 5 + .../assets/ckeditor/lang/fa.js | 5 + .../assets/ckeditor/lang/fi.js | 5 + .../assets/ckeditor/lang/fo.js | 5 + .../assets/ckeditor/lang/fr-ca.js | 5 + .../assets/ckeditor/lang/fr.js | 5 + .../assets/ckeditor/lang/gl.js | 5 + .../assets/ckeditor/lang/gu.js | 5 + .../assets/ckeditor/lang/he.js | 5 + .../assets/ckeditor/lang/hi.js | 5 + .../assets/ckeditor/lang/hr.js | 5 + .../assets/ckeditor/lang/hu.js | 5 + .../assets/ckeditor/lang/id.js | 5 + .../assets/ckeditor/lang/is.js | 5 + .../assets/ckeditor/lang/it.js | 5 + .../assets/ckeditor/lang/ja.js | 5 + .../assets/ckeditor/lang/ka.js | 5 + .../assets/ckeditor/lang/km.js | 5 + .../assets/ckeditor/lang/ko.js | 5 + .../assets/ckeditor/lang/ku.js | 5 + .../assets/ckeditor/lang/lt.js | 5 + .../assets/ckeditor/lang/lv.js | 5 + .../assets/ckeditor/lang/mk.js | 5 + .../assets/ckeditor/lang/mn.js | 5 + .../assets/ckeditor/lang/ms.js | 5 + .../assets/ckeditor/lang/nb.js | 5 + .../assets/ckeditor/lang/nl.js | 5 + .../assets/ckeditor/lang/no.js | 5 + .../assets/ckeditor/lang/oc.js | 5 + .../assets/ckeditor/lang/pl.js | 5 + .../assets/ckeditor/lang/pt-br.js | 5 + .../assets/ckeditor/lang/pt.js | 5 + .../assets/ckeditor/lang/ro.js | 5 + .../assets/ckeditor/lang/ru.js | 5 + .../assets/ckeditor/lang/si.js | 5 + .../assets/ckeditor/lang/sk.js | 5 + .../assets/ckeditor/lang/sl.js | 5 + .../assets/ckeditor/lang/sq.js | 5 + .../assets/ckeditor/lang/sr-latn.js | 5 + .../assets/ckeditor/lang/sr.js | 5 + .../assets/ckeditor/lang/sv.js | 5 + .../assets/ckeditor/lang/th.js | 5 + .../assets/ckeditor/lang/tr.js | 5 + .../assets/ckeditor/lang/tt.js | 5 + .../assets/ckeditor/lang/ug.js | 5 + .../assets/ckeditor/lang/uk.js | 5 + .../assets/ckeditor/lang/vi.js | 5 + .../assets/ckeditor/lang/zh-cn.js | 5 + .../assets/ckeditor/lang/zh.js | 5 + .../plugins/a11yhelp/dialogs/a11yhelp.js | 10 + .../dialogs/lang/_translationstatus.txt | 25 + .../plugins/a11yhelp/dialogs/lang/af.js | 11 + .../plugins/a11yhelp/dialogs/lang/ar.js | 11 + .../plugins/a11yhelp/dialogs/lang/az.js | 11 + .../plugins/a11yhelp/dialogs/lang/bg.js | 11 + .../plugins/a11yhelp/dialogs/lang/ca.js | 13 + .../plugins/a11yhelp/dialogs/lang/cs.js | 12 + .../plugins/a11yhelp/dialogs/lang/cy.js | 11 + .../plugins/a11yhelp/dialogs/lang/da.js | 11 + .../plugins/a11yhelp/dialogs/lang/de-ch.js | 12 + .../plugins/a11yhelp/dialogs/lang/de.js | 13 + .../plugins/a11yhelp/dialogs/lang/el.js | 13 + .../plugins/a11yhelp/dialogs/lang/en-au.js | 11 + .../plugins/a11yhelp/dialogs/lang/en-gb.js | 11 + .../plugins/a11yhelp/dialogs/lang/en.js | 11 + .../plugins/a11yhelp/dialogs/lang/eo.js | 13 + .../plugins/a11yhelp/dialogs/lang/es-mx.js | 13 + .../plugins/a11yhelp/dialogs/lang/es.js | 13 + .../plugins/a11yhelp/dialogs/lang/et.js | 11 + .../plugins/a11yhelp/dialogs/lang/eu.js | 12 + .../plugins/a11yhelp/dialogs/lang/fa.js | 11 + .../plugins/a11yhelp/dialogs/lang/fi.js | 11 + .../plugins/a11yhelp/dialogs/lang/fo.js | 11 + .../plugins/a11yhelp/dialogs/lang/fr-ca.js | 11 + .../plugins/a11yhelp/dialogs/lang/fr.js | 13 + .../plugins/a11yhelp/dialogs/lang/gl.js | 12 + .../plugins/a11yhelp/dialogs/lang/gu.js | 11 + .../plugins/a11yhelp/dialogs/lang/he.js | 11 + .../plugins/a11yhelp/dialogs/lang/hi.js | 11 + .../plugins/a11yhelp/dialogs/lang/hr.js | 11 + .../plugins/a11yhelp/dialogs/lang/hu.js | 12 + .../plugins/a11yhelp/dialogs/lang/id.js | 11 + .../plugins/a11yhelp/dialogs/lang/it.js | 13 + .../plugins/a11yhelp/dialogs/lang/ja.js | 9 + .../plugins/a11yhelp/dialogs/lang/km.js | 11 + .../plugins/a11yhelp/dialogs/lang/ko.js | 10 + .../plugins/a11yhelp/dialogs/lang/ku.js | 11 + .../plugins/a11yhelp/dialogs/lang/lt.js | 11 + .../plugins/a11yhelp/dialogs/lang/lv.js | 12 + .../plugins/a11yhelp/dialogs/lang/mk.js | 11 + .../plugins/a11yhelp/dialogs/lang/mn.js | 11 + .../plugins/a11yhelp/dialogs/lang/nb.js | 12 + .../plugins/a11yhelp/dialogs/lang/nl.js | 12 + .../plugins/a11yhelp/dialogs/lang/no.js | 11 + .../plugins/a11yhelp/dialogs/lang/oc.js | 12 + .../plugins/a11yhelp/dialogs/lang/pl.js | 13 + .../plugins/a11yhelp/dialogs/lang/pt-br.js | 13 + .../plugins/a11yhelp/dialogs/lang/pt.js | 12 + .../plugins/a11yhelp/dialogs/lang/ro.js | 12 + .../plugins/a11yhelp/dialogs/lang/ru.js | 11 + .../plugins/a11yhelp/dialogs/lang/si.js | 10 + .../plugins/a11yhelp/dialogs/lang/sk.js | 11 + .../plugins/a11yhelp/dialogs/lang/sl.js | 11 + .../plugins/a11yhelp/dialogs/lang/sq.js | 12 + .../plugins/a11yhelp/dialogs/lang/sr-latn.js | 11 + .../plugins/a11yhelp/dialogs/lang/sr.js | 11 + .../plugins/a11yhelp/dialogs/lang/sv.js | 11 + .../plugins/a11yhelp/dialogs/lang/th.js | 11 + .../plugins/a11yhelp/dialogs/lang/tr.js | 12 + .../plugins/a11yhelp/dialogs/lang/tt.js | 11 + .../plugins/a11yhelp/dialogs/lang/ug.js | 12 + .../plugins/a11yhelp/dialogs/lang/uk.js | 12 + .../plugins/a11yhelp/dialogs/lang/vi.js | 11 + .../plugins/a11yhelp/dialogs/lang/zh-cn.js | 9 + .../plugins/a11yhelp/dialogs/lang/zh.js | 9 + .../ckeditor/plugins/about/dialogs/about.js | 8 + .../about/dialogs/hidpi/logo_ckeditor.png | Bin 0 -> 12236 bytes .../plugins/about/dialogs/logo_ckeditor.png | Bin 0 -> 5650 bytes .../plugins/clipboard/dialogs/paste.js | 11 + .../plugins/dialog/dialogDefinition.js | 4 + .../assets/ckeditor/plugins/icons.png | Bin 0 -> 5881 bytes .../assets/ckeditor/plugins/icons_hidpi.png | Bin 0 -> 20430 bytes .../ckeditor/plugins/image/dialogs/image.js | 44 + .../ckeditor/plugins/image/images/noimage.png | Bin 0 -> 1610 bytes .../ckeditor/plugins/link/dialogs/anchor.js | 8 + .../ckeditor/plugins/link/dialogs/link.js | 30 + .../ckeditor/plugins/link/images/anchor.png | Bin 0 -> 752 bytes .../plugins/link/images/hidpi/anchor.png | Bin 0 -> 1109 bytes .../magicline/images/hidpi/icon-rtl.png | Bin 0 -> 176 bytes .../plugins/magicline/images/hidpi/icon.png | Bin 0 -> 199 bytes .../plugins/magicline/images/icon-rtl.png | Bin 0 -> 138 bytes .../plugins/magicline/images/icon.png | Bin 0 -> 133 bytes .../plugins/pastefromword/filter/default.js | 55 + .../ckeditor/plugins/scayt/CHANGELOG.md | 20 + .../assets/ckeditor/plugins/scayt/LICENSE.md | 28 + .../assets/ckeditor/plugins/scayt/README.md | 25 + .../ckeditor/plugins/scayt/dialogs/dialog.css | 23 + .../ckeditor/plugins/scayt/dialogs/options.js | 32 + .../plugins/scayt/dialogs/toolbar.css | 71 + .../plugins/scayt/skins/moono-lisa/scayt.css | 25 + .../dialogs/lang/_translationstatus.txt | 20 + .../plugins/specialchar/dialogs/lang/af.js | 13 + .../plugins/specialchar/dialogs/lang/ar.js | 13 + .../plugins/specialchar/dialogs/lang/az.js | 10 + .../plugins/specialchar/dialogs/lang/bg.js | 13 + .../plugins/specialchar/dialogs/lang/ca.js | 14 + .../plugins/specialchar/dialogs/lang/cs.js | 13 + .../plugins/specialchar/dialogs/lang/cy.js | 14 + .../plugins/specialchar/dialogs/lang/da.js | 11 + .../plugins/specialchar/dialogs/lang/de-ch.js | 13 + .../plugins/specialchar/dialogs/lang/de.js | 13 + .../plugins/specialchar/dialogs/lang/el.js | 13 + .../plugins/specialchar/dialogs/lang/en-au.js | 13 + .../plugins/specialchar/dialogs/lang/en-ca.js | 13 + .../plugins/specialchar/dialogs/lang/en-gb.js | 13 + .../plugins/specialchar/dialogs/lang/en.js | 13 + .../plugins/specialchar/dialogs/lang/eo.js | 12 + .../plugins/specialchar/dialogs/lang/es-mx.js | 13 + .../plugins/specialchar/dialogs/lang/es.js | 13 + .../plugins/specialchar/dialogs/lang/et.js | 13 + .../plugins/specialchar/dialogs/lang/eu.js | 13 + .../plugins/specialchar/dialogs/lang/fa.js | 12 + .../plugins/specialchar/dialogs/lang/fi.js | 13 + .../plugins/specialchar/dialogs/lang/fr-ca.js | 10 + .../plugins/specialchar/dialogs/lang/fr.js | 12 + .../plugins/specialchar/dialogs/lang/gl.js | 13 + .../plugins/specialchar/dialogs/lang/he.js | 12 + .../plugins/specialchar/dialogs/lang/hr.js | 13 + .../plugins/specialchar/dialogs/lang/hu.js | 12 + .../plugins/specialchar/dialogs/lang/id.js | 13 + .../plugins/specialchar/dialogs/lang/it.js | 14 + .../plugins/specialchar/dialogs/lang/ja.js | 9 + .../plugins/specialchar/dialogs/lang/km.js | 13 + .../plugins/specialchar/dialogs/lang/ko.js | 10 + .../plugins/specialchar/dialogs/lang/ku.js | 13 + .../plugins/specialchar/dialogs/lang/lt.js | 13 + .../plugins/specialchar/dialogs/lang/lv.js | 13 + .../plugins/specialchar/dialogs/lang/nb.js | 11 + .../plugins/specialchar/dialogs/lang/nl.js | 13 + .../plugins/specialchar/dialogs/lang/no.js | 11 + .../plugins/specialchar/dialogs/lang/oc.js | 12 + .../plugins/specialchar/dialogs/lang/pl.js | 12 + .../plugins/specialchar/dialogs/lang/pt-br.js | 11 + .../plugins/specialchar/dialogs/lang/pt.js | 13 + .../plugins/specialchar/dialogs/lang/ro.js | 13 + .../plugins/specialchar/dialogs/lang/ru.js | 13 + .../plugins/specialchar/dialogs/lang/si.js | 13 + .../plugins/specialchar/dialogs/lang/sk.js | 13 + .../plugins/specialchar/dialogs/lang/sl.js | 12 + .../plugins/specialchar/dialogs/lang/sq.js | 13 + .../plugins/specialchar/dialogs/lang/sv.js | 11 + .../plugins/specialchar/dialogs/lang/th.js | 13 + .../plugins/specialchar/dialogs/lang/tr.js | 12 + .../plugins/specialchar/dialogs/lang/tt.js | 13 + .../plugins/specialchar/dialogs/lang/ug.js | 13 + .../plugins/specialchar/dialogs/lang/uk.js | 12 + .../plugins/specialchar/dialogs/lang/vi.js | 14 + .../plugins/specialchar/dialogs/lang/zh-cn.js | 9 + .../plugins/specialchar/dialogs/lang/zh.js | 9 + .../specialchar/dialogs/specialchar.js | 14 + .../ckeditor/plugins/table/dialogs/table.js | 21 + .../tableselection/styles/tableselection.css | 36 + .../plugins/tabletools/dialogs/tableCell.js | 19 + .../ckeditor/plugins/widget/images/handle.png | Bin 0 -> 220 bytes .../assets/ckeditor/plugins/wsc/LICENSE.md | 28 + .../assets/ckeditor/plugins/wsc/README.md | 25 + .../ckeditor/plugins/wsc/dialogs/ciframe.html | 66 + .../plugins/wsc/dialogs/tmpFrameset.html | 52 + .../ckeditor/plugins/wsc/dialogs/wsc.css | 82 + .../ckeditor/plugins/wsc/dialogs/wsc.js | 91 + .../ckeditor/plugins/wsc/dialogs/wsc_ie.js | 11 + .../plugins/wsc/skins/moono-lisa/wsc.css | 43 + .../ckeditor/skins/moono-lisa/dialog.css | 5 + .../ckeditor/skins/moono-lisa/dialog_ie.css | 5 + .../ckeditor/skins/moono-lisa/dialog_ie8.css | 5 + .../skins/moono-lisa/dialog_iequirks.css | 5 + .../ckeditor/skins/moono-lisa/editor.css | 5 + .../skins/moono-lisa/editor_gecko.css | 5 + .../ckeditor/skins/moono-lisa/editor_ie.css | 5 + .../ckeditor/skins/moono-lisa/editor_ie8.css | 5 + .../skins/moono-lisa/editor_iequirks.css | 5 + .../ckeditor/skins/moono-lisa/icons.png | Bin 0 -> 5881 bytes .../ckeditor/skins/moono-lisa/icons_hidpi.png | Bin 0 -> 20430 bytes .../skins/moono-lisa/images/arrow.png | Bin 0 -> 191 bytes .../skins/moono-lisa/images/close.png | Bin 0 -> 615 bytes .../skins/moono-lisa/images/hidpi/close.png | Bin 0 -> 1238 bytes .../moono-lisa/images/hidpi/lock-open.png | Bin 0 -> 1071 bytes .../skins/moono-lisa/images/hidpi/lock.png | Bin 0 -> 1062 bytes .../skins/moono-lisa/images/hidpi/refresh.png | Bin 0 -> 1623 bytes .../skins/moono-lisa/images/lock-open.png | Bin 0 -> 511 bytes .../ckeditor/skins/moono-lisa/images/lock.png | Bin 0 -> 506 bytes .../skins/moono-lisa/images/refresh.png | Bin 0 -> 757 bytes .../skins/moono-lisa/images/spinner.gif | Bin 0 -> 2984 bytes .../ckeditor/skins/moono-lisa/readme.md | 46 + .../assets/ckeditor/styles.js | 137 ++ .../qualityiron-site/assets/images/delete.png | Bin 0 -> 11542 bytes .../qualityiron-site/assets/images/jobdocs.js | 184 ++ .../assets/images/magglass.png | Bin 0 -> 1060 bytes jetc/qualityiron-site/assets/images/main.css | 83 + jetc/qualityiron-site/assets/images/open.png | Bin 0 -> 4463 bytes jetc/qualityiron-site/assets/images/plus.png | Bin 0 -> 1096 bytes .../assets/images/qi_logo.png | Bin 0 -> 42015 bytes jetc/qualityiron-site/assets/images/spa.js | 346 ++++ jetc/qualityiron-site/src/SESSIONCTL.tag | 255 +++ jetc/qualityiron-site/src/addjobaddress.proc | 16 + jetc/qualityiron-site/src/addjobcontact.proc | 12 + jetc/qualityiron-site/src/addjobnotation.proc | 10 + jetc/qualityiron-site/src/admin.page | 12 + jetc/qualityiron-site/src/contractor.card | 15 + jetc/qualityiron-site/src/contractor.form | 17 + jetc/qualityiron-site/src/contractor.page | 70 + jetc/qualityiron-site/src/contractors.page | 65 + .../src/createcontractor.page | 14 + .../src/createcontractor.proc | 20 + jetc/qualityiron-site/src/createcustomer.page | 14 + jetc/qualityiron-site/src/createcustomer.proc | 9 + jetc/qualityiron-site/src/createrole.proc | 4 + jetc/qualityiron-site/src/createstatus.proc | 6 + jetc/qualityiron-site/src/createsubtype.proc | 4 + jetc/qualityiron-site/src/createtype.proc | 4 + jetc/qualityiron-site/src/createuser.page | 14 + jetc/qualityiron-site/src/createuser.proc | 11 + jetc/qualityiron-site/src/customer.card | 7 + jetc/qualityiron-site/src/customer.form | 1 + jetc/qualityiron-site/src/customer.page | 61 + jetc/qualityiron-site/src/customers.page | 58 + .../src/deletejobaddress.proc | 3 + .../src/deletejobcontact.proc | 3 + jetc/qualityiron-site/src/deleterole.proc | 3 + jetc/qualityiron-site/src/deletestatus.proc | 3 + jetc/qualityiron-site/src/deletesubtype.proc | 3 + jetc/qualityiron-site/src/deletetype.proc | 3 + jetc/qualityiron-site/src/deleteuser.proc | 3 + jetc/qualityiron-site/src/drawing.page | 36 + jetc/qualityiron-site/src/editcontractor.page | 26 + jetc/qualityiron-site/src/editcustomer.page | 18 + jetc/qualityiron-site/src/editdoctypes.page | 43 + jetc/qualityiron-site/src/editstatus.page | 40 + jetc/qualityiron-site/src/edituser.page | 23 + jetc/qualityiron-site/src/email.page | 6 + jetc/qualityiron-site/src/functions.menu | 29 + jetc/qualityiron-site/src/home.page | 125 ++ jetc/qualityiron-site/src/job.notations | 29 + jetc/qualityiron-site/src/job.page | 268 +++ jetc/qualityiron-site/src/jobdocs.jet | 2 + jetc/qualityiron-site/src/jobdocs.page | 133 ++ jetc/qualityiron-site/src/jobdocs_api.jet | 84 + jetc/qualityiron-site/src/jobfolder.form | 115 ++ jetc/qualityiron-site/src/jobs.list | 104 + jetc/qualityiron-site/src/jobs.page | 102 + jetc/qualityiron-site/src/login.bar | 4 + jetc/qualityiron-site/src/login.method | 14 + jetc/qualityiron-site/src/login.page | 20 + jetc/qualityiron-site/src/login.proc | 3 + jetc/qualityiron-site/src/logout.proc | 6 + .../qualityiron-site/src/mainpagetemplate.jet | 127 ++ jetc/qualityiron-site/src/profile.page | 61 + jetc/qualityiron-site/src/roles.page | 36 + .../src/selectcontractor.proc | 3 + jetc/qualityiron-site/src/selectcustomer.proc | 3 + jetc/qualityiron-site/src/selectjob.proc | 3 + jetc/qualityiron-site/src/selectuser.proc | 3 + jetc/qualityiron-site/src/setreview.proc | 9 + .../src/updatecontractor.proc | 18 + jetc/qualityiron-site/src/updatecustomer.proc | 8 + jetc/qualityiron-site/src/updatejobdates.proc | 18 + .../qualityiron-site/src/updatejobfolder.proc | 173 ++ jetc/qualityiron-site/src/updaterole.proc | 4 + jetc/qualityiron-site/src/updatestatus.proc | 6 + .../src/updatestatususer.proc | 11 + jetc/qualityiron-site/src/updatesubtype.proc | 4 + jetc/qualityiron-site/src/updatetype.proc | 4 + jetc/qualityiron-site/src/updateuser.proc | 13 + jetc/qualityiron-site/src/user.form | 14 + jetc/qualityiron-site/src/users.page | 36 + jetc/wcwc/wcwc.jet | 1790 +++++++++++++++++ 406 files changed, 15803 insertions(+), 587 deletions(-) create mode 100644 __imapemptyfolder.cpp create mode 100644 __imapemptyfolder.h create mode 100644 jetc/barant-site/src/SIPPHONE.tag create mode 100644 jetc/barant-site/src/account-info.subpage create mode 100644 jetc/barant-site/src/account-invoices.subpage create mode 100644 jetc/barant-site/src/account-phones.subpage create mode 100644 jetc/barant-site/src/account.menu create mode 100644 jetc/barant-site/src/admin-invoice.subpage create mode 100644 jetc/barant-site/src/admin-mailaccounts.subpage delete mode 100755 jetc/barant-site/src/admin_invoice.page create mode 100644 jetc/barant-site/src/copy_invoice.jet create mode 100644 jetc/barant-site/src/create_invoice.jet mode change 100755 => 100644 jetc/barant-site/src/editinvoice.page delete mode 100755 jetc/barant-site/src/jukebox.page create mode 100644 jetc/barant-site/src/mail_invoice.jet create mode 100644 jetc/barant-site/src/mailaccounts.jet create mode 100644 jetc/barant-site/src/main-ianslibrary.subpage create mode 100644 jetc/barant-site/src/main-library.subpage create mode 100644 jetc/barant-site/src/main-music.subpage create mode 100644 jetc/barant-site/src/main-overview.subpage delete mode 100755 jetc/barant-site/src/music.page create mode 100644 jetc/barant-site/src/send_invoice_email.method rename jetc/barant-site/src/{documents.page => services-documents.subpage} (96%) mode change 100755 => 100644 rename jetc/barant-site/src/{hosting.page => services-hosting.subpage} (89%) mode change 100755 => 100644 create mode 100644 jetc/barant-site/src/services-overview.subpage rename jetc/barant-site/src/{siptrunk.page => services-siptrunking.subpage} (92%) mode change 100755 => 100644 create mode 100644 jetc/barant-site/src/services.menu create mode 100644 jetc/barant-site/src/setplayerstate.proc create mode 100644 jetc/barant-site/src/setvolume.proc create mode 100644 jetc/qualityiron-site/assets/ckeditor/CHANGES.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/LICENSE.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/README.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/build-config.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/ckeditor.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/config.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/contents.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/af.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ar.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/az.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/bg.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/bn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/bs.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/cs.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/cy.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/da.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/de-ch.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/de.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/el.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/en-au.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/en-ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/en-gb.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/en.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/eo.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/es-mx.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/es.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/et.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/eu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/fa.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/fi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/fo.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/fr-ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/fr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/gl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/gu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/he.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/hi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/hr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/hu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/id.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/is.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/it.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ja.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ka.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/km.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ko.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ku.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/lt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/lv.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/mk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/mn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ms.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/nb.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/nl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/no.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/oc.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/pl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/pt-br.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/pt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ro.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ru.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/si.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/sk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/sl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/sq.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/sr-latn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/sr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/sv.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/th.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/tr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/tt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/ug.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/uk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/vi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/zh-cn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/lang/zh.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/_translationstatus.txt create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/af.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ar.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/az.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/bg.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/cs.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/cy.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/da.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/de-ch.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/de.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/el.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/en-au.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/en-gb.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/en.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/eo.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/es-mx.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/es.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/et.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/eu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/fa.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/fi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/fo.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/fr-ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/fr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/gl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/gu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/he.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/hi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/hr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/hu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/id.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/it.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ja.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/km.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ko.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ku.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/lt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/lv.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/mk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/mn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/nb.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/nl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/no.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/oc.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/pl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/pt-br.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/pt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ro.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ru.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/si.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/sk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/sl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/sq.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/sr-latn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/sr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/sv.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/th.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/tr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/tt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/ug.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/uk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/vi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/zh-cn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/a11yhelp/dialogs/lang/zh.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/about/dialogs/about.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/about/dialogs/hidpi/logo_ckeditor.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/about/dialogs/logo_ckeditor.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/clipboard/dialogs/paste.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/dialog/dialogDefinition.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/icons.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/icons_hidpi.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/image/dialogs/image.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/image/images/noimage.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/link/dialogs/anchor.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/link/dialogs/link.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/link/images/anchor.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/link/images/hidpi/anchor.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/magicline/images/hidpi/icon-rtl.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/magicline/images/hidpi/icon.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/magicline/images/icon-rtl.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/magicline/images/icon.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/pastefromword/filter/default.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/CHANGELOG.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/LICENSE.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/README.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/dialogs/dialog.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/dialogs/options.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/dialogs/toolbar.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/scayt/skins/moono-lisa/scayt.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/_translationstatus.txt create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/af.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ar.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/az.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/bg.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/cs.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/cy.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/da.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/de-ch.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/de.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/el.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/en-au.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/en-ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/en-gb.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/en.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/eo.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/es-mx.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/es.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/et.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/eu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/fa.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/fi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/fr-ca.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/fr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/gl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/he.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/hr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/hu.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/id.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/it.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ja.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/km.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ko.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ku.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/lt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/lv.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/nb.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/nl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/no.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/oc.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/pl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/pt-br.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/pt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ro.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ru.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/si.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/sk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/sl.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/sq.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/sv.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/th.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/tr.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/tt.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/ug.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/uk.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/vi.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/zh-cn.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/lang/zh.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/specialchar/dialogs/specialchar.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/table/dialogs/table.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/tableselection/styles/tableselection.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/tabletools/dialogs/tableCell.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/widget/images/handle.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/LICENSE.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/README.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/dialogs/ciframe.html create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/dialogs/tmpFrameset.html create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/dialogs/wsc.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/dialogs/wsc.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/dialogs/wsc_ie.js create mode 100644 jetc/qualityiron-site/assets/ckeditor/plugins/wsc/skins/moono-lisa/wsc.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/dialog.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/dialog_ie.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/dialog_ie8.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/dialog_iequirks.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/editor.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/editor_gecko.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/editor_ie.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/editor_ie8.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/editor_iequirks.css create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/icons.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/icons_hidpi.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/arrow.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/close.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/hidpi/close.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/hidpi/lock-open.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/hidpi/lock.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/hidpi/refresh.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/lock-open.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/lock.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/refresh.png create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/images/spinner.gif create mode 100644 jetc/qualityiron-site/assets/ckeditor/skins/moono-lisa/readme.md create mode 100644 jetc/qualityiron-site/assets/ckeditor/styles.js create mode 100644 jetc/qualityiron-site/assets/images/delete.png create mode 100644 jetc/qualityiron-site/assets/images/jobdocs.js create mode 100644 jetc/qualityiron-site/assets/images/magglass.png create mode 100644 jetc/qualityiron-site/assets/images/main.css create mode 100644 jetc/qualityiron-site/assets/images/open.png create mode 100644 jetc/qualityiron-site/assets/images/plus.png create mode 100644 jetc/qualityiron-site/assets/images/qi_logo.png create mode 100644 jetc/qualityiron-site/assets/images/spa.js create mode 100755 jetc/qualityiron-site/src/SESSIONCTL.tag create mode 100644 jetc/qualityiron-site/src/addjobaddress.proc create mode 100644 jetc/qualityiron-site/src/addjobcontact.proc create mode 100644 jetc/qualityiron-site/src/addjobnotation.proc create mode 100644 jetc/qualityiron-site/src/admin.page create mode 100644 jetc/qualityiron-site/src/contractor.card create mode 100644 jetc/qualityiron-site/src/contractor.form create mode 100644 jetc/qualityiron-site/src/contractor.page create mode 100644 jetc/qualityiron-site/src/contractors.page create mode 100644 jetc/qualityiron-site/src/createcontractor.page create mode 100644 jetc/qualityiron-site/src/createcontractor.proc create mode 100644 jetc/qualityiron-site/src/createcustomer.page create mode 100644 jetc/qualityiron-site/src/createcustomer.proc create mode 100644 jetc/qualityiron-site/src/createrole.proc create mode 100644 jetc/qualityiron-site/src/createstatus.proc create mode 100644 jetc/qualityiron-site/src/createsubtype.proc create mode 100644 jetc/qualityiron-site/src/createtype.proc create mode 100644 jetc/qualityiron-site/src/createuser.page create mode 100644 jetc/qualityiron-site/src/createuser.proc create mode 100644 jetc/qualityiron-site/src/customer.card create mode 100644 jetc/qualityiron-site/src/customer.form create mode 100644 jetc/qualityiron-site/src/customer.page create mode 100644 jetc/qualityiron-site/src/customers.page create mode 100644 jetc/qualityiron-site/src/deletejobaddress.proc create mode 100644 jetc/qualityiron-site/src/deletejobcontact.proc create mode 100644 jetc/qualityiron-site/src/deleterole.proc create mode 100644 jetc/qualityiron-site/src/deletestatus.proc create mode 100644 jetc/qualityiron-site/src/deletesubtype.proc create mode 100644 jetc/qualityiron-site/src/deletetype.proc create mode 100644 jetc/qualityiron-site/src/deleteuser.proc create mode 100644 jetc/qualityiron-site/src/drawing.page create mode 100644 jetc/qualityiron-site/src/editcontractor.page create mode 100644 jetc/qualityiron-site/src/editcustomer.page create mode 100644 jetc/qualityiron-site/src/editdoctypes.page create mode 100644 jetc/qualityiron-site/src/editstatus.page create mode 100644 jetc/qualityiron-site/src/edituser.page create mode 100644 jetc/qualityiron-site/src/email.page create mode 100644 jetc/qualityiron-site/src/functions.menu create mode 100644 jetc/qualityiron-site/src/home.page create mode 100644 jetc/qualityiron-site/src/job.notations create mode 100644 jetc/qualityiron-site/src/job.page create mode 100644 jetc/qualityiron-site/src/jobdocs.jet create mode 100644 jetc/qualityiron-site/src/jobdocs.page create mode 100644 jetc/qualityiron-site/src/jobdocs_api.jet create mode 100644 jetc/qualityiron-site/src/jobfolder.form create mode 100644 jetc/qualityiron-site/src/jobs.list create mode 100644 jetc/qualityiron-site/src/jobs.page create mode 100644 jetc/qualityiron-site/src/login.bar create mode 100644 jetc/qualityiron-site/src/login.method create mode 100644 jetc/qualityiron-site/src/login.page create mode 100644 jetc/qualityiron-site/src/login.proc create mode 100644 jetc/qualityiron-site/src/logout.proc create mode 100644 jetc/qualityiron-site/src/mainpagetemplate.jet create mode 100644 jetc/qualityiron-site/src/profile.page create mode 100644 jetc/qualityiron-site/src/roles.page create mode 100644 jetc/qualityiron-site/src/selectcontractor.proc create mode 100644 jetc/qualityiron-site/src/selectcustomer.proc create mode 100644 jetc/qualityiron-site/src/selectjob.proc create mode 100644 jetc/qualityiron-site/src/selectuser.proc create mode 100644 jetc/qualityiron-site/src/setreview.proc create mode 100644 jetc/qualityiron-site/src/updatecontractor.proc create mode 100644 jetc/qualityiron-site/src/updatecustomer.proc create mode 100644 jetc/qualityiron-site/src/updatejobdates.proc create mode 100644 jetc/qualityiron-site/src/updatejobfolder.proc create mode 100644 jetc/qualityiron-site/src/updaterole.proc create mode 100644 jetc/qualityiron-site/src/updatestatus.proc create mode 100644 jetc/qualityiron-site/src/updatestatususer.proc create mode 100644 jetc/qualityiron-site/src/updatesubtype.proc create mode 100644 jetc/qualityiron-site/src/updatetype.proc create mode 100644 jetc/qualityiron-site/src/updateuser.proc create mode 100644 jetc/qualityiron-site/src/user.form create mode 100644 jetc/qualityiron-site/src/users.page create mode 100644 jetc/wcwc/wcwc.jet diff --git a/Tag.cpp b/Tag.cpp index a32c3eb..0975404 100644 --- a/Tag.cpp +++ b/Tag.cpp @@ -11,6 +11,7 @@ #include "__imapmessage.h" #include "__imapflag.h" #include "__imapdelete.h" +#include "__imapemptyfolder.h" #include "__imapmove.h" #include "__imapfolders.h" #include "__imapsearch.h" @@ -215,9 +216,33 @@ namespace jet { // matches the same unconsumed on every subsequent // iteration forever. Build the real expected delimiter // from splitTagName itself so it works for any split tag. - coreutils::MString splitOpenTag; - splitOpenTag << "<" << splitTagName << ">"; - in.ifNextIgnoreCase(splitOpenTag); + in.ifNext("<"); + in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"); + while(!in.eod()) { + in.skipWhitespace(); + if(in.ifNext(">")) + break; + else if(in.getTokenExclude("=").getLength() != 0) { + bool dq = in.ifNext("=\""); + bool sq = !dq && in.ifNext("='"); + if(dq || sq) { + while(1) { + if(in.ifNext(dq ? "\"" : "'")) + break; + in.nextChar(); + } + } else { + in.nextChar(); + while(!in.eod()) { + char c = in.charAt(0); + if(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '>' || c == '/') + break; + in.nextChar(); + } + } + } else + break; + } start = in.getCursor(); } else if(ifNested(in)) { } else @@ -477,6 +502,9 @@ namespace jet { } else if(ifTagName(in, "imapdelete")) { __imapdelete _imapdelete(in, out, global, this, local); continue; + } else if(ifTagName(in, "imapemptyfolder")) { + __imapemptyfolder _imapemptyfolder(in, out, global, this, local); + continue; } else if(ifTagName(in, "imapmove")) { __imapmove _imapmove(in, out, global, this, local); continue; @@ -737,16 +765,53 @@ namespace jet { bool Tag::ifSplitTagName(coreutils::ZString &in) { in.push(); - if(in.ifNext("<")) - if(coreutils::MString(in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_")).toLower() == coreutils::MString(splitTagName).toLower()) { - if(in.ifNext(">")) - in.pop(); - return true; - } + if(in.ifNext("<")) { + if(coreutils::MString(in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_")).toLower() == coreutils::MString(splitTagName).toLower()) { + // Tolerate attributes on the split-tag marker itself (e.g. + // 's own ) rather than requiring + // '>' to land immediately after the tag name - every + // splitTagName="else" caller writes a bare so this + // never mattered for them, but is the + // universal convention everywhere it's used. Previously this + // whole check was a single unbraced + // if(...){in.pop();return true;} where the missing braces + // meant "return true" executed unconditionally, leaving the + // cursor in a half-advanced, never-popped state on the + // attributed-tag path - confirmed live via a real /email/list + // failure whose caught error text leaked + // "name=\"_imaperr\">" into the JSON response. + while(!in.eod()) { + in.skipWhitespace(); + if(in.ifNext(">")) { + in.pop(); + return true; + } else if(in.getTokenExclude("=").getLength() != 0) { + bool dq = in.ifNext("=\""); + bool sq = !dq && in.ifNext("='"); + if(dq || sq) { + while(1) { + if(in.ifNext(dq ? "\"" : "'")) + break; + in.nextChar(); + } + } else { + in.nextChar(); + while(!in.eod()) { + char c = in.charAt(0); + if(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '>' || c == '/') + break; + in.nextChar(); + } + } + } else + break; + } + } + } in.pop(); return false; } - + int Tag::skipBlankLine(coreutils::ZString in) { ZString temp = in.getTokenInclude(" \t"); if(ifNext("\n")) diff --git a/__call.cpp b/__call.cpp index d951445..a56d2a0 100644 --- a/__call.cpp +++ b/__call.cpp @@ -7,13 +7,15 @@ #include #include #include +#include +#include #include namespace jet { - + __call::__call(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent, Tag *local) : Tag(in, parentOut, global, parent, local) { if(hasContainer && keywordDefined("input")) - throw coreutils::Exception("call tag cannot have both input keyword and have a container."); + throw coreutils::Exception("call tag cannot have both input keyword and have a container."); if(!keywordDefined("pgm")) throw coreutils::Exception("pgm keyword must be specified."); for(ix = 0; ix < 50; ++ix) @@ -35,48 +37,93 @@ namespace jet { } else break; } - pipe(fdo); + // pipe()/fork() both used to go unchecked here - on failure (most + // realistically pipe() hitting the process's open-file-descriptor + // limit, see below) fdo[] is left holding whatever garbage was + // already on the stack/in this member array, and every use of it + // after this point (close(), read(), and - for a failed fork() - + // waitpid(-1, ...), which has the special POSIX meaning "wait for + // ANY child" rather than "wait for none") operates on that garbage + // or on an unrelated process instead of safely no-oping. That's a + // real, confirmed mechanism for exactly the kind of sporadic + // memory corruption this codebase has seen: closing/reading a + // stale fd that coincidentally matches another subsystem's live + // socket, or reaping a concurrent request's own child out from + // under it. + if(pipe(fdo) != 0) + throw coreutils::Exception("call: pipe() failed - " + std::string(strerror(errno)), __FILE__, __LINE__, 500); pid = fork(); + if(pid < 0) { + close(fdo[0]); + close(fdo[1]); + throw coreutils::Exception("call: fork() failed - " + std::string(strerror(errno)), __FILE__, __LINE__, 500); + } if(pid == 0) { close(fdo[0]); dup2(fdo[1], 1); - if(hasContainer) { - pipe(fdi); - if(fork() == 0) { - close(fdi[0]); - write(fdi[1], container.getData(), container.getLength()); - close(fdi[1]); - exit(0); + if(hasContainer) { + if(pipe(fdi) == 0) { + pid_t innerPid = fork(); + if(innerPid == 0) { + close(fdi[0]); + write(fdi[1], container.getData(), container.getLength()); + close(fdi[1]); + _exit(0); + } else if(innerPid > 0) { + close(fdi[1]); + dup2(fdi[0], 0); + close(fdi[0]); + } else { + close(fdi[0]); + close(fdi[1]); + } } - close(fdi[1]); - dup2(fdi[0], 0); } else if(keywordDefined("input")) { coreutils::MString input(resolveKeyword("input")); - pipe(fdi); - if(fork() == 0) { - close(fdi[0]); - write(fdi[1], input.getData(), input.getLength()); - close(fdi[1]); - exit(0); + if(pipe(fdi) == 0) { + pid_t innerPid = fork(); + if(innerPid == 0) { + close(fdi[0]); + write(fdi[1], input.getData(), input.getLength()); + close(fdi[1]); + _exit(0); + } else if(innerPid > 0) { + close(fdi[1]); + dup2(fdi[0], 0); + close(fdi[0]); + } else { + close(fdi[0]); + close(fdi[1]); + } } - close(fdi[1]); - dup2(fdi[0], 0); } rc = execvpe(argv[0], argv, global.envp); close(fdo[1]); - exit(errno); + _exit(errno); } close(fdo[1]); if(keywordDefined("name")) { coreutils::MString value; value.read(fdo[0]); storeVariable(resolveKeyword("name"), value, resolveKeyword("scope")); - } else - out.read(fdo[0]); + } else + out.read(fdo[0]); + // fdo[0] (the read end, still open in this - the parent - process) + // was never closed here before, leaking one file descriptor on + // every single invocation for the life of the process. + // Harmless-looking for an occasional , but is used + // throughout this codebase (jq/curl parsing, mailcreate, this + // session's own per-line-item JS-escaping on the invoice editor, + // which alone can issue a double-digit number of calls per page + // load) - repeated, routine use was slowly accumulating leaked + // fds for as long as this process stayed up, eventually hitting + // the real open-files limit and turning into exactly the pipe() + // failures (and the undefined behavior above) this fix addresses. + close(fdo[0]); waitpid(pid, &status, 0); - if(keywordDefined("error")) { + if(keywordDefined("error")) { global.variables[resolveKeyword("error")] = (status >> 8 & 255); - } + } } - + } diff --git a/__imap.cpp b/__imap.cpp index b2506e2..ad4ebec 100644 --- a/__imap.cpp +++ b/__imap.cpp @@ -559,8 +559,15 @@ namespace jet { coreutils::MString passwordVal = resolveKeyword("password"); coreutils::JFile config(configPath); - std::string host = config.getString("host"); - long port = (long)config.getNumber("port"); + // host/port keywords override the config file's own values when + // present - lets a caller reuse one config file (still needed for + // caCertificate/smtpPort) across many accounts that each live on + // a different mail server, rather than requiring a separate config + // file per server. Every existing caller omits these keywords, so + // behavior is unchanged for them - config's own host/port is still + // the only thing read in that case. + std::string host = keywordDefined("host") ? resolveKeyword("host").str() : config.getString("host"); + long port = keywordDefined("port") ? strtol(resolveKeyword("port").str().c_str(), nullptr, 10) : (long)config.getNumber("port"); if (port <= 0) port = 993; @@ -1034,6 +1041,24 @@ namespace jet { return coreutils::MString(std::string("{\"ok\":") + (ok ? "true" : "false") + "}"); } + coreutils::MString __imap::emptyFolder(const std::string &folder) { + if (!selectFolderIfNeeded(folder)) + throw coreutils::Exception("imap: could not select folder " + folder, __FILE__, __LINE__, 502); + + std::string tag = nextTag(); + sendLine(tag + " UID STORE 1:* +FLAGS (\\Deleted)"); + auto lines = readUntilTagged(tag); + bool ok1 = taggedOk(lines, tag); + + std::string tag2 = nextTag(); + sendLine(tag2 + " EXPUNGE"); + auto lines2 = readUntilTagged(tag2); + bool ok2 = taggedOk(lines2, tag2); + + bool ok = ok1 && ok2; + return coreutils::MString(std::string("{\"ok\":") + (ok ? "true" : "false") + "}"); + } + // BARANTMail (see __IMAP_COPY.cpp) implements COPY but not the // RFC 6851 MOVE extension - not surprising, since the whole point // of that extension was standardizing what every real-world client diff --git a/__imap.h b/__imap.h index 7d396d9..3a8b953 100644 --- a/__imap.h +++ b/__imap.h @@ -63,6 +63,15 @@ namespace jet { coreutils::MString setFlag(const std::string &folder, uint32_t uid, const std::string &flag, bool add); coreutils::MString deleteMessage(const std::string &folder, uint32_t uid); coreutils::MString moveMessage(const std::string &folder, uint32_t uid, const std::string &destFolder); + // Permanently empties an entire folder - every message, not one at + // a time. "1:*" is IMAP's standard UID-range syntax for "every UID + // in the selected mailbox" (well-defined and a no-op, not an error, + // on an already-empty folder - verified directly against + // BARANTMail rather than assumed from the RFC), so this is a + // single mark-all-deleted STORE plus one EXPUNGE, not a loop over + // deleteMessage() - the whole point is one IMAP round trip instead + // of one per message. + coreutils::MString emptyFolder(const std::string &folder); coreutils::MString folderCounts(); coreutils::MString sessionId; diff --git a/__imapaccounts.cpp b/__imapaccounts.cpp index cbb16e6..9a78aa0 100644 --- a/__imapaccounts.cpp +++ b/__imapaccounts.cpp @@ -37,8 +37,8 @@ namespace jet { return s.substr(start, end - start + 1); } - std::vector> __imapaccounts::decodeList(const std::string &encodedRaw) { - std::vector> entries; + std::vector<__imapaccounts::Account> __imapaccounts::decodeList(const std::string &encodedRaw) { + std::vector entries; coreutils::Base64 base64; // The list value round-trips through / template // captures, which include whatever whitespace/newlines surround @@ -56,26 +56,35 @@ namespace jet { entry = trimWhitespace(entry); if (entry.empty()) continue; - size_t colon = entry.find(':'); - if (colon == std::string::npos) + size_t colon1 = entry.find(':'); + if (colon1 == std::string::npos) continue; - std::string userB64 = trimWhitespace(entry.substr(0, colon)); - std::string passB64 = trimWhitespace(entry.substr(colon + 1)); - std::string user = base64.decode(userB64).str(); - std::string password = base64.decode(passB64).str(); - entries.push_back(std::make_pair(user, password)); + size_t colon2 = entry.find(':', colon1 + 1); + if (colon2 == std::string::npos) + continue; + std::string hostB64 = trimWhitespace(entry.substr(0, colon1)); + std::string userB64 = trimWhitespace(entry.substr(colon1 + 1, colon2 - colon1 - 1)); + std::string passB64 = trimWhitespace(entry.substr(colon2 + 1)); + Account account; + account.host = base64.decode(hostB64).str(); + account.user = base64.decode(userB64).str(); + account.password = base64.decode(passB64).str(); + entries.push_back(account); } return entries; } - std::string __imapaccounts::encodeList(const std::vector> &entries) { + std::string __imapaccounts::encodeList(const std::vector &entries) { coreutils::Base64 base64; std::string result; for (size_t i = 0; i < entries.size(); i++) { if (i > 0) result += ";"; - std::string user = entries[i].first; - std::string password = entries[i].second; + std::string host = entries[i].host; + std::string user = entries[i].user; + std::string password = entries[i].password; + result += base64.encode(host).str(); + result += ":"; result += base64.encode(user).str(); result += ":"; result += base64.encode(password).str(); @@ -90,20 +99,25 @@ namespace jet { auto entries = decodeList(listStr); if (action == "add") { + std::string host = trimWhitespace(resolveKeyword("host").str()); std::string user = trimWhitespace(resolveKeyword("user").str()); std::string password = trimWhitespace(resolveKeyword("password").str()); for (size_t i = 0; i < entries.size(); i++) { - if (entries[i].first == user) { + if (entries[i].user == user) { entries.erase(entries.begin() + (long)i); break; } } - entries.push_back(std::make_pair(user, password)); + Account account; + account.host = host; + account.user = user; + account.password = password; + entries.push_back(account); out = coreutils::MString(encodeList(entries)); } else if (action == "remove") { std::string user = trimWhitespace(resolveKeyword("user").str()); for (size_t i = 0; i < entries.size(); i++) { - if (entries[i].first == user) { + if (entries[i].user == user) { entries.erase(entries.begin() + (long)i); break; } @@ -113,21 +127,31 @@ namespace jet { std::string user = trimWhitespace(resolveKeyword("user").str()); std::string password; for (size_t i = 0; i < entries.size(); i++) { - if (entries[i].first == user) { - password = entries[i].second; + if (entries[i].user == user) { + password = entries[i].password; break; } } out = coreutils::MString(password); + } else if (action == "gethost") { + std::string user = trimWhitespace(resolveKeyword("user").str()); + std::string host; + for (size_t i = 0; i < entries.size(); i++) { + if (entries[i].user == user) { + host = entries[i].host; + break; + } + } + out = coreutils::MString(host); } else if (action == "firstuser") { - out = coreutils::MString(entries.empty() ? std::string() : entries[0].first); + out = coreutils::MString(entries.empty() ? std::string() : entries[0].user); } else if (action == "list") { std::string active = resolveKeyword("active").str(); std::string json = "{\"accounts\":["; for (size_t i = 0; i < entries.size(); i++) { if (i > 0) json += ","; - json += "\"" + jsonEscape(entries[i].first) + "\""; + json += "\"" + jsonEscape(entries[i].user) + "\""; } json += "],\"active\":\"" + jsonEscape(active) + "\"}"; out = coreutils::MString(json); diff --git a/__imapaccounts.h b/__imapaccounts.h index 1261a87..649f80b 100644 --- a/__imapaccounts.h +++ b/__imapaccounts.h @@ -11,8 +11,8 @@ namespace jet { /// - /// + /// /// /// Pure list-transform tag (no session-variable access of its own, /// no IMAP connection) that manages the multi-account list webmail @@ -23,34 +23,45 @@ namespace jet { /// touches Global's session-variable map directly). /// /// The list's own on-the-wire encoding (semicolon-separated - /// "base64(user):base64(password)" entries) is private to this tag - - /// callers only ever pass the whole `list` value back in verbatim - /// and use the returned value the same way, so the choice of - /// delimiter can't collide with any real username or password - /// character. + /// "base64(host):base64(user):base64(password)" entries) is private + /// to this tag - callers only ever pass the whole `list` value back + /// in verbatim and use the returned value the same way, so the + /// choice of delimiter can't collide with any real username or + /// password character. Each account can live on its own IMAP server + /// (see the //etc. tags' own optional host/port + /// keywords), not just the one fixed host in email.cfg. /// - /// action="add": upserts user/password (removing any existing entry - /// for the same user first, so reconnecting with a changed password - /// updates it) - returns the updated encoded list. + /// action="add": upserts host/user/password (removing any existing + /// entry for the same user first, so reconnecting with a changed + /// password or server updates it) - returns the updated encoded list. /// action="remove": drops the entry for user, if present - returns /// the updated encoded list. /// action="getpassword": returns the stored password for user, or /// an empty string if not present. + /// action="gethost": returns the stored host for user, or an empty + /// string if not present. /// action="firstuser": returns the first entry's username, or an /// empty string if the list is empty. /// action="list": returns JSON ({"accounts":[...],"active":"..."}) /// - the one client-facing action; "active" echoes the `active` /// keyword (typically $[@_imap_user]) back verbatim so the sidebar - /// can highlight the current one, and never includes any password. + /// can highlight the current one, and never includes any password or + /// host (unchanged shape from before per-account hosts existed - + /// nothing client-side needs the host to switch between already- + /// connected accounts). /// class __imapaccounts : public Tag { + struct Account { + std::string host, user, password; + }; + public: __imapaccounts(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent, Tag *local); private: - static std::vector> decodeList(const std::string &encoded); - static std::string encodeList(const std::vector> &entries); + static std::vector decodeList(const std::string &encoded); + static std::string encodeList(const std::vector &entries); static std::string jsonEscape(const std::string &s); }; diff --git a/__imapemptyfolder.cpp b/__imapemptyfolder.cpp new file mode 100644 index 0000000..58daa14 --- /dev/null +++ b/__imapemptyfolder.cpp @@ -0,0 +1,26 @@ +#include "__imapemptyfolder.h" +#include "Exception.h" +#include "__imap.h" + +namespace jet { + + __imapemptyfolder::__imapemptyfolder(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent, Tag *local) : Tag(in, parentOut, global, parent, local) { + + coreutils::MString sessionId = resolveKeyword("sessionid"); + if (!global.imapSessionExists(sessionId)) + throw coreutils::Exception("imap sessionid does not exist.", __FILE__, __LINE__, 502); + + // Unlike __imapdelete (one message - low blast radius even on a + // wrong default), this permanently destroys an entire folder's + // contents - no silent "defaults to INBOX" here. A missing/blank + // folder attribute is refused outright rather than risked. + if (!keywordDefined("folder")) + throw coreutils::Exception("imapemptyfolder tag must have folder defined.", __FILE__, __LINE__, 400); + std::string folder = resolveKeyword("folder").str(); + if (folder.empty()) + throw coreutils::Exception("imapemptyfolder tag must have folder defined.", __FILE__, __LINE__, 400); + + out = global.getImapSession(sessionId)->emptyFolder(folder); + } + +} diff --git a/__imapemptyfolder.h b/__imapemptyfolder.h new file mode 100644 index 0000000..102d983 --- /dev/null +++ b/__imapemptyfolder.h @@ -0,0 +1,26 @@ +#ifndef ____imapemptyfolder_h__ +# define ____imapemptyfolder_h__ + +# include "Tag.h" + +namespace jet { + + /// + /// + /// + /// Self-closing tag - permanently deletes every message in the given + /// folder (mark-all-\Deleted + one EXPUNGE, not a per-message loop), + /// writes {"ok":true|false} into `out`. See __imaplist.h's doc + /// comment for how `out` reaches the real response body. + /// + + class __imapemptyfolder : public Tag { + + public: + __imapemptyfolder(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent, Tag *local); + + }; + +} + +#endif diff --git a/__smtpsend.cpp b/__smtpsend.cpp index de96709..50ece7e 100644 --- a/__smtpsend.cpp +++ b/__smtpsend.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include namespace jet { @@ -88,10 +90,31 @@ namespace jet { return std::string(buf); } + // RFC 5322 3.6.4: Message-ID "SHOULD be present" - in practice + // several real receivers (confirmed live: Gmail) now hard-reject + // anything missing one ("550 5.7.1 Messages missing a valid + // Message-ID header are not accepted") rather than just marking it + // down, so this isn't optional in practice. Domain part is the + // sender's own domain (everything after '@' in `from`), matching + // RFC 5322's own recommendation that it be a name under the + // generating system's control - falls back to the literal `from` + // string in the (should-never-happen) case it has no '@' at all. + std::string __smtpsend::generateMessageId(const std::string &from) { + size_t at = from.find('@'); + std::string domainPart = (at == std::string::npos) ? from : from.substr(at + 1); + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + std::ostringstream idStream; + idStream << ts.tv_sec << "." << std::setfill('0') << std::setw(9) << ts.tv_nsec + << "." << rand() << "@" << domainPart; + return idStream.str(); + } + std::string __smtpsend::buildMessage(const std::string &from, const std::string &to, const std::string &subject, const std::string &html) { std::string msg; msg += "Date: " + rfc2822Date() + "\r\n"; + msg += "Message-ID: <" + generateMessageId(from) + ">\r\n"; msg += "From: " + from + "\r\n"; msg += "To: " + to + "\r\n"; msg += "Subject: " + subject + "\r\n"; diff --git a/__smtpsend.h b/__smtpsend.h index 6438a22..5e489e9 100644 --- a/__smtpsend.h +++ b/__smtpsend.h @@ -58,6 +58,7 @@ namespace jet { static std::string base64Encode(const std::string &s); static std::string rfc2822Date(); + static std::string generateMessageId(const std::string &from); // Builds the full RFC 5322 message (headers + dot-stuffed body) // handed to SMTP's DATA command. static std::string buildMessage(const std::string &from, const std::string &to, diff --git a/jetc/barant-site/assets/images/btglogo.png b/jetc/barant-site/assets/images/btglogo.png index 43ab4af5e05eeff7024e76236b9e3002a6b36903..6c3791630f88ba8e6b804dd0ff219f862231f0bc 100644 GIT binary patch literal 522240 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]XP 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