NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
accountcmd.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <assert.h>
31#include <stdio.h>
32#include <sys/types.h>
33#include "mutt/lib.h"
34#include "config/lib.h"
35#include "core/lib.h"
36#include "accountcmd.h"
37#include "mutt_account.h"
38
45static void make_cmd(struct Buffer *buf, const struct ConnAccount *cac, const char *cmd)
46{
47 assert(buf && cac);
48
49 mutt_buffer_addstr(buf, cmd);
50 mutt_buffer_add_printf(buf, " --hostname %s", cac->host);
51 if (cac->flags & MUTT_ACCT_USER)
52 {
53 mutt_buffer_add_printf(buf, " --username %s", cac->user);
54 }
55
56 static const char *types[] = { "", "imap", "pop", "smtp", "nntp" };
57 assert(sizeof(types) / sizeof(*types) == MUTT_ACCT_TYPE_MAX);
58 if (cac->type != MUTT_ACCT_TYPE_NONE)
59 {
60 mutt_buffer_add_printf(buf, " --type %s%c", types[cac->type],
61 (cac->flags & MUTT_ACCT_SSL) ? 's' : '\0');
62 }
63}
64
72static MuttAccountFlags parse_one(struct ConnAccount *cac, char *line)
73{
74 assert(cac && line);
75
76 const regmatch_t *match = mutt_prex_capture(PREX_ACCOUNT_CMD, line);
77 if (!match)
78 {
79 mutt_perror(_("Line is malformed: expected <key: val>, got <%s>"), line);
80 return MUTT_ACCT_NO_FLAGS;
81 }
82
83 const regmatch_t *keymatch = &match[PREX_ACCOUNT_CMD_MATCH_KEY];
84 const regmatch_t *valmatch = &match[PREX_ACCOUNT_CMD_MATCH_VALUE];
85 line[mutt_regmatch_start(keymatch) + mutt_regmatch_len(keymatch)] = '\0';
86 const char *key = line + mutt_regmatch_start(keymatch);
87 const char *val = line + mutt_regmatch_start(valmatch);
88
89 switch (key[0])
90 {
91 case 'l':
92 if (mutt_str_equal(key + 1, "ogin"))
93 {
94 mutt_str_copy(cac->login, val, sizeof(cac->login));
95 return MUTT_ACCT_LOGIN;
96 }
97 break;
98
99 case 'p':
100 if (mutt_str_equal(key + 1, "assword"))
101 {
102 mutt_str_copy(cac->pass, val, sizeof(cac->pass));
103 return MUTT_ACCT_PASS;
104 }
105 break;
106
107 case 'u':
108 if (mutt_str_equal(key + 1, "sername"))
109 {
110 mutt_str_copy(cac->user, val, sizeof(cac->user));
111 return MUTT_ACCT_USER;
112 }
113 break;
114
115 default:
116 break;
117 }
118
119 mutt_warning(_("Unhandled key in line <%s: %s>"), key, val);
120 return MUTT_ACCT_NO_FLAGS;
121}
122
130static MuttAccountFlags call_cmd(struct ConnAccount *cac, const struct Buffer *cmd)
131{
132 assert(cac && cmd);
133
135
136 FILE *fp = NULL;
137 pid_t pid = filter_create(mutt_buffer_string(cmd), NULL, &fp, NULL);
138 if (pid < 0)
139 {
140 mutt_perror(_("Unable to run account command"));
141 return rc;
142 }
143
144 size_t len = 0;
145 char *line = NULL;
146 while ((line = mutt_file_read_line(NULL, &len, fp, NULL, MUTT_RL_NO_FLAGS)))
147 {
148 rc |= parse_one(cac, line);
149 FREE(&line);
150 }
151
152 mutt_file_fclose(&fp);
153 filter_wait(pid);
154 return rc;
155}
156
164{
165 if (!cac || (cac->host[0] == '\0') || (cac->type == MUTT_ACCT_TYPE_NONE))
166 {
167 return MUTT_ACCT_NO_FLAGS;
168 }
169
170 const char *c_account_command = cs_subset_string(NeoMutt->sub, "account_command");
171 if (!c_account_command)
172 {
173 return MUTT_ACCT_NO_FLAGS;
174 }
175
177 struct Buffer *cmd_buf = mutt_buffer_pool_get();
178
179 make_cmd(cmd_buf, cac, c_account_command);
180 rc = call_cmd(cac, cmd_buf);
181 cac->flags |= rc;
182
183 mutt_buffer_pool_release(&cmd_buf);
184 return rc;
185}
static MuttAccountFlags call_cmd(struct ConnAccount *cac, const struct Buffer *cmd)
Call the account command.
Definition: accountcmd.c:130
static MuttAccountFlags parse_one(struct ConnAccount *cac, char *line)
Parse a single line of the response.
Definition: accountcmd.c:72
static void make_cmd(struct Buffer *buf, const struct ConnAccount *cac, const char *cmd)
Build the command line for the external account command.
Definition: accountcmd.c:45
MuttAccountFlags mutt_account_call_external_cmd(struct ConnAccount *cac)
Retrieve account credentials via an external command.
Definition: accountcmd.c:163
Connection Credentials External Command.
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:211
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:78
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
Convenience wrapper for the config headers.
uint8_t MuttAccountFlags
Flags, Which ConnAccount fields are initialised, e.g. MUTT_ACCT_PORT.
Definition: connaccount.h:41
#define MUTT_ACCT_NO_FLAGS
No flags are set.
Definition: connaccount.h:42
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:47
#define MUTT_ACCT_PASS
Password field has been set.
Definition: connaccount.h:46
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:44
#define MUTT_ACCT_LOGIN
Login field has been set.
Definition: connaccount.h:45
Convenience wrapper for the core headers.
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:738
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:149
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
#define mutt_warning(...)
Definition: logging.h:85
#define mutt_perror(...)
Definition: logging.h:88
#define FREE(x)
Definition: memory.h:43
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:652
ConnAccount object used by POP and IMAP.
@ MUTT_ACCT_TYPE_NONE
Account type is unknown.
Definition: mutt_account.h:36
@ MUTT_ACCT_TYPE_MAX
Definition: mutt_account.h:41
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)
Match a precompiled regex against a string.
Definition: prex.c:308
@ PREX_ACCOUNT_CMD_MATCH_KEY
[key]: value
Definition: prex.h:247
@ PREX_ACCOUNT_CMD_MATCH_VALUE
key: [value]
Definition: prex.h:248
@ PREX_ACCOUNT_CMD
key: value
Definition: prex.h:42
static size_t mutt_regmatch_len(const regmatch_t *match)
Return the length of a match.
Definition: regex3.h:80
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
Definition: regex3.h:60
String manipulation buffer.
Definition: buffer.h:34
Login details for a remote server.
Definition: connaccount.h:53
char login[128]
Login name.
Definition: connaccount.h:55
char user[128]
Username.
Definition: connaccount.h:56
char pass[256]
Password.
Definition: connaccount.h:57
char host[128]
Server to login to.
Definition: connaccount.h:54
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:59
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:60
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39