NeoMutt  2025-12-11-694-ga89709
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
accountcmd.c File Reference

Connection Credentials External Command. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <sys/types.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "accountcmd.h"
#include "connaccount.h"
#include "mutt_account.h"
+ Include dependency graph for accountcmd.c:

Go to the source code of this file.

Functions

static void make_cmd (struct Buffer *buf, const struct ConnAccount *cac, const char *cmd)
 Build the command line for the external account command.
 
static MuttAccountFlags parse_one (struct ConnAccount *cac, char *line)
 Parse a single line of the response.
 
static MuttAccountFlags call_cmd (struct ConnAccount *cac, const struct Buffer *cmd)
 Call the account command.
 
MuttAccountFlags mutt_account_call_external_cmd (struct ConnAccount *cac)
 Retrieve account credentials via an external command.
 

Detailed Description

Connection Credentials External Command.

Authors
  • Pietro Cerutti
  • Richard Russon

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, see http://www.gnu.org/licenses/.

Definition in file accountcmd.c.

Function Documentation

◆ make_cmd()

static void make_cmd ( struct Buffer * buf,
const struct ConnAccount * cac,
const char * cmd )
static

Build the command line for the external account command.

Parameters
bufBuffer to fill with a command line
cacConnAccount to read params from
cmdAccount command from the user config

Definition at line 47 of file accountcmd.c.

48{
49 ASSERT(buf && cac);
50
51 buf_addstr(buf, cmd);
52
53 struct Buffer *quoted = buf_pool_get();
54
55 buf_quote_filename(quoted, cac->host, true);
56 buf_add_printf(buf, " --hostname %s", buf_string(quoted));
57 if (cac->flags & MUTT_ACCT_USER)
58 {
59 buf_quote_filename(quoted, cac->user, true);
60 buf_add_printf(buf, " --username %s", buf_string(quoted));
61 }
62
63 buf_pool_release(&quoted);
64
65 static const char *types[] = { "", "imap", "pop", "smtp", "nntp" };
66 ASSERT(sizeof(types) / sizeof(*types) == MUTT_ACCT_TYPE_MAX);
67 if (cac->type != MUTT_ACCT_TYPE_NONE)
68 {
69 buf_add_printf(buf, " --type %s%c", types[cac->type],
70 (cac->flags & MUTT_ACCT_SSL) ? 's' : '\0');
71 }
72}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition connaccount.h:47
#define MUTT_ACCT_USER
User field has been set.
Definition connaccount.h:44
void buf_quote_filename(struct Buffer *buf, const char *filename, bool add_outer)
Quote a filename to survive the shell's quoting rules.
Definition file.c:803
@ MUTT_ACCT_TYPE_NONE
Account type is unknown.
@ MUTT_ACCT_TYPE_MAX
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define ASSERT(COND)
Definition signal2.h:59
String manipulation buffer.
Definition buffer.h:36
char user[128]
Username.
Definition connaccount.h:56
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_one()

static MuttAccountFlags parse_one ( struct ConnAccount * cac,
char * line )
static

Parse a single line of the response.

Parameters
cacConnAccount to write to
lineLine from the response
Return values
numMuttAccountFlags that matched
MUTT_ACCT_NO_FLAGSFailure

Definition at line 81 of file accountcmd.c.

