Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netrc: Implement .netrc parsing #244

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ axel_SOURCES = \
src/ftp.h \
src/http.c \
src/http.h \
src/netrc.c \
src/netrc.h \
src/search.c \
src/search.h \
src/ssl.c \
Expand Down
2 changes: 2 additions & 0 deletions src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define AXEL_CONF_H

typedef struct {
char netrc_filename[MAX_STRING];
davidpolverari marked this conversation as resolved.
Show resolved Hide resolved
char default_filename[MAX_STRING];
char http_proxy[MAX_STRING];
char no_proxy[MAX_STRING];
Expand All @@ -67,6 +68,7 @@ typedef struct {
int search_threads;
int search_amount;
int search_top;
int use_netrc;

unsigned io_timeout;

Expand Down
3 changes: 3 additions & 0 deletions src/conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
/* Connection stuff */

#include "axel.h"
#include "netrc.h"

/**
* Convert an URL to a conn_t structure.
Expand Down Expand Up @@ -253,6 +254,8 @@ conn_init(conn_t *conn)
conn->ftp->local_if = conn->local_if;
conn->ftp->ftp_mode = FTP_PASSIVE;
conn->ftp->tcp.ai_family = conn->conf->ai_family;
if (conn->conf->use_netrc)
netrc_parse(conn);
if (!ftp_connect(conn->ftp, conn->proto, conn->host, conn->port,
conn->user, conn->pass,
conn->conf->io_timeout)) {
Expand Down
114 changes: 114 additions & 0 deletions src/netrc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
Axel -- A lighter download accelerator for Linux and other Unices

Copyright 2019 David da Silva Polverari

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.

In addition, as a special exception, the copyright holders give
permission to link the code of portions of this program with the
OpenSSL library under certain conditions as described in each
individual source file, and distribute linked combinations including
the two.

You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the
file(s), but you are not obligated to do so. If you do not wish to do
so, delete this exception statement from your version. If you delete
this exception statement from all source files in the program, then
also delete it here.

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/* .netrc parsing implementation */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "axel.h"
#include "netrc.h"

enum lookup_state {
NOTHING,
DEFAULT,
MACHINE,
HOST_ENTRY,
LOGIN,
PASSWORD
};
davidpolverari marked this conversation as resolved.
Show resolved Hide resolved

void
netrc_parse(conn_t *conn)
{
FILE *fp;
bool found = false;
char *home;
char *tok, *ntok;
char line[MAX_STRING];
char const *delims = " \t\n";
enum lookup_state state = NOTHING;

if (conn->conf->netrc_filename[0] == '\0') {
davidpolverari marked this conversation as resolved.
Show resolved Hide resolved
home = getenv("HOME");
snprintf(conn->conf->netrc_filename, MAX_STRING, "%s/.netrc", home);
}
if ((fp = fopen(conn->conf->netrc_filename, "r")) == NULL)
return;
while (!found && fgets(line, MAX_STRING, fp)) {
tok = strtok_r(line, delims, &ntok);
if (tok && *tok == '#')
continue;
while (tok != NULL) {
switch (state) {
case NOTHING:
if (!strcmp("machine", tok)) {
state = MACHINE;
} else if (!strcmp("default", tok)) {
state = DEFAULT;
}
break;
case MACHINE:
if (!strcmp(conn->host, tok)) {
state = HOST_ENTRY;
} else {
state = NOTHING;
}
break;
case DEFAULT:
state = HOST_ENTRY;
// fall through
case HOST_ENTRY:
if (!strcmp("login", tok)) {
state = LOGIN;
} else if (!strcmp("password", tok)) {
state = PASSWORD;
}
break;
case LOGIN:
strcpy(conn->user, tok);
davidpolverari marked this conversation as resolved.
Show resolved Hide resolved
state = HOST_ENTRY;
break;
case PASSWORD:
strcpy(conn->pass, tok);
found = true;
break;
default:
break;
}
tok = strtok_r(NULL, delims, &ntok);
}
}
}
42 changes: 42 additions & 0 deletions src/netrc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
Axel -- A lighter download accelerator for Linux and other Unices

Copyright 2019 David da Silva Polverari

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.

In addition, as a special exception, the copyright holders give
permission to link the code of portions of this program with the
OpenSSL library under certain conditions as described in each
individual source file, and distribute linked combinations including
the two.

You must obey the GNU General Public License in all respects for all
of the code used other than OpenSSL. If you modify file(s) with this
exception, you may extend this exception to your version of the
file(s), but you are not obligated to do so. If you do not wish to do
so, delete this exception statement from your version. If you delete
this exception statement from all source files in the program, then
also delete it here.

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/* .netrc parsing include file */

#ifndef AXEL_NETRC_H
#define AXEL_NETRC_H

void netrc_parse(conn_t *conn);

#endif /* AXEL_NETRC_H */
14 changes: 13 additions & 1 deletion src/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static struct option axel_options[] = {
{"max-redirect", 1, NULL, MAX_REDIR_OPT},
{"output", 1, NULL, 'o'},
{"search", 2, NULL, 'S'},
{"netrc", 2, NULL, 'R'},
{"ipv4", 0, NULL, '4'},
{"ipv6", 0, NULL, '6'},
{"no-proxy", 0, NULL, 'N'},
Expand Down Expand Up @@ -117,7 +118,7 @@ main(int argc, char *argv[])
j = -1;
while (1) {
int option = getopt_long(argc, argv,
"s:n:o:S::46NqvhVakcH:U:T:",
"s:n:o:S::R::46NqvhVakcH:U:T:",
axel_options, NULL);
if (option == -1)
break;
Expand Down Expand Up @@ -161,6 +162,15 @@ main(int argc, char *argv[])
}
}
break;
case 'R':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's define a negative version, it's necessary for if there's a default in the axel config file. I'm not sure a short version is needed (I've been thinking about removing support for systems not supporting getopt_long anyway).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About negative version of the option, I don't know whether it is a good idea to make .netrc parsing default, as it may break existing users' assumptions/scripts/workflows, etc. What do you think about it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mean to make it the default, but if you have the option on the configuration file, then you need a way to disable it from the command line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll add it.

conf->use_netrc = 1;
if (optarg) {
if (!sscanf(optarg, "%s", conf->netrc_filename)) {
davidpolverari marked this conversation as resolved.
Show resolved Hide resolved
print_help();
goto free_conf;
}
}
break;
case '6':
conf->ai_family = AF_INET6;
break;
Expand Down Expand Up @@ -659,6 +669,7 @@ print_help(void)
"-n x\tSpecify maximum number of connections\n"
"-o f\tSpecify local output file\n"
"-S[n]\tSearch for mirrors and download from n servers\n"
"-R[file]\tRetrieve credentials from $HOME/.netrc file or filename\n"
"-4\tUse the IPv4 protocol\n"
"-6\tUse the IPv6 protocol\n"
"-H x\tAdd HTTP header string\n"
Expand All @@ -682,6 +693,7 @@ print_help(void)
"--max-redirect=x\t\tSpecify maximum number of redirections\n"
"--output=f\t\t-o f\tSpecify local output file\n"
"--search[=n]\t\t-S[n]\tSearch for mirrors and download from n servers\n"
"--netrc[=file]\t\t-R[file]\tRetrieve credentials from $HOME/.netrc file or filename\n"
"--ipv4\t\t\t-4\tUse the IPv4 protocol\n"
"--ipv6\t\t\t-6\tUse the IPv6 protocol\n"
"--header=x\t\t-H x\tAdd HTTP header string\n"
Expand Down