;; fetchmail-mode.el -*- Emacs-Lisp -*-
;;
;; Mode for editing .fetchmailrc files
;;
;; Created: <Mon Oct 30 20:13:15 EST 2000>
;; Time-stamp: <17.02.2001 17:59:43>
;; Version: 0.1
;; Keywords: fetchmail,config
;; Author: Alex Shinn <foof@debian.org>
;;
;; 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
;; Commentary:
;;
;; This file provides a major mode for editing .fetchmailrc files.
;; It offers syntax highlighting and indentation.
;;
;; To use it, put the following in your .emacs:
;;
;; (autoload 'fetchmail-mode "fetchmail-mode.el" "Mode for editing .fetchmailrc files" t)
;;
;; You may also want something like:
;;
;; (setq auto-mode-alist
;; (append '(("\..fetchmailrc$" . fetchmail-mode))
;; auto-mode-alist))
;; Create mode-specific tables.
(defvar fetchmail-mode-syntax-table nil
"Syntax table used while in fetchmail-mode" )
(if fetchmail-mode-syntax-table
() ; Do not change the table if it is already set up.
(setq fetchmail-mode-syntax-table (make-syntax-table))
(modify-syntax-entry ?\\ "\\ " fetchmail-mode-syntax-table)
(modify-syntax-entry ?\,pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long *//*
* conf.c -- dump fetchmail configuration as Python dictionary initializer
*
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
#include "tunable.h"
#include <stdio.h>
#include <ctype.h>
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <string.h>
#include <pwd.h>
#include <errno.h>
#include "fetchmail.h"
/* Python prettyprinting functions */
static int indent_level;
static void indent(char ic)
/* indent current line */
{
int i;
if (ic == ')' || ic == ']' || ic == '}')
indent_level--;
/*
* The guard here is a kluge. It depends on the fact that in the
* particular structure we're dumping, opening [s are always
* initializers for dictionary members and thus will be preceded
* by a member name.
*/
if (ic != '[')
{
for (i = 0; i < indent_level / 2; i++)
putc('\t', stdout);
if (indent_level % 2)
fputs(" ", stdout);
}
if (ic)
{
putc(ic, stdout);
putc('\n', stdout);
}
if (ic == '(' || ic == '[' || ic == '{')
indent_level++;
}
static void stringdump(const char *name, const char *member)
/* dump a string member with current indent */
{
indent('\0');
fprintf(stdout, "\"%s\":", name);
if (member)
fprintf(stdout, "\"%s\"", visbuf(member));
else
fputs("None", stdout);
fputs(",\n", stdout);
}
static void numdump(const char *name, const int num)
/* dump a numeric quantity at current indent */
{
indent('\0');
fprintf(stdout, "'%s':%d,\n", name, NUM_VALUE_OUT(num));
}
static void booldump(const char *name, const int onoff)
/* dump a boolean quantity at current indent */
{
indent('\0');
if (onoff)
fprintf(stdout, "'%s':TRUE,\n", name);
else
fprintf(stdout, "'%s':FALSE,\n", name);
}
static void listdump(const char *name, struct idlist *list)
/* dump a string list member with current indent */
{
indent('\0');
fprintf(stdout, "\"%s\":", name);
if (!list)
fputs("None,\n", stdout);
else
{
struct idlist *idp;
fputs("[", stdout);
for (idp = list; idp; idp = idp->next)
if (idp->id)
{
fprintf(stdout, "\"%s\"", visbuf(idp->id));
if (idp->next)
fputs(", ", stdout);
}
fputs("],\n", stdout);
}
}
/*
* Note: this function dumps the entire configuration,
* after merging of the defaults record (if any). It
* is intended to produce output parseable by a configuration
* front end, not anything especially comfortable for humans.
*/
void dump_config(struct runctl *runp, struct query *querylist)
/* dump the in-core configuration in recompilable form */
{
struct query *ctl;
struct idlist *idp;
indent_level = 0;
/*
* These had better match the values fetchmailconf is expecting!
* (We don't want to import them from Tkinter because the user
* might not have it installed.)
*/
fputs("TRUE=1; FALSE=0\n\n", stdout);
/*
* We need this in order to know whether `interface' and `monitor'
* are valid options or not.
*/
#if defined(linux)
fputs("os_type = 'linux'\n", stdout);
#elif defined(__FreeBSD__)
fputs("os_type = 'freebsd'\n", stdout);
#else
fputs("os_type = 'generic'\n", stdout);
#endif
/*
* This should be approximately in sync with the -V option dumping
* in fetchmail.c.
*/
printf("feature_options = (");
#ifdef POP2_ENABLE
printf("'pop2',");
#endif /* POP2_ENABLE */
#ifdef POP3_ENABLE
printf("'pop3',");
#endif /* POP3_ENABLE */
#ifdef IMAP_ENABLE
printf("'imap',");
#endif /* IMAP_ENABLE */
#ifdef GSSAPI
printf("'gssapi',");
#endif /* GSSAPI */
#if defined(KERBEROS_V4)
printf("'kerberos',");
#endif /* defined(IMAP4) */
#ifdef RPA_ENABLE
printf("'rpa',");
#endif /* RPA_ENABLE */
#ifdef SDPS_ENABLE
printf("'sdps',");
#endif /* SDPS_ENABLE */
#ifdef ETRN_ENABLE
printf("'etrn',");
#endif /* ETRN_ENABLE */
#ifdef ODMR_ENABLE
printf("'odmr',");
#endif /* ODMR_ENABLE */
#ifdef SSL_ENABLE
printf("'ssl',");
#endif /* SSL_ENABLE */
#if OPIE_ENABLE
printf("'opie',");
#endif /* OPIE_ENABLE */
#if INET6_ENABLE
printf("'inet6',");
#endif /* INET6_ENABLE */
#if NET_SECURITY
printf("'netsec',");
#endif /* NET_SECURITY */
printf(")\n");
fputs("# Start of configuration initializer\n", stdout);
fputs("fetchmailrc = ", stdout);
indent('{');
numdump("poll_interval", runp->poll_interval);
stringdump("logfile", runp->logfile);
stringdump("idfile", runp->idfile);
stringdump("postmaster", runp->postmaster);
booldump("bouncemail", runp->bouncemail);
booldump("spambounce", runp->spambounce);
stringdump("properties", runp->properties);
booldump("invisible", runp->invisible);
booldump("showdots", runp->showdots);
booldump("syslog", runp->use_syslog);
if (!querylist)
{
fputs(" 'servers': []\n", stdout);
goto alldone;
}
indent(0);
fputs("# List of server entries begins here\n", stdout);
indent(0);
fputs("'servers': ", stdout);
indent('[');
for (ctl = querylist; ctl; ctl = ctl->next)
{
/*
* First, the server stuff.
*/
if (!ctl->server.lead_server)
{
flag using_kpop;
/*
* Every time we see a leading server entry after the first one,
* it implicitly ends the both (a) the list of user structures
* associated with the previous entry, and (b) that previous entry.
*/
if (ctl > querylist)
{
indent(']');
indent('}');
indent('\0');
putc(',', stdout);
putc('\n', stdout);
}
indent(0);
fprintf(stdout,"# Entry for site `%s' begins:\n",ctl->server.pollname);
indent('{');
using_kpop =
(ctl->server.protocol == P_POP3 &&
#if !INET6_ENABLE
ctl->server.port == KPOP_PORT &&
#else
ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT ) &&
#endif
ctl->server.authenticate == A_KERBEROS_V4);
stringdump("pollname", ctl->server.pollname);
booldump("active", !ctl->server.skip);
stringdump("via", ctl->server.via);
stringdump("protocol",
using_kpop ? "KPOP" : showproto(ctl->server.protocol));
#ifndef INET6_ENABLE
numdump("port", ctl->server.port);
#else
stringdump("port", ctl->server.service);
#endif
numdump("timeout", ctl->server.timeout);
numdump("interval", ctl->server.interval);
if (ctl->server.envelope == STRING_DISABLED)
stringdump("envelope", NULL);
else if (ctl->server.envelope == NULL)
stringdump("envelope", "Received");
else
stringdump("envelope", ctl->server.envelope);
numdump("envskip", ctl->server.envskip);
stringdump("qvirtual", ctl->server.qvirtual);
if (ctl->server.authenticate == A_ANY)
stringdump("auth", "any");
else if (ctl->server.authenticate == A_PASSWORD)
stringdump("auth", "password");
else if (ctl->server.authenticate == A_OTP)
stringdump("auth", "otp");
else if (ctl->server.authenticate == A_NTLM)
stringdump("auth", "ntlm");
else if (ctl->server.authenticate == A_CRAM_MD5)
stringdump("auth", "cram-md5");
else if (ctl->server.authenticate == A_GSSAPI)
stringdump("auth", "gssapi");
else if (ctl->server.authenticate == A_KERBEROS_V4)
stringdump("auth", "kerberos_v4");
else if (ctl->server.authenticate == A_KERBEROS_V5)
stringdump("auth", "kerberos_v5");
else if (ctl->server.authenticate == A_SSH)
stringdump("auth", "ssh");
#if defined(HAVE_GETHOSTBYNAME) && defined(HAVE_RES_SEARCH)
booldump("dns", ctl->server.dns);
#endif /* HAVE_GETHOSTBYNAME && HAVE_RES_SEARCH */
booldump("uidl", ctl->server.uidl);
listdump("aka", ctl->server.akalist);
listdump("localdomains", ctl->server.localdomains);
#if defined(linux) || defined(__FreeBSD__)
stringdump("interface", ctl->server.interface);
stringdump("monitor", ctl->server.monitor);
#endif /* linux || __FreeBSD__ */
stringdump("plugin", ctl->server.plugin);
stringdump("plugout", ctl->server.plugout);
stringdump("principal", ctl->server.principal);
indent(0);
fputs("'users': ", stdout);
indent('[');
}
indent('{');
stringdump("remote", ctl->remotename);
stringdump("password", ctl->password);
indent('\0');
fprintf(stdout, "'localnames':[");
for (idp = ctl->localnames; idp; idp = idp->next)
{
char namebuf[USERNAMELEN + 1];
strncpy(namebuf, visbuf(idp->id), USERNAMELEN);
namebuf[USERNAMELEN] = '\0';
if (idp->val.id2)
fprintf(stdout, "(\"%s\", %s)", namebuf, visbuf(idp->val.id2));
else
fprintf(stdout, "\"%s\"", namebuf);
if (idp->next)
fputs(", ", stdout);
}
if (ctl->wildcard)
fputs(", '*'", stdout);
fputs("],\n", stdout);
booldump("fetchall", ctl->fetchall);
booldump("keep", ctl->keep);
booldump("flush", ctl->flush);
booldump("rewrite", ctl->rewrite);
booldump("stripcr", ctl->stripcr);
booldump("forcecr", ctl->forcecr);
booldump("pass8bits", ctl->pass8bits);
booldump("dropstatus", ctl->dropstatus);
booldump("dropdelivered", ctl->dropdelivered);
booldump("mimedecode", ctl->mimedecode);
booldump("idle", ctl->idle);
stringdump("mda", ctl->mda);
stringdump("bsmtp", ctl->bsmtp);
indent('\0');
if (ctl->listener == LMTP_MODE)
fputs("'lmtp':TRUE,\n", stdout);
else
fputs("'lmtp':FALSE,\n", stdout);
#ifdef INET6_ENABLE
stringdump("netsec", ctl->server.netsec);
#endif /* INET6_ENABLE */
stringdump("preconnect", ctl->preconnect);
stringdump("postconnect", ctl->postconnect);
numdump("limit", ctl->limit);
numdump("warnings", ctl->warnings);
numdump("fetchlimit", ctl->fetchlimit);
numdump("batchlimit", ctl->batchlimit);
#ifdef SSL_ENABLE
booldump("ssl", ctl->use_ssl);
stringdump("sslkey", ctl->sslkey);
stringdump("sslcert", ctl->sslcert);
stringdump("sslproto", ctl->sslproto);
#endif /* SSL_ENABLE */
numdump("expunge", ctl->expunge);
stringdump("properties", ctl->properties);
listdump("smtphunt", ctl->smtphunt);
stringdump("smtpaddress", ctl->smtpaddress);
stringdump("smtpname", ctl->smtpname);
indent('\0');
fprintf(stdout, "'antispam':'");
if (!ctl->antispam)
fputs("'\n", stdout);
else
{
for (idp = ctl->antispam; idp; idp = idp->next)
{
fprintf(stdout, "%d", idp->val.status.num);
if (idp->next)
fputs(" ", stdout);
}
fputs("',\n", stdout);
}
listdump("mailboxes", ctl->mailboxes);
indent('}');
indent('\0');
fputc(',', stdout);
}
/* end last span of user entries and last server entry */
indent(']');
indent('}');
/* end array of servers */
indent(']');
alldone:
/* end top-level dictionary */
indent('}');
fputs("# End of initializer\n", stdout);
}
/* conf.c ends here */