82{
83 ASSERT(cac && line);
84
85 const regmatch_t *match = mutt_prex_capture(PREX_ACCOUNT_CMD, line);
86 if (!match)
87 {
88 mutt_perror(_("Line is malformed: expected <key: val>, got <%s>"), line);
89 return MUTT_ACCT_NO_FLAGS;
90 }
91
92 const regmatch_t *keymatch = &match[PREX_ACCOUNT_CMD_MATCH_KEY];
93 const regmatch_t *valmatch = &match[PREX_ACCOUNT_CMD_MATCH_VALUE];
94 line[mutt_regmatch_start(keymatch) + mutt_regmatch_len(keymatch)] = '\0';
95 const char *key = line + mutt_regmatch_start(keymatch);
96 const char *val = line + mutt_regmatch_start(valmatch);
97
98 switch (key[0])
99 {
100 case 'l':
101 if (mutt_str_equal(key + 1, "ogin"))
102 {
103 mutt_str_copy(cac->login, val, sizeof(cac->login));
104 return MUTT_ACCT_LOGIN;
105 }
106 break;
107
108 case 'p':
109 if (mutt_str_equal(key + 1, "assword"))
110 {
111 mutt_str_copy(cac->pass, val, sizeof(cac->pass));
112 return MUTT_ACCT_PASS;
113 }
114 break;
115
116 case 'u':
117 if (mutt_str_equal(key + 1, "sername"))
118 {
119 mutt_str_copy(cac->user, val, sizeof(cac->user));
120 return MUTT_ACCT_USER;
121 }
122 break;
123
124 default:
125 break;
126 }
127
128 mutt_warning(_("Unhandled key in line <%s: %s>"), key, val);
129 return MUTT_ACCT_NO_FLAGS;
130}
#define MUTT_ACCT_NO_FLAGS
No flags are set.
Definition connaccount.h:42
#define MUTT_ACCT_PASS
Password field has been set.
Definition connaccount.h:46
#define MUTT_ACCT_LOGIN
Login field has been set.
Definition connaccount.h:45
#define mutt_warning(...)
Definition logging2.h:92
#define mutt_perror(...)
Definition logging2.h:95
#define _(a)
Definition message.h:28
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
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:586
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)
Match a precompiled regex against a string.
Definition prex.c:301
@ PREX_ACCOUNT_CMD_MATCH_KEY
[key]: value
Definition prex.h:225
@ PREX_ACCOUNT_CMD_MATCH_VALUE
key: [value]
Definition prex.h:226
@ 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:76
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
Definition regex3.h:56
char login[128]
Login name.
Definition connaccount.h:55
char pass[256]
Password.
Definition connaccount.h:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ call_cmd()

static MuttAccountFlags call_cmd ( struct ConnAccount * cac,
const struct Buffer * cmd )
static

Call the account command.

Parameters
cacConnAccount to write to
cmdCommand line to run
Return values
numMuttAccountFlags that matched
MUTT_ACCT_NO_FLAGSFailure

Definition at line 139 of file accountcmd.c.

140{
141 ASSERT(cac && cmd);
142
144
145 FILE *fp = NULL;
146 pid_t pid = filter_create(buf_string(cmd), NULL, &fp, NULL, NeoMutt->env);
147 if (pid < 0)
148 {
149 mutt_perror(_("Unable to run account command"));
150 return rc;
151 }
152
153 size_t len = 0;
154 char *line = NULL;
155 while ((line = mutt_file_read_line(NULL, &len, fp, NULL, MUTT_RL_NO_FLAGS)))
156 {
157 rc |= parse_one(cac, line);
158 FREE(&line);
159 }
160
161 mutt_file_fclose(&fp);
162 filter_wait(pid);
163 return rc;
164}
static MuttAccountFlags parse_one(struct ConnAccount *cac, char *line)
Parse a single line of the response.
Definition accountcmd.c:81
uint8_t MuttAccountFlags
Flags, Which ConnAccount fields are initialised, e.g. MUTT_ACCT_PORT.
Definition connaccount.h:41
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:678
#define mutt_file_fclose(FP)
Definition file.h:139
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition file.h:40
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition filter.c:228
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, char **envlist)
Set up filter program.
Definition filter.c:217
Container for Accounts, Notifications.
Definition neomutt.h:41
char ** env
Private copy of the environment variables.
Definition neomutt.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_account_call_external_cmd()

MuttAccountFlags mutt_account_call_external_cmd ( struct ConnAccount * cac)

Retrieve account credentials via an external command.

Parameters
cacConnAccount to fill
Return values
numA bitmask of MuttAccountFlags that were retrieved on success
MUTT_ACCT_NO_FLAGSFailure

Definition at line 172 of file accountcmd.c.

173{
174 if (!cac || (cac->host[0] == '\0') || (cac->type == MUTT_ACCT_TYPE_NONE))
175 {
176 return MUTT_ACCT_NO_FLAGS;
177 }
178
179 const char *c_account_command = cs_subset_string(NeoMutt->sub, "account_command");
180 if (!c_account_command)
181 {
182 return MUTT_ACCT_NO_FLAGS;
183 }
184
186 struct Buffer *cmd_buf = buf_pool_get();
187
188 make_cmd(cmd_buf, cac, c_account_command);
189 rc = call_cmd(cac, cmd_buf);
190 cac->flags |= rc;
191
192 buf_pool_release(&cmd_buf);
193 return rc;
194}
static MuttAccountFlags call_cmd(struct ConnAccount *cac, const struct Buffer *cmd)
Call the account command.
Definition accountcmd.c:139
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:47
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function: