* Re: git protocol specification
From: Shawn O. Pearce @ 2008-07-10 2:32 UTC (permalink / raw)
To: Tom Werner; +Cc: Git Mailing List
In-Reply-To: <48750231.4020805@rubyisawesome.com>
Tom Werner <pubsub@rubyisawesome.com> wrote:
> I'm working on a flexible Erlang replacement for git-daemon and would
> like to know if there is a specification available for the protocol that
> git-upload-pack and git-receive-pack use. I've reverse engineered it but
> have come across some points that seem inconsistent. Before I dig into
> the C code in earnest I wanted to see if there's anything like spec
> document for the system. Thanks!
I'm curious, are you planning on implementing git-upload-pack and
git-receive-pack in Erlang as well? Or are you just doing the
git-daemon frontend and spawn the C git binaries as port processes?
git-receive-pack isn't too much trouble, the protocol on the server
side without the tell-me-more is fairly simple to implement, once
you have something like index-pack or unpack-objects implemented.
But that is somewhat non-trivial to do.
git-upload-pack is much more complex on the server side as you
must actually create the packfile, which means you also need to
compute the set of objects the client is missing, as well as tell
the client when you have enough "have" lines in order to compute
the smallest reasonable pack possible for the data transfer.
I know Erlang is really good at protocol handling and binary
formatting/parsing, but I don't know if you have a good git object
navigation library available to you in Erlang. Its been years
since I last worked with it, or was involved in its community... ;-)
--
Shawn.
^ permalink raw reply
* Re: [PATCH 3/4] imap-send.c: Clean up coding style to better match the rest of the git codebase.
From: Junio C Hamano @ 2008-07-10 2:18 UTC (permalink / raw)
To: Robert Shearman; +Cc: git
In-Reply-To: <1215638942-25010-3-git-send-email-robertshearman@gmail.com>
Robert Shearman <robertshearman@gmail.com> writes:
> - else if (!strcmp( "ssl_verify", key ))
> - server.ssl_verify = git_config_bool( key, val );
> + else if (!strcmp("sslverify", key))
> + server.ssl_verify = git_config_bool(key, val);
This is not a style fix. Output from "size imap-send.o" before and after
a style fix patch should exactly match.
I'll fix up in the earlier one [2/4] so that this becomes a pure style
fix, so no need to resend.
^ permalink raw reply
* Re: [PATCH 2/4] git-imap-send: Add support for SSL.
From: Junio C Hamano @ 2008-07-10 2:02 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Robert Shearman, git, Robert Shearman
In-Reply-To: <alpine.LFD.1.10.0807091825500.11076@woody.linux-foundation.org>
Linus Torvalds <torvalds@linux-foundation.org> writes:
> We should be able to safely include <ctype.h> as-is.
>
> It should just happen _before_ including git-compat-util.h. That's why
> git-compat-util.h does all those #undef's - exactly because ctype.h does
> get included on various systems by various header files when
> git-compat-util.h includes all those other files.
Eh, that's true,... although I am not convinced we should keep doing this.
With and without NO_OPENSSL, on top of Robert's patch, these seem to pass
compile test.
--
git-compat-util.h | 5 +++++
imap-send.c | 4 ----
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/git-compat-util.h b/git-compat-util.h
index 545df59..65c4671 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -99,6 +99,11 @@
#include <iconv.h>
#endif
+#ifndef NO_OPENSSL
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#endif
+
/* On most systems <limits.h> would have given us this, but
* not on some systems (e.g. GNU/Hurd).
*/
diff --git a/imap-send.c b/imap-send.c
index 9dc5d08..8026334 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -25,9 +25,6 @@
#include "cache.h"
#ifdef NO_OPENSSL
typedef void *SSL;
-#else
-# include <openssl/ssl.h>
-# include <openssl/err.h>
#endif
typedef struct store_conf {
^ permalink raw reply related
* Re: git protocol specification
From: Shawn O. Pearce @ 2008-07-10 1:47 UTC (permalink / raw)
To: Tom Werner; +Cc: Johannes Schindelin, Git Mailing List
In-Reply-To: <alpine.DEB.1.00.0807092044120.4010@eeepc-johanness>
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Wed, 9 Jul 2008, Tom Werner wrote:
>
> > I'm working on a flexible Erlang replacement for git-daemon and would
> > like to know if there is a specification available for the protocol that
> > git-upload-pack and git-receive-pack use.
>
> How about Documentation/technical/pack-protocol.txt?
You may also want to look at jgit's source code. Its a cleaner
implementation of the protocol in 100% Java. Not something you
would want to try and call directly from in Erlang, but it may
be easier to follow.
http://repo.or.cz/w/egit.git/
Look inside of the org.spearce.jgit/src/org/spearce/jgit/transport
package. In particular the client side of the protocol for git://
is in the TransportGitAnon class as two inner subclasses, one for
fetch ('git-upload-pack') and another for push ('git-receive-pack').
--
Shawn.
^ permalink raw reply
* Re: [PATCH 2/4] git-imap-send: Add support for SSL.
From: Linus Torvalds @ 2008-07-10 1:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Robert Shearman, git, Robert Shearman
In-Reply-To: <7v8wwa5ycf.fsf@gitster.siamese.dyndns.org>
On Wed, 9 Jul 2008, Junio C Hamano wrote:
>
> A hack like the one attached below would make it "work" but it is too
> ugly. Probably we need to bite the bullet and rename ours not to
> collide, so that external library headers can safely include <ctype.h>.
We should be able to safely include <ctype.h> as-is.
It should just happen _before_ including git-compat-util.h. That's why
git-compat-util.h does all those #undef's - exactly because ctype.h does
get included on various systems by various header files when
git-compat-util.h includes all those other files.
So the problem with Robert's patch is that it happens after "cache.h". The
system headers should be included at the top of git-compat-util.h, or
before it.
Linus
^ permalink raw reply
* Re: [PATCH 2/4] git-imap-send: Add support for SSL.
From: Junio C Hamano @ 2008-07-10 1:20 UTC (permalink / raw)
To: Robert Shearman; +Cc: git, Robert Shearman, Linus Torvalds
In-Reply-To: <1215638942-25010-2-git-send-email-robertshearman@gmail.com>
Robert Shearman <robertshearman@gmail.com> writes:
> diff --git a/imap-send.c b/imap-send.c
> index 24d76a7..26d1dba 100644
> --- a/imap-send.c
> +++ b/imap-send.c
> @@ -23,6 +23,12 @@
> */
>
> #include "cache.h"
> +#ifdef NO_OPENSSL
> +typedef void *SSL;
> +#else
> +# include <openssl/ssl.h>
> +# include <openssl/err.h>
> +#endif
This unfortunately is causing compilation issues. <openssl/ssl.h> wants
to include <ctype.h> and gets upset by seeing our isalpha() and friends
that are defined indirectly in "cache.h" expanded.
In <ctype.h> (on FC9), isCHARACTERISTC() are defined like this:
#define __exctype(name) extern int name (int) __THROW
...
__exctype (isalnum);
__exctype (isalpha);
but we have been using our own locale agonistic and signed-chars safe
macros defined in git-compat-util.h. Including <ctype.h> breaks at the
syntax level, but more importantly if the system <ctype.h> redefines
isalpha() and friends as macro, then it would break _our_ code that expect
these macros are the sane_ctype[] based ones we have.
A hack like the one attached below would make it "work" but it is too
ugly. Probably we need to bite the bullet and rename ours not to
collide, so that external library headers can safely include <ctype.h>.
Sigh...
diff --git a/git-compat-util.h b/git-compat-util.h
index 8c7e114..0af6406 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -302,6 +302,7 @@ static inline int has_extension(const char *filename, const char *ext)
}
/* Sane ctype - no locale, and works with signed chars */
+#define _CTYPE_H
#undef isspace
#undef isdigit
#undef isalpha
^ permalink raw reply related
* [PATCH] git-submodule - register submodule URL if adding in place
From: Mark Levedahl @ 2008-07-10 1:05 UTC (permalink / raw)
To: gitster, Johannes.Schindelin
Cc: git, sylvain.joyeux, hjemli, pkufranky, Mark Levedahl
In-Reply-To: <1215651941-3460-1-git-send-email-mlevedahl@gmail.com>
When adding a new submodule in place, meaning the user created the
submodule as a git repo in the superproject's tree first, we don't go
through "git submodule init" to register the module. Thus, the
submodule's origin repository URL is not stored in .git/config, and no
subsequent submodule operation will ever do so. In this case, assume the
URL the user supplies to "submodule add" is the one that should be
registered, and do so.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
Dscho's issue, so far as I can tell, was not really with this patch
but is addressed by the preceding patch eliminating the
confusing single argument "submodule add" format that lead to the
error he wanted to avoid. This patch is not changed except that it
is rebased.
git-submodule.sh | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/git-submodule.sh b/git-submodule.sh
index c2ce2fb..9228f56 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -172,6 +172,16 @@ cmd_add()
else
die "'$path' already exists and is not a valid git repo"
fi
+
+ case "$repo" in
+ ./*|../*)
+ url=$(resolve_relative_url "$repo") || exit
+ ;;
+ *)
+ url="$repo"
+ ;;
+ esac
+ git config submodule."$path".url "$url"
else
module_clone "$path" "$realrepo" || exit
--
1.5.6.2.271.g73ad8
^ permalink raw reply related
* [PATCH] git-submodule - make "submodule add" more strict, and document it
From: Mark Levedahl @ 2008-07-10 1:05 UTC (permalink / raw)
To: gitster, Johannes.Schindelin
Cc: git, sylvain.joyeux, hjemli, pkufranky, Mark Levedahl
In-Reply-To: <7vwsjvlhjw.fsf@gitster.siamese.dyndns.org>
This change makes "submodule add" much more strict in the arguments it
takes, and is intended to address confusion as recently noted on the
git-list. With this change, the required syntax is:
$ git submodule add URL path
Specifically, this eliminates the form
$ git submodule add URL
which was confused by more than one person as
$ git submodule add path
With this patch, the URL locating the submodule's origin repository can be
either an absolute URL, or (if it begins with ./ or ../) can express the
submodule's repository location relative to the superproject's origin.
This patch also eliminates a third form of URL, which was relative to the
superproject's top-level directory (not its repository). Any URL that was
neither absolute nor matched ./*|../* was assumed to point to a
subdirectory of the superproject as the location of the submodule's origin
repository. This URL form was confusing and does not seem to correspond
to an important use-case. Specifically, no-one has identified the need to
clone from a repository already in the superproject's tree, but if this is
needed it is easily done using an absolute URL: $(pwd)/relative-path. So,
no functionality is lost with this patch. (t6008-rev-list-submodule.sh did
rely upon this relative URL, fixed by using $(pwd).)
Following this change, there are exactly four variants of
submodule-add, as both arguments have two flavors:
URL can be absolute, or can begin with ./|../ and thus names the
submodule's origin relative to the superproject's origin.
Note: With this patch, "submodule add" discerns an absolute URL as
matching /*|*:*: e.g., URL begins with /, or it contains a :. This works
for all valid URLs, an absolute path in POSIX, as well as an absolute path
on Windows).
path can either already exist as a valid git repo, or will be cloned from
the given URL. The first form here eases creation of a new submodule in
an existing superproject as the submodule can be added and tested in-tree
before pushing to the public repository. However, the more usual form is
the second, where the repo is cloned from the given URL.
This specifically addresses the issue of
$ git submodule add a/b/c
attempting to clone from a repository at "a/b/c" to create a new module
in "c". This also simplifies description of "relative URL" as there is now
exactly *one* form: a URL relative to the parent's origin repo.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
---
This should address Junio's issues. In addition, I found one test
affected by this change and fixed that (the test actually used
the relative path URL to clone, replaced with $(pwd)).
Documentation/git-submodule.txt | 36 +++++++++++++++++++------
git-submodule.sh | 55 ++++++++++++++------------------------
t/t6008-rev-list-submodule.sh | 2 +-
3 files changed, 48 insertions(+), 45 deletions(-)
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 105fc2d..1fe13a6 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules
SYNOPSIS
--------
[verse]
-'git submodule' [--quiet] add [-b branch] [--] <repository> [<path>]
+'git submodule' [--quiet] add [-b branch] [--] <repository> <path>
'git submodule' [--quiet] status [--cached] [--] [<path>...]
'git submodule' [--quiet] init [--] [<path>...]
'git submodule' [--quiet] update [--init] [--] [<path>...]
@@ -20,14 +20,31 @@ COMMANDS
--------
add::
Add the given repository as a submodule at the given path
- to the changeset to be committed next. If path is a valid
- repository within the project, it is added as is. Otherwise,
- repository is cloned at the specified path. path is added to the
- changeset and registered in .gitmodules. If no path is
- specified, the path is deduced from the repository specification.
- If the repository url begins with ./ or ../, it is stored as
- given but resolved as a relative path from the main project's
- url when cloning.
+ to the changeset to be committed next to the current
+ project: the current project is termed termed the "superproject".
+
+ This requires two arguments: <repository> and <path>.
+
+ <repository> is the URL of the new submodule's origin repository.
+ This may be either an absolute URL, or (if it begins with ./
+ or ../), the location relative to the superproject's origin
+ repository.
+
+ <path> is the relative location for the cloned submodule to
+ exist in the superproject. If <path> does not exist, then the
+ submodule is created by cloning from the named URL. If <path> does
+ exist and is already a valid git repository, then this is added
+ to the changeset without cloning. This second form is provided
+ to ease creating a new submodule from scratch, and presumes
+ the user will later push the submodule to the given URL.
+
+ In either case, the given URL is recorded into .gitmodules for
+ use by subsequent users cloning the superproject. If the URL is
+ given relative to the superproject's repository, the presumption
+ is the superproject and submodule repositories will be kept
+ together in the same relative location, and only the
+ superproject's URL need be provided: git-submodule will correctly
+ locate the submodule using the relative URL in .gitmodules.
status::
Show the status of the submodules. This will print the SHA-1 of the
@@ -85,6 +102,7 @@ OPTIONS
<path>::
Path to submodule(s). When specified this will restrict the command
to only operate on the submodules found at the specified paths.
+ (This argument is required with add).
FILES
-----
diff --git a/git-submodule.sh b/git-submodule.sh
index 099a7d7..c2ce2fb 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -5,7 +5,7 @@
# Copyright (c) 2007 Lars Hjemli
USAGE="[--quiet] [--cached] \
-[add <repo> [-b branch]|status|init|update [-i|--init]|summary [-n|--summary-limit <n>] [<commit>]] \
+[add <repo> [-b branch] <path>]|[status|init|update [-i|--init]|summary [-n|--summary-limit <n>] [<commit>]] \
[--] [<path>...]"
OPTIONS_SPEC=
. git-sh-setup
@@ -27,18 +27,6 @@ say()
fi
}
-# NEEDSWORK: identical function exists in get_repo_base in clone.sh
-get_repo_base() {
- (
- cd "`/bin/pwd`" &&
- cd "$1" || cd "$1.git" &&
- {
- cd .git
- pwd
- }
- ) 2>/dev/null
-}
-
# Resolve relative url by appending to parent's url
resolve_relative_url ()
{
@@ -115,7 +103,7 @@ module_clone()
#
# Add a new submodule to the working tree, .gitmodules and the index
#
-# $@ = repo [path]
+# $@ = repo path
#
# optional branch is stored in global branch variable
#
@@ -150,16 +138,27 @@ cmd_add()
repo=$1
path=$2
- if test -z "$repo"; then
+ if test -z "$repo" -o -z "$path"; then
usage
fi
- # Guess path from repo if not specified or strip trailing slashes
- if test -z "$path"; then
- path=$(echo "$repo" | sed -e 's|/*$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
- else
- path=$(echo "$path" | sed -e 's|/*$||')
- fi
+ # assure repo is absolute or relative to parent
+ case "$repo" in
+ ./*|../*)
+ # dereference source url relative to parent's url
+ realrepo=$(resolve_relative_url "$repo") || exit
+ ;;
+ *:*|/*)
+ # absolute url
+ realrepo=$repo
+ ;;
+ *)
+ die "repo URL: '$repo' must be absolute or begin with ./|../"
+ ;;
+ esac
+
+ # strip trailing slashes from path
+ path=$(echo "$path" | sed -e 's|/*$||')
git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
die "'$path' already exists in the index"
@@ -174,20 +173,6 @@ cmd_add()
die "'$path' already exists and is not a valid git repo"
fi
else
- case "$repo" in
- ./*|../*)
- # dereference source url relative to parent's url
- realrepo=$(resolve_relative_url "$repo") || exit
- ;;
- *)
- # Turn the source into an absolute path if
- # it is local
- if base=$(get_repo_base "$repo"); then
- repo="$base"
- fi
- realrepo=$repo
- ;;
- esac
module_clone "$path" "$realrepo" || exit
(unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
diff --git a/t/t6008-rev-list-submodule.sh b/t/t6008-rev-list-submodule.sh
index 88e96fb..c4af9ca 100755
--- a/t/t6008-rev-list-submodule.sh
+++ b/t/t6008-rev-list-submodule.sh
@@ -23,7 +23,7 @@ test_expect_success 'setup' '
: > super-file &&
git add super-file &&
- git submodule add . sub &&
+ git submodule add "$(pwd)" sub &&
git symbolic-ref HEAD refs/heads/super &&
test_tick &&
git commit -m super-initial &&
--
1.5.6.2.271.g73ad8
^ permalink raw reply related
* Re: [RFC/PATCH (WIP)] Git.pm: Add get_config() method and related subroutines
From: Jakub Narebski @ 2008-07-09 23:33 UTC (permalink / raw)
To: Petr Baudis; +Cc: git, Lea Wiemann
In-Reply-To: <20080709160303.GL10151@machine.or.cz>
On Wed, Jul 09, 2008, Petr "Pasky" Baudis wrote:
> On Thu, Jul 03, 2008 at 06:24:53PM +0200, Jakub Narebski wrote:
> >
> > There are also a few things which I'd like some comments about:
> >
> > * Do config_val_to_bool and config_val_to_int should be exported
> > by default?
>
> Yes with the current API, not with object API (see below). But if
> exported by default, there should be definitely a git_ prefix.
Object API for config is definitely good idea; some more reasons are
given below.
> > * Should config_val_to_bool and config_val_to_int throw error or
> > just return 'undef' on invalid values? One can check if variable
> > is defined using "exists($config_hash{'varname'})".
>
> I think that it's more reasonable to throw an error here (as long as
> you don't throw an error on undef argument). This particular case is
> clearly a misconfiguration by the user and you rarely need to handle
> this more gracefully, I believe.
If we follow git-config convention (and I guess we should), it would be
value of appropriate type if variable value is of appropriate type,
'undef' (no output in the case of git-config) when variable does not
exists, and throwing error (status and "fatal: ..." message on STDERR
in the case of git-config) if variable is not of given type.
> > * How config_val_to_bool etc. should be named? Perhaps just
> > config_to_bool, like in gitweb?
>
> What about Git::Config::bool()? ;-) (See below.)
>
> > * Is "return wantarray ? %config : \%config;" DWIM-mery good style?
> > I am _not_ a Perl hacker...
>
> I maybe wouldn't be as liberal myself, but I can't tell if it's a bad
> style either.
This won't matter, I think, in the case of object API (returning
Git::Config instead of hash or hashref).
> > * Should ->get_config() use ->command_output_pipe, or simpler
> > ->command() method, reading whole config into array?
>
> You have the code written already, I'd stick with it.
This is simple rewrite of code which is in gitweb, changing open '-|'
into ->command_output_pipe, but we could just read the whole config
into array using ->command(), which would be a bit simpler.
> > * What should ->get_config() have as an optional parameter:
> > PREFIX (/^$prefix/o), or simply SECTION (/^(?:$section)\./o)?
>
> Do we even _need_ a parameter like that? I don't understand what is
> this interface trying to address.
For example if one wants to access _all_ variables in gitweb.* section
(or in gitcvs.* section), and _only_ config variables in given section.
> > * Should we perltie hash?
>
> I agree with Lea that we should actually bless it. :-) Returning a
> Git::Config object provides a more flexible interface, and you can
> also do $repo->get_config()->bool('key') which is quite more elegant
> way than the val_ functions, I think.
Yes it is.
Also it does allow to use any capitalization of the section name and
variable name (which are case insensitive), so you can write either
$repo->get_config()->get('gitcvs.dbtablenameprefix');
but also
$repo->get_config()->get('gitcvs.dbTableNamePrefix');
or even better, as below:
$config = $repo->get_config();
$config->get('gitcvs.dbTableNamePrefix');
BTW. what should non-typecasting should be named? $c->get(<VAR>),
$c->value(<VAR>), $c->param(<VAR>), or something yet different?
> Also, having accessors for special types lets you return undef when
> the type really isn't defined, instead of e.g. true with current
> config_val_bool, which is clearly bogus and requires complicated code
> on the user side.
I don't follow you. Didn't we agree on casting an error when variable
is not of given type?
By the way, bool values are processed a bit strangely. Value is true
if it there is no value[*1*], if it is 'true' or 'yes' case insensitive,
or of it is integer != 0. Value is false if it has empty value[*2*],
if it is 'false' or 'no' case insensitive, and if it is integer of
value '0'. All other values are invalid (and should cause throwing an
error).
Both current config_val_to_bool() and config_val_to_int() implementation
are too forbidding.
> > As this is an RFC I have not checked if manpage (generated from
> > embedded POD documentation) renders correctly.
>
> By the way, unless you know already, you can do that trivially by
> issuing:
>
> perldoc perl/Git.pm
Thanks, I didn't knew this.
> --
> Petr "Pasky" Baudis
> The last good thing written in C++ was the Pachelbel Canon.
> -- J. Olson
Eh? Isn't it written C# rather?
--
Jakub Narebski
Poland
^ permalink raw reply
* Re: [PATCH] git-send-email: Fix authenticating on some servers when using TLS.
From: Junio C Hamano @ 2008-07-09 22:51 UTC (permalink / raw)
To: Robert Shearman; +Cc: git
In-Reply-To: <1215639580-25040-1-git-send-email-robertshearman@gmail.com>
Robert Shearman <robertshearman@gmail.com> writes:
> Send hello after a successful STARTTLS command to refresh the list of extensions. These may be different to what is returned over a clear connection (for example the AUTH command may be accepted over a secure connection, but not over a clear connection).
>
> Furthermore, this behaviour is recommended by RFC 2487 (http://www.ietf.org/rfc/rfc2487.txt).
Very true. Thanks.
^ permalink raw reply
* [PATCH] git-send-email: Fix authenticating on some servers when using TLS.
From: Robert Shearman @ 2008-07-09 21:39 UTC (permalink / raw)
To: git; +Cc: Robert Shearman
Send hello after a successful STARTTLS command to refresh the list of extensions. These may be different to what is returned over a clear connection (for example the AUTH command may be accepted over a secure connection, but not over a clear connection).
Furthermore, this behaviour is recommended by RFC 2487 (http://www.ietf.org/rfc/rfc2487.txt).
Signed-off-by: Robert Shearman <robertshearman@gmail.com>
---
git-send-email.perl | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/git-send-email.perl b/git-send-email.perl
index 3564419..6adb669 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -773,6 +773,9 @@ X-Mailer: git-send-email $gitversion
$smtp = Net::SMTP::SSL->start_SSL($smtp)
or die "STARTTLS failed! ".$smtp->message;
$smtp_encryption = '';
+ # Send EHLO again to receive fresh
+ # supported commands
+ $smtp->hello();
} else {
die "Server does not support STARTTLS! ".$smtp->message;
}
--
1.5.6.2.224.g26efb.dirty
^ permalink raw reply related
* [PATCH] git-shortlog: migrate to parse-options partially.
From: Pierre Habouzit @ 2008-07-09 21:38 UTC (permalink / raw)
To: git; +Cc: gitster, Pierre Habouzit
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-shortlog.c | 135 +++++++++++++++++++++++++++++----------------------
1 files changed, 77 insertions(+), 58 deletions(-)
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index e6a2865..9107bff 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -7,9 +7,14 @@
#include "utf8.h"
#include "mailmap.h"
#include "shortlog.h"
+#include "parse-options.h"
-static const char shortlog_usage[] =
-"git-shortlog [-n] [-s] [-e] [-w] [<commit-id>... ]";
+static char const * const shortlog_usage[] = {
+ "git-shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]",
+ "",
+ "[rev-opts] are documented in git-rev-list(1)",
+ NULL
+};
static int compare_by_number(const void *a1, const void *a2)
{
@@ -164,21 +169,19 @@ static void get_from_rev(struct rev_info *rev, struct shortlog *log)
shortlog_add_commit(log, commit);
}
-static int parse_uint(char const **arg, int comma)
+static int parse_uint(char const **arg, int comma, int defval)
{
unsigned long ul;
int ret;
char *endp;
ul = strtoul(*arg, &endp, 10);
- if (endp != *arg && *endp && *endp != comma)
+ if (*endp && *endp != comma)
return -1;
- ret = (int) ul;
- if (ret != ul)
+ if (ul > INT_MAX)
return -1;
- *arg = endp;
- if (**arg)
- (*arg)++;
+ ret = *arg == endp ? defval : (int)ul;
+ *arg = *endp ? endp + 1 : endp;
return ret;
}
@@ -187,30 +190,30 @@ static const char wrap_arg_usage[] = "-w[<width>[,<indent1>[,<indent2>]]]";
#define DEFAULT_INDENT1 6
#define DEFAULT_INDENT2 9
-static void parse_wrap_args(const char *arg, int *in1, int *in2, int *wrap)
+static int parse_wrap_args(const struct option *opt, const char *arg, int unset)
{
- arg += 2; /* skip -w */
-
- *wrap = parse_uint(&arg, ',');
- if (*wrap < 0)
- die(wrap_arg_usage);
- *in1 = parse_uint(&arg, ',');
- if (*in1 < 0)
- die(wrap_arg_usage);
- *in2 = parse_uint(&arg, '\0');
- if (*in2 < 0)
- die(wrap_arg_usage);
-
- if (!*wrap)
- *wrap = DEFAULT_WRAPLEN;
- if (!*in1)
- *in1 = DEFAULT_INDENT1;
- if (!*in2)
- *in2 = DEFAULT_INDENT2;
- if (*wrap &&
- ((*in1 && *wrap <= *in1) ||
- (*in2 && *wrap <= *in2)))
- die(wrap_arg_usage);
+ struct shortlog *log = opt->value;
+
+ log->wrap_lines = !unset;
+ if (unset)
+ return 0;
+ if (!arg) {
+ log->wrap = DEFAULT_WRAPLEN;
+ log->in1 = DEFAULT_INDENT1;
+ log->in2 = DEFAULT_INDENT2;
+ return 0;
+ }
+
+ log->wrap = parse_uint(&arg, ',', DEFAULT_WRAPLEN);
+ log->in1 = parse_uint(&arg, ',', DEFAULT_INDENT1);
+ log->in2 = parse_uint(&arg, '\0', DEFAULT_INDENT2);
+ if (log->wrap < 0 || log->in1 < 0 || log->in2 < 0)
+ return error(wrap_arg_usage);
+ if (log->wrap &&
+ ((log->in1 && log->wrap <= log->in1) ||
+ (log->in2 && log->wrap <= log->in2)))
+ return error(wrap_arg_usage);
+ return 0;
}
void shortlog_init(struct shortlog *log)
@@ -227,38 +230,54 @@ void shortlog_init(struct shortlog *log)
int cmd_shortlog(int argc, const char **argv, const char *prefix)
{
- struct shortlog log;
- struct rev_info rev;
+ static struct shortlog log;
+ static struct rev_info rev;
int nongit;
+ static const struct option options[] = {
+ OPT_BOOLEAN('n', "numbered", &log.sort_by_number,
+ "sort output according to the number of commits per author"),
+ OPT_BOOLEAN('s', "summary", &log.summary,
+ "Suppress commit descriptions, only provides commit count"),
+ OPT_BOOLEAN('e', "email", &log.email,
+ "Show the email address of each author"),
+ { OPTION_CALLBACK, 'w', NULL, &log, "w[,i1[,i2]]",
+ "Linewrap output", PARSE_OPT_OPTARG, &parse_wrap_args },
+ OPT_END(),
+ };
+
+ struct parse_opt_ctx_t ctx;
+
prefix = setup_git_directory_gently(&nongit);
shortlog_init(&log);
-
- /* since -n is a shadowed rev argument, parse our args first */
- while (argc > 1) {
- if (!strcmp(argv[1], "-n") || !strcmp(argv[1], "--numbered"))
- log.sort_by_number = 1;
- else if (!strcmp(argv[1], "-s") ||
- !strcmp(argv[1], "--summary"))
- log.summary = 1;
- else if (!strcmp(argv[1], "-e") ||
- !strcmp(argv[1], "--email"))
- log.email = 1;
- else if (!prefixcmp(argv[1], "-w")) {
- log.wrap_lines = 1;
- parse_wrap_args(argv[1], &log.in1, &log.in2, &log.wrap);
+ init_revisions(&rev, prefix);
+ parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
+ PARSE_OPT_KEEP_ARGV0);
+
+ for (;;) {
+ int n;
+ switch (parse_options_step(&ctx, options, shortlog_usage)) {
+ case PARSE_OPT_HELP:
+ exit(129);
+ case PARSE_OPT_DONE:
+ goto parse_done;
}
- else if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
- usage(shortlog_usage);
- else
- break;
- argv++;
- argc--;
+ n = handle_revision_opt(&rev, ctx.argc, ctx.argv,
+ &ctx.cpidx, ctx.out);
+ if (n <= 0) {
+ error("unknown option `%s'", ctx.argv[0]);
+ usage_with_options(shortlog_usage, options);
+ }
+ ctx.argv += n;
+ ctx.argc -= n;
+ }
+parse_done:
+ argc = parse_options_end(&ctx);
+
+ if (setup_revisions(argc, argv, &rev, NULL) != 1) {
+ error("unrecognized argument: %s", argv[1]);
+ usage_with_options(shortlog_usage, options);
}
- init_revisions(&rev, prefix);
- argc = setup_revisions(argc, argv, &rev, NULL);
- if (argc > 1)
- die ("unrecognized argument: %s", argv[1]);
/* assume HEAD if from a tty */
if (!nongit && !rev.pending.nr && isatty(0))
--
1.5.6.2.428.gdce6.dirty
^ permalink raw reply related
* [PATCH] revisions: refactor handle_revision_opt into parse_revision_opt.
From: Pierre Habouzit @ 2008-07-09 21:38 UTC (permalink / raw)
To: git; +Cc: gitster, Pierre Habouzit
In-Reply-To: <1215639514-1612-1-git-send-email-madcoder@debian.org>
It seems we're using handle_revision_opt the same way each time, have a
wrapper around it that does the 9-liner we copy each time instead.
handle_revision_opt can be static in the module for now, it's always
possible to make it public again if needed.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-blame.c | 11 +----------
builtin-shortlog.c | 10 +---------
revision.c | 18 ++++++++++++++++--
revision.h | 7 +++++--
4 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/builtin-blame.c b/builtin-blame.c
index 73d26c6..06c7de4 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2305,8 +2305,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
parse_options_start(&ctx, argc, argv, PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_KEEP_ARGV0);
for (;;) {
- int n;
-
switch (parse_options_step(&ctx, options, blame_opt_usage)) {
case PARSE_OPT_HELP:
exit(129);
@@ -2320,14 +2318,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
ctx.argv[0] = "--children";
reverse = 1;
}
- n = handle_revision_opt(&revs, ctx.argc, ctx.argv,
- &ctx.cpidx, ctx.out);
- if (n <= 0) {
- error("unknown option `%s'", ctx.argv[0]);
- usage_with_options(blame_opt_usage, options);
- }
- ctx.argv += n;
- ctx.argc -= n;
+ parse_revision_opt(&revs, &ctx, options, blame_opt_usage);
}
parse_done:
argc = parse_options_end(&ctx);
diff --git a/builtin-shortlog.c b/builtin-shortlog.c
index 9107bff..0136202 100644
--- a/builtin-shortlog.c
+++ b/builtin-shortlog.c
@@ -255,21 +255,13 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
PARSE_OPT_KEEP_ARGV0);
for (;;) {
- int n;
switch (parse_options_step(&ctx, options, shortlog_usage)) {
case PARSE_OPT_HELP:
exit(129);
case PARSE_OPT_DONE:
goto parse_done;
}
- n = handle_revision_opt(&rev, ctx.argc, ctx.argv,
- &ctx.cpidx, ctx.out);
- if (n <= 0) {
- error("unknown option `%s'", ctx.argv[0]);
- usage_with_options(shortlog_usage, options);
- }
- ctx.argv += n;
- ctx.argc -= n;
+ parse_revision_opt(&rev, &ctx, options, shortlog_usage);
}
parse_done:
argc = parse_options_end(&ctx);
diff --git a/revision.c b/revision.c
index 9d5d933..bbd563e 100644
--- a/revision.c
+++ b/revision.c
@@ -974,8 +974,8 @@ static void add_ignore_packed(struct rev_info *revs, const char *name)
revs->ignore_packed[num] = NULL;
}
-int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
- int *unkc, const char **unkv)
+static int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
+ int *unkc, const char **unkv)
{
const char *arg = argv[0];
@@ -1180,6 +1180,20 @@ int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
return 1;
}
+void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
+ const struct option *options,
+ const char * const usagestr[])
+{
+ int n = handle_revision_opt(revs, ctx->argc, ctx->argv,
+ &ctx->cpidx, ctx->out);
+ if (n <= 0) {
+ error("unknown option `%s'", ctx->argv[0]);
+ usage_with_options(usagestr, options);
+ }
+ ctx->argv += n;
+ ctx->argc -= n;
+}
+
/*
* Parse revision information, filling in the "rev_info" structure,
* and removing the used arguments from the argument list.
diff --git a/revision.h b/revision.h
index cc80fcd..fa68c65 100644
--- a/revision.h
+++ b/revision.h
@@ -1,6 +1,8 @@
#ifndef REVISION_H
#define REVISION_H
+#include "parse-options.h"
+
#define SEEN (1u<<0)
#define UNINTERESTING (1u<<1)
#define TREESAME (1u<<2)
@@ -122,8 +124,9 @@ volatile show_early_output_fn_t show_early_output;
extern void init_revisions(struct rev_info *revs, const char *prefix);
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
-extern int handle_revision_opt(struct rev_info *revs, int argc, const char **argv,
- int *unkc, const char **unkv);
+extern void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,
+ const struct option *options,
+ const char * const usagestr[]);
extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
extern int prepare_revision_walk(struct rev_info *revs);
--
1.5.6.2.428.gdce6.dirty
^ permalink raw reply related
* [PATCH 4/4] Documentation: Improve documentation for git-imap-send(1).
From: Robert Shearman @ 2008-07-09 21:29 UTC (permalink / raw)
To: git; +Cc: Robert Shearman
Change the description to be similar to that used for git-send-email(1) to give a better description of what the tool can be used for and sound more user-friendly.
Document the configuration variables used by git-imap-send, split the example into tunnel and direct examples. Rephrase other parts of the git-imap-send documentation to use better grammar and to be clearer.
Signed-off-by: Robert Shearman <robertshearman@gmail.com>
---
Documentation/git-imap-send.txt | 77 +++++++++++++++++++++++++++++++++------
1 files changed, 65 insertions(+), 12 deletions(-)
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index 136c82b..f9e7288 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -3,7 +3,7 @@ git-imap-send(1)
NAME
----
-git-imap-send - Dump a mailbox from stdin into an imap folder
+git-imap-send - Send a collection of patches from stdin to an IMAP folder
SYNOPSIS
@@ -13,9 +13,9 @@ SYNOPSIS
DESCRIPTION
-----------
-This command uploads a mailbox generated with git-format-patch
-into an imap drafts folder. This allows patches to be sent as
-other email is sent with mail clients that cannot read mailbox
+This command uploads a mailbox generated with git format-patch
+into an IMAP drafts folder. This allows patches to be sent as
+other email is when using mail clients that cannot read mailbox
files directly.
Typical usage is something like:
@@ -26,21 +26,74 @@ git format-patch --signoff --stdout --attach origin | git imap-send
CONFIGURATION
-------------
-'git-imap-send' requires the following values in the repository
-configuration file (shown with examples):
+To use the tool imap.folder and either imap.tunnel or imap.host must be set
+to appropriate values.
+
+Variables
+~~~~~~~~~
+
+imap.folder::
+ The folder to drop the mails into, which is typically the Drafts
+ folder. For example: "INBOX.Drafts", "INBOX/Drafts" or
+ "[Gmail]/Drafts". Required to use imap-send.
+
+imap.tunnel::
+ Command used to setup a tunnel to the IMAP server through which
+ commands will be piped instead of using a direct network connection
+ to the server. Required when imap.host is not set to use imap-send.
+
+imap.host::
+ A URL identifying the server. Use a `imap://` prefix for non-secure
+ connections and a `imaps://` prefix for secure connections.
+ Ignored when imap.tunnel is set, but required to use imap-send
+ otherwise.
+
+imap.user::
+ The username to use when logging in to the server.
+
+imap.password::
+ The password to use when logging in to the server.
+
+imap.port::
+ An integer port number to connect to on the server.
+ Defaults to 143 for imap:// hosts and 993 for imaps:// hosts.
+ Ignored when imap.tunnel is set.
+
+imap.sslverify::
+ A boolean to enable/disable verification of the server certificate
+ used by the SSL/TLS connection. Default is `true`. Ignored when
+ imap.tunnel is set.
+
+Examples
+~~~~~~~~
+
+Using tunnel mode:
..........................
[imap]
- Folder = "INBOX.Drafts"
+ folder = "INBOX.Drafts"
+ tunnel = "ssh -q -C user@example.com /usr/bin/imapd ./Maildir 2> /dev/null"
+..........................
+Using direct mode:
+
+.........................
[imap]
- Tunnel = "ssh -q user@server.com /usr/bin/imapd ./Maildir 2> /dev/null"
+ folder = "INBOX.Drafts"
+ host = imap://imap.example.com
+ user = bob
+ pass = p4ssw0rd
+..........................
+
+Using direct mode with SSL:
+.........................
[imap]
- Host = imap://imap.example.com
- User = bob
- Pass = pwd
- Port = 143
+ folder = "INBOX.Drafts"
+ host = imaps://imap.example.com
+ user = bob
+ pass = p4ssw0rd
+ port = 123
sslverify = false
..........................
--
1.5.6.2.224.g26efb.dirty
^ permalink raw reply related
* [PATCH 3/4] imap-send.c: Clean up coding style to better match the rest of the git codebase.
From: Robert Shearman @ 2008-07-09 21:29 UTC (permalink / raw)
To: git; +Cc: Robert Shearman
Signed-off-by: Robert Shearman <robertshearman@gmail.com>
---
imap-send.c | 629 ++++++++++++++++++++++++++++-------------------------------
1 files changed, 300 insertions(+), 329 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 26d1dba..ae8189f 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -102,14 +102,14 @@ typedef struct {
static int Verbose, Quiet;
-static void imap_info( const char *, ... );
-static void imap_warn( const char *, ... );
+static void imap_info(const char *, ...);
+static void imap_warn(const char *, ...);
-static char *next_arg( char ** );
+static char *next_arg(char **);
-static void free_generic_messages( message_t * );
+static void free_generic_messages(message_t *);
-static int nfsnprintf( char *buf, int blen, const char *fmt, ... );
+static int nfsnprintf(char *buf, int blen, const char *fmt, ...);
static int nfvasprintf(char **strp, const char *fmt, va_list ap)
{
@@ -125,8 +125,8 @@ static int nfvasprintf(char **strp, const char *fmt, va_list ap)
return len;
}
-static void arc4_init( void );
-static unsigned char arc4_getbyte( void );
+static void arc4_init(void);
+static unsigned char arc4_getbyte(void);
typedef struct imap_server_conf {
char *name;
@@ -187,8 +187,8 @@ typedef struct imap_store {
} imap_store_t;
struct imap_cmd_cb {
- int (*cont)( imap_store_t *ctx, struct imap_cmd *cmd, const char *prompt );
- void (*done)( imap_store_t *ctx, struct imap_cmd *cmd, int response);
+ int (*cont)(imap_store_t *ctx, struct imap_cmd *cmd, const char *prompt);
+ void (*done)(imap_store_t *ctx, struct imap_cmd *cmd, int response);
void *ctx;
char *data;
int dlen;
@@ -225,7 +225,7 @@ static const char *cap_list[] = {
#define RESP_NO 1
#define RESP_BAD 2
-static int get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd );
+static int get_cmd_result(imap_store_t *ctx, struct imap_cmd *tcmd);
static const char *Flags[] = {
@@ -243,8 +243,7 @@ static void ssl_socket_perror(const char *func)
}
#endif
-static void
-socket_perror( const char *func, Socket_t *sock, int ret )
+static void socket_perror(const char *func, Socket_t *sock, int ret)
{
#ifndef NO_OPENSSL
if (sock->ssl) {
@@ -321,8 +320,7 @@ static int ssl_socket_connect(Socket_t *sock, int use_tls_only, int verify)
#endif
}
-static int
-socket_read( Socket_t *sock, char *buf, int len )
+static int socket_read(Socket_t *sock, char *buf, int len)
{
ssize_t n;
#ifndef NO_OPENSSL
@@ -330,17 +328,16 @@ socket_read( Socket_t *sock, char *buf, int len )
n = SSL_read(sock->ssl, buf, len);
else
#endif
- n = xread( sock->fd, buf, len );
+ n = xread(sock->fd, buf, len);
if (n <= 0) {
- socket_perror( "read", sock, n );
- close( sock->fd );
+ socket_perror("read", sock, n);
+ close(sock->fd);
sock->fd = -1;
}
return n;
}
-static int
-socket_write( Socket_t *sock, const char *buf, int len )
+static int socket_write(Socket_t *sock, const char *buf, int len)
{
int n;
#ifndef NO_OPENSSL
@@ -348,10 +345,10 @@ socket_write( Socket_t *sock, const char *buf, int len )
n = SSL_write(sock->ssl, buf, len);
else
#endif
- n = write_in_full( sock->fd, buf, len );
+ n = write_in_full(sock->fd, buf, len);
if (n != len) {
- socket_perror( "write", sock, n );
- close( sock->fd );
+ socket_perror("write", sock, n);
+ close(sock->fd);
sock->fd = -1;
}
return n;
@@ -369,8 +366,7 @@ static void socket_shutdown(Socket_t *sock)
}
/* simple line buffering */
-static int
-buffer_gets( buffer_t * b, char **s )
+static int buffer_gets(buffer_t * b, char **s)
{
int n;
int start = b->offset;
@@ -384,7 +380,7 @@ buffer_gets( buffer_t * b, char **s )
/* shift down used bytes */
*s = b->buf;
- assert( start <= b->bytes );
+ assert(start <= b->bytes);
n = b->bytes - start;
if (n)
@@ -394,8 +390,8 @@ buffer_gets( buffer_t * b, char **s )
start = 0;
}
- n = socket_read( &b->sock, b->buf + b->bytes,
- sizeof(b->buf) - b->bytes );
+ n = socket_read(&b->sock, b->buf + b->bytes,
+ sizeof(b->buf) - b->bytes);
if (n <= 0)
return -1;
@@ -404,12 +400,12 @@ buffer_gets( buffer_t * b, char **s )
}
if (b->buf[b->offset] == '\r') {
- assert( b->offset + 1 < b->bytes );
+ assert(b->offset + 1 < b->bytes);
if (b->buf[b->offset + 1] == '\n') {
b->buf[b->offset] = 0; /* terminate the string */
b->offset += 2; /* next line */
if (Verbose)
- puts( *s );
+ puts(*s);
return 0;
}
}
@@ -419,39 +415,36 @@ buffer_gets( buffer_t * b, char **s )
/* not reached */
}
-static void
-imap_info( const char *msg, ... )
+static void imap_info(const char *msg, ...)
{
va_list va;
if (!Quiet) {
- va_start( va, msg );
- vprintf( msg, va );
- va_end( va );
- fflush( stdout );
+ va_start(va, msg);
+ vprintf(msg, va);
+ va_end(va);
+ fflush(stdout);
}
}
-static void
-imap_warn( const char *msg, ... )
+static void imap_warn(const char *msg, ...)
{
va_list va;
if (Quiet < 2) {
- va_start( va, msg );
- vfprintf( stderr, msg, va );
- va_end( va );
+ va_start(va, msg);
+ vfprintf(stderr, msg, va);
+ va_end(va);
}
}
-static char *
-next_arg( char **s )
+static char *next_arg(char **s)
{
char *ret;
if (!s || !*s)
return NULL;
- while (isspace( (unsigned char) **s ))
+ while (isspace((unsigned char) **s))
(*s)++;
if (!**s) {
*s = NULL;
@@ -460,10 +453,10 @@ next_arg( char **s )
if (**s == '"') {
++*s;
ret = *s;
- *s = strchr( *s, '"' );
+ *s = strchr(*s, '"');
} else {
ret = *s;
- while (**s && !isspace( (unsigned char) **s ))
+ while (**s && !isspace((unsigned char) **s))
(*s)++;
}
if (*s) {
@@ -475,27 +468,25 @@ next_arg( char **s )
return ret;
}
-static void
-free_generic_messages( message_t *msgs )
+static void free_generic_messages(message_t *msgs)
{
message_t *tmsg;
for (; msgs; msgs = tmsg) {
tmsg = msgs->next;
- free( msgs );
+ free(msgs);
}
}
-static int
-nfsnprintf( char *buf, int blen, const char *fmt, ... )
+static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
{
int ret;
va_list va;
- va_start( va, fmt );
- if (blen <= 0 || (unsigned)(ret = vsnprintf( buf, blen, fmt, va )) >= (unsigned)blen)
- die( "Fatal: buffer too small. Please report a bug.\n");
- va_end( va );
+ va_start(va, fmt);
+ if (blen <= 0 || (unsigned)(ret = vsnprintf(buf, blen, fmt, va)) >= (unsigned)blen)
+ die("Fatal: buffer too small. Please report a bug.\n");
+ va_end(va);
return ret;
}
@@ -503,21 +494,20 @@ static struct {
unsigned char i, j, s[256];
} rs;
-static void
-arc4_init( void )
+static void arc4_init(void)
{
int i, fd;
unsigned char j, si, dat[128];
- if ((fd = open( "/dev/urandom", O_RDONLY )) < 0 && (fd = open( "/dev/random", O_RDONLY )) < 0) {
- fprintf( stderr, "Fatal: no random number source available.\n" );
- exit( 3 );
+ if ((fd = open("/dev/urandom", O_RDONLY)) < 0 && (fd = open("/dev/random", O_RDONLY)) < 0) {
+ fprintf(stderr, "Fatal: no random number source available.\n");
+ exit(3);
}
- if (read_in_full( fd, dat, 128 ) != 128) {
- fprintf( stderr, "Fatal: cannot read random number source.\n" );
- exit( 3 );
+ if (read_in_full(fd, dat, 128) != 128) {
+ fprintf(stderr, "Fatal: cannot read random number source.\n");
+ exit(3);
}
- close( fd );
+ close(fd);
for (i = 0; i < 256; i++)
rs.s[i] = i;
@@ -533,8 +523,7 @@ arc4_init( void )
arc4_getbyte();
}
-static unsigned char
-arc4_getbyte( void )
+static unsigned char arc4_getbyte(void)
{
unsigned char si, sj;
@@ -547,54 +536,54 @@ arc4_getbyte( void )
return rs.s[(si + sj) & 0xff];
}
-static struct imap_cmd *
-v_issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb,
- const char *fmt, va_list ap )
+static struct imap_cmd *v_issue_imap_cmd(imap_store_t *ctx,
+ struct imap_cmd_cb *cb,
+ const char *fmt, va_list ap)
{
imap_t *imap = ctx->imap;
struct imap_cmd *cmd;
int n, bufl;
char buf[1024];
- cmd = xmalloc( sizeof(struct imap_cmd) );
- nfvasprintf( &cmd->cmd, fmt, ap );
+ cmd = xmalloc(sizeof(struct imap_cmd));
+ nfvasprintf(&cmd->cmd, fmt, ap);
cmd->tag = ++imap->nexttag;
if (cb)
cmd->cb = *cb;
else
- memset( &cmd->cb, 0, sizeof(cmd->cb) );
+ memset(&cmd->cb, 0, sizeof(cmd->cb));
while (imap->literal_pending)
- get_cmd_result( ctx, NULL );
+ get_cmd_result(ctx, NULL);
- bufl = nfsnprintf( buf, sizeof(buf), cmd->cb.data ? CAP(LITERALPLUS) ?
+ bufl = nfsnprintf(buf, sizeof(buf), cmd->cb.data ? CAP(LITERALPLUS) ?
"%d %s{%d+}\r\n" : "%d %s{%d}\r\n" : "%d %s\r\n",
- cmd->tag, cmd->cmd, cmd->cb.dlen );
+ cmd->tag, cmd->cmd, cmd->cb.dlen);
if (Verbose) {
if (imap->num_in_progress)
- printf( "(%d in progress) ", imap->num_in_progress );
- if (memcmp( cmd->cmd, "LOGIN", 5 ))
- printf( ">>> %s", buf );
+ printf("(%d in progress) ", imap->num_in_progress);
+ if (memcmp(cmd->cmd, "LOGIN", 5))
+ printf(">>> %s", buf);
else
- printf( ">>> %d LOGIN <user> <pass>\n", cmd->tag );
+ printf(">>> %d LOGIN <user> <pass>\n", cmd->tag);
}
- if (socket_write( &imap->buf.sock, buf, bufl ) != bufl) {
- free( cmd->cmd );
- free( cmd );
+ if (socket_write(&imap->buf.sock, buf, bufl) != bufl) {
+ free(cmd->cmd);
+ free(cmd);
if (cb)
- free( cb->data );
+ free(cb->data);
return NULL;
}
if (cmd->cb.data) {
if (CAP(LITERALPLUS)) {
- n = socket_write( &imap->buf.sock, cmd->cb.data, cmd->cb.dlen );
- free( cmd->cb.data );
+ n = socket_write(&imap->buf.sock, cmd->cb.data, cmd->cb.dlen);
+ free(cmd->cb.data);
if (n != cmd->cb.dlen ||
- (n = socket_write( &imap->buf.sock, "\r\n", 2 )) != 2)
+ (n = socket_write(&imap->buf.sock, "\r\n", 2)) != 2)
{
- free( cmd->cmd );
- free( cmd );
+ free(cmd->cmd);
+ free(cmd);
return NULL;
}
cmd->cb.data = NULL;
@@ -609,109 +598,106 @@ v_issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb,
return cmd;
}
-static struct imap_cmd *
-issue_imap_cmd( imap_store_t *ctx, struct imap_cmd_cb *cb, const char *fmt, ... )
+static struct imap_cmd *issue_imap_cmd(imap_store_t *ctx,
+ struct imap_cmd_cb *cb,
+ const char *fmt, ...)
{
struct imap_cmd *ret;
va_list ap;
- va_start( ap, fmt );
- ret = v_issue_imap_cmd( ctx, cb, fmt, ap );
- va_end( ap );
+ va_start(ap, fmt);
+ ret = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ va_end(ap);
return ret;
}
-static int
-imap_exec( imap_store_t *ctx, struct imap_cmd_cb *cb, const char *fmt, ... )
+static int imap_exec(imap_store_t *ctx, struct imap_cmd_cb *cb,
+ const char *fmt, ...)
{
va_list ap;
struct imap_cmd *cmdp;
- va_start( ap, fmt );
- cmdp = v_issue_imap_cmd( ctx, cb, fmt, ap );
- va_end( ap );
+ va_start(ap, fmt);
+ cmdp = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ va_end(ap);
if (!cmdp)
return RESP_BAD;
- return get_cmd_result( ctx, cmdp );
+ return get_cmd_result(ctx, cmdp);
}
-static int
-imap_exec_m( imap_store_t *ctx, struct imap_cmd_cb *cb, const char *fmt, ... )
+static int imap_exec_m(imap_store_t *ctx, struct imap_cmd_cb *cb,
+ const char *fmt, ...)
{
va_list ap;
struct imap_cmd *cmdp;
- va_start( ap, fmt );
- cmdp = v_issue_imap_cmd( ctx, cb, fmt, ap );
- va_end( ap );
+ va_start(ap, fmt);
+ cmdp = v_issue_imap_cmd(ctx, cb, fmt, ap);
+ va_end(ap);
if (!cmdp)
return DRV_STORE_BAD;
- switch (get_cmd_result( ctx, cmdp )) {
+ switch (get_cmd_result(ctx, cmdp)) {
case RESP_BAD: return DRV_STORE_BAD;
case RESP_NO: return DRV_MSG_BAD;
default: return DRV_OK;
}
}
-static int
-is_atom( list_t *list )
+static int is_atom(list_t *list)
{
return list && list->val && list->val != NIL && list->val != LIST;
}
-static int
-is_list( list_t *list )
+static int is_list(list_t *list)
{
return list && list->val == LIST;
}
-static void
-free_list( list_t *list )
+static void free_list(list_t *list)
{
list_t *tmp;
for (; list; list = tmp) {
tmp = list->next;
- if (is_list( list ))
- free_list( list->child );
- else if (is_atom( list ))
- free( list->val );
- free( list );
+ if (is_list(list))
+ free_list(list->child);
+ else if (is_atom(list))
+ free(list->val);
+ free(list);
}
}
-static int
-parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
+static int parse_imap_list_l(imap_t *imap, char **sp, list_t **curp, int level)
{
list_t *cur;
char *s = *sp, *p;
int n, bytes;
for (;;) {
- while (isspace( (unsigned char)*s ))
+ while (isspace((unsigned char)*s))
s++;
if (level && *s == ')') {
s++;
break;
}
- *curp = cur = xmalloc( sizeof(*cur) );
+ *curp = cur = xmalloc(sizeof(*cur));
curp = &cur->next;
cur->val = NULL; /* for clean bail */
if (*s == '(') {
/* sublist */
s++;
cur->val = LIST;
- if (parse_imap_list_l( imap, &s, &cur->child, level + 1 ))
+ if (parse_imap_list_l(imap, &s, &cur->child, level + 1))
goto bail;
} else if (imap && *s == '{') {
/* literal */
- bytes = cur->len = strtol( s + 1, &s, 10 );
+ bytes = cur->len = strtol(s + 1, &s, 10);
if (*s != '}')
goto bail;
- s = cur->val = xmalloc( cur->len );
+ s = cur->val = xmalloc(cur->len);
/* dump whats left over in the input buffer */
n = imap->buf.bytes - imap->buf.offset;
@@ -720,7 +706,7 @@ parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
/* the entire message fit in the buffer */
n = bytes;
- memcpy( s, imap->buf.buf + imap->buf.offset, n );
+ memcpy(s, imap->buf.buf + imap->buf.offset, n);
s += n;
bytes -= n;
@@ -729,13 +715,13 @@ parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
/* now read the rest of the message */
while (bytes > 0) {
- if ((n = socket_read (&imap->buf.sock, s, bytes)) <= 0)
+ if ((n = socket_read(&imap->buf.sock, s, bytes)) <= 0)
goto bail;
s += n;
bytes -= n;
}
- if (buffer_gets( &imap->buf, &s ))
+ if (buffer_gets(&imap->buf, &s))
goto bail;
} else if (*s == '"') {
/* quoted string */
@@ -750,11 +736,11 @@ parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
} else {
/* atom */
p = s;
- for (; *s && !isspace( (unsigned char)*s ); s++)
+ for (; *s && !isspace((unsigned char)*s); s++)
if (level && *s == ')')
break;
cur->len = s - p;
- if (cur->len == 3 && !memcmp ("NIL", p, 3)) {
+ if (cur->len == 3 && !memcmp("NIL", p, 3)) {
cur->val = NIL;
} else {
cur->val = xmemdupz(p, cur->len);
@@ -775,39 +761,36 @@ parse_imap_list_l( imap_t *imap, char **sp, list_t **curp, int level )
return -1;
}
-static list_t *
-parse_imap_list( imap_t *imap, char **sp )
+static list_t *parse_imap_list(imap_t *imap, char **sp)
{
list_t *head;
- if (!parse_imap_list_l( imap, sp, &head, 0 ))
+ if (!parse_imap_list_l(imap, sp, &head, 0))
return head;
- free_list( head );
+ free_list(head);
return NULL;
}
-static list_t *
-parse_list( char **sp )
+static list_t *parse_list(char **sp)
{
- return parse_imap_list( NULL, sp );
+ return parse_imap_list(NULL, sp);
}
-static void
-parse_capability( imap_t *imap, char *cmd )
+static void parse_capability(imap_t *imap, char *cmd)
{
char *arg;
unsigned i;
imap->caps = 0x80000000;
- while ((arg = next_arg( &cmd )))
+ while ((arg = next_arg(&cmd)))
for (i = 0; i < ARRAY_SIZE(cap_list); i++)
- if (!strcmp( cap_list[i], arg ))
+ if (!strcmp(cap_list[i], arg))
imap->caps |= 1 << i;
imap->rcaps = imap->caps;
}
-static int
-parse_response_code( imap_store_t *ctx, struct imap_cmd_cb *cb, char *s )
+static int parse_response_code(imap_store_t *ctx, struct imap_cmd_cb *cb,
+ char *s)
{
imap_t *imap = ctx->imap;
char *arg, *p;
@@ -815,43 +798,42 @@ parse_response_code( imap_store_t *ctx, struct imap_cmd_cb *cb, char *s )
if (*s != '[')
return RESP_OK; /* no response code */
s++;
- if (!(p = strchr( s, ']' ))) {
- fprintf( stderr, "IMAP error: malformed response code\n" );
+ if (!(p = strchr(s, ']'))) {
+ fprintf(stderr, "IMAP error: malformed response code\n");
return RESP_BAD;
}
*p++ = 0;
- arg = next_arg( &s );
- if (!strcmp( "UIDVALIDITY", arg )) {
- if (!(arg = next_arg( &s )) || !(ctx->gen.uidvalidity = atoi( arg ))) {
- fprintf( stderr, "IMAP error: malformed UIDVALIDITY status\n" );
+ arg = next_arg(&s);
+ if (!strcmp("UIDVALIDITY", arg)) {
+ if (!(arg = next_arg(&s)) || !(ctx->gen.uidvalidity = atoi(arg))) {
+ fprintf(stderr, "IMAP error: malformed UIDVALIDITY status\n");
return RESP_BAD;
}
- } else if (!strcmp( "UIDNEXT", arg )) {
- if (!(arg = next_arg( &s )) || !(imap->uidnext = atoi( arg ))) {
- fprintf( stderr, "IMAP error: malformed NEXTUID status\n" );
+ } else if (!strcmp("UIDNEXT", arg)) {
+ if (!(arg = next_arg(&s)) || !(imap->uidnext = atoi(arg))) {
+ fprintf(stderr, "IMAP error: malformed NEXTUID status\n");
return RESP_BAD;
}
- } else if (!strcmp( "CAPABILITY", arg )) {
- parse_capability( imap, s );
- } else if (!strcmp( "ALERT", arg )) {
+ } else if (!strcmp("CAPABILITY", arg)) {
+ parse_capability(imap, s);
+ } else if (!strcmp("ALERT", arg)) {
/* RFC2060 says that these messages MUST be displayed
* to the user
*/
- for (; isspace( (unsigned char)*p ); p++);
- fprintf( stderr, "*** IMAP ALERT *** %s\n", p );
- } else if (cb && cb->ctx && !strcmp( "APPENDUID", arg )) {
- if (!(arg = next_arg( &s )) || !(ctx->gen.uidvalidity = atoi( arg )) ||
- !(arg = next_arg( &s )) || !(*(int *)cb->ctx = atoi( arg )))
+ for (; isspace((unsigned char)*p); p++);
+ fprintf(stderr, "*** IMAP ALERT *** %s\n", p);
+ } else if (cb && cb->ctx && !strcmp("APPENDUID", arg)) {
+ if (!(arg = next_arg(&s)) || !(ctx->gen.uidvalidity = atoi(arg)) ||
+ !(arg = next_arg(&s)) || !(*(int *)cb->ctx = atoi(arg)))
{
- fprintf( stderr, "IMAP error: malformed APPENDUID status\n" );
+ fprintf(stderr, "IMAP error: malformed APPENDUID status\n");
return RESP_BAD;
}
}
return RESP_OK;
}
-static int
-get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
+static int get_cmd_result(imap_store_t *ctx, struct imap_cmd *tcmd)
{
imap_t *imap = ctx->imap;
struct imap_cmd *cmdp, **pcmdp, *ncmdp;
@@ -859,38 +841,38 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
int n, resp, resp2, tag;
for (;;) {
- if (buffer_gets( &imap->buf, &cmd ))
+ if (buffer_gets(&imap->buf, &cmd))
return RESP_BAD;
- arg = next_arg( &cmd );
+ arg = next_arg(&cmd);
if (*arg == '*') {
- arg = next_arg( &cmd );
+ arg = next_arg(&cmd);
if (!arg) {
- fprintf( stderr, "IMAP error: unable to parse untagged response\n" );
+ fprintf(stderr, "IMAP error: unable to parse untagged response\n");
return RESP_BAD;
}
- if (!strcmp( "NAMESPACE", arg )) {
- imap->ns_personal = parse_list( &cmd );
- imap->ns_other = parse_list( &cmd );
- imap->ns_shared = parse_list( &cmd );
- } else if (!strcmp( "OK", arg ) || !strcmp( "BAD", arg ) ||
- !strcmp( "NO", arg ) || !strcmp( "BYE", arg )) {
- if ((resp = parse_response_code( ctx, NULL, cmd )) != RESP_OK)
+ if (!strcmp("NAMESPACE", arg)) {
+ imap->ns_personal = parse_list(&cmd);
+ imap->ns_other = parse_list(&cmd);
+ imap->ns_shared = parse_list(&cmd);
+ } else if (!strcmp("OK", arg) || !strcmp("BAD", arg) ||
+ !strcmp("NO", arg) || !strcmp("BYE", arg)) {
+ if ((resp = parse_response_code(ctx, NULL, cmd)) != RESP_OK)
return resp;
- } else if (!strcmp( "CAPABILITY", arg ))
- parse_capability( imap, cmd );
- else if ((arg1 = next_arg( &cmd ))) {
- if (!strcmp( "EXISTS", arg1 ))
- ctx->gen.count = atoi( arg );
- else if (!strcmp( "RECENT", arg1 ))
- ctx->gen.recent = atoi( arg );
+ } else if (!strcmp("CAPABILITY", arg))
+ parse_capability(imap, cmd);
+ else if ((arg1 = next_arg(&cmd))) {
+ if (!strcmp("EXISTS", arg1))
+ ctx->gen.count = atoi(arg);
+ else if (!strcmp("RECENT", arg1))
+ ctx->gen.recent = atoi(arg);
} else {
- fprintf( stderr, "IMAP error: unable to parse untagged response\n" );
+ fprintf(stderr, "IMAP error: unable to parse untagged response\n");
return RESP_BAD;
}
} else if (!imap->in_progress) {
- fprintf( stderr, "IMAP error: unexpected reply: %s %s\n", arg, cmd ? cmd : "" );
+ fprintf(stderr, "IMAP error: unexpected reply: %s %s\n", arg, cmd ? cmd : "");
return RESP_BAD;
} else if (*arg == '+') {
/* This can happen only with the last command underway, as
@@ -898,30 +880,30 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
cmdp = (struct imap_cmd *)((char *)imap->in_progress_append -
offsetof(struct imap_cmd, next));
if (cmdp->cb.data) {
- n = socket_write( &imap->buf.sock, cmdp->cb.data, cmdp->cb.dlen );
- free( cmdp->cb.data );
+ n = socket_write(&imap->buf.sock, cmdp->cb.data, cmdp->cb.dlen);
+ free(cmdp->cb.data);
cmdp->cb.data = NULL;
if (n != (int)cmdp->cb.dlen)
return RESP_BAD;
} else if (cmdp->cb.cont) {
- if (cmdp->cb.cont( ctx, cmdp, cmd ))
+ if (cmdp->cb.cont(ctx, cmdp, cmd))
return RESP_BAD;
} else {
- fprintf( stderr, "IMAP error: unexpected command continuation request\n" );
+ fprintf(stderr, "IMAP error: unexpected command continuation request\n");
return RESP_BAD;
}
- if (socket_write( &imap->buf.sock, "\r\n", 2 ) != 2)
+ if (socket_write(&imap->buf.sock, "\r\n", 2) != 2)
return RESP_BAD;
if (!cmdp->cb.cont)
imap->literal_pending = 0;
if (!tcmd)
return DRV_OK;
} else {
- tag = atoi( arg );
+ tag = atoi(arg);
for (pcmdp = &imap->in_progress; (cmdp = *pcmdp); pcmdp = &cmdp->next)
if (cmdp->tag == tag)
goto gottag;
- fprintf( stderr, "IMAP error: unexpected tag %s\n", arg );
+ fprintf(stderr, "IMAP error: unexpected tag %s\n", arg);
return RESP_BAD;
gottag:
if (!(*pcmdp = cmdp->next))
@@ -929,26 +911,26 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
imap->num_in_progress--;
if (cmdp->cb.cont || cmdp->cb.data)
imap->literal_pending = 0;
- arg = next_arg( &cmd );
- if (!strcmp( "OK", arg ))
+ arg = next_arg(&cmd);
+ if (!strcmp("OK", arg))
resp = DRV_OK;
else {
- if (!strcmp( "NO", arg )) {
- if (cmdp->cb.create && cmd && (cmdp->cb.trycreate || !memcmp( cmd, "[TRYCREATE]", 11 ))) { /* SELECT, APPEND or UID COPY */
- p = strchr( cmdp->cmd, '"' );
- if (!issue_imap_cmd( ctx, NULL, "CREATE \"%.*s\"", strchr( p + 1, '"' ) - p + 1, p )) {
+ if (!strcmp("NO", arg)) {
+ if (cmdp->cb.create && cmd && (cmdp->cb.trycreate || !memcmp(cmd, "[TRYCREATE]", 11))) { /* SELECT, APPEND or UID COPY */
+ p = strchr(cmdp->cmd, '"');
+ if (!issue_imap_cmd(ctx, NULL, "CREATE \"%.*s\"", strchr(p + 1, '"') - p + 1, p)) {
resp = RESP_BAD;
goto normal;
}
/* not waiting here violates the spec, but a server that does not
grok this nonetheless violates it too. */
cmdp->cb.create = 0;
- if (!(ncmdp = issue_imap_cmd( ctx, &cmdp->cb, "%s", cmdp->cmd ))) {
+ if (!(ncmdp = issue_imap_cmd(ctx, &cmdp->cb, "%s", cmdp->cmd))) {
resp = RESP_BAD;
goto normal;
}
- free( cmdp->cmd );
- free( cmdp );
+ free(cmdp->cmd);
+ free(cmdp);
if (!tcmd)
return 0; /* ignored */
if (cmdp == tcmd)
@@ -956,21 +938,21 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
continue;
}
resp = RESP_NO;
- } else /*if (!strcmp( "BAD", arg ))*/
+ } else /*if (!strcmp("BAD", arg))*/
resp = RESP_BAD;
- fprintf( stderr, "IMAP command '%s' returned response (%s) - %s\n",
- memcmp (cmdp->cmd, "LOGIN", 5) ?
+ fprintf(stderr, "IMAP command '%s' returned response (%s) - %s\n",
+ memcmp(cmdp->cmd, "LOGIN", 5) ?
cmdp->cmd : "LOGIN <user> <pass>",
arg, cmd ? cmd : "");
}
- if ((resp2 = parse_response_code( ctx, &cmdp->cb, cmd )) > resp)
+ if ((resp2 = parse_response_code(ctx, &cmdp->cb, cmd)) > resp)
resp = resp2;
normal:
if (cmdp->cb.done)
- cmdp->cb.done( ctx, cmdp, resp );
- free( cmdp->cb.data );
- free( cmdp->cmd );
- free( cmdp );
+ cmdp->cb.done(ctx, cmdp, resp);
+ free(cmdp->cb.data);
+ free(cmdp->cmd);
+ free(cmdp);
if (!tcmd || tcmd == cmdp)
return resp;
}
@@ -978,31 +960,28 @@ get_cmd_result( imap_store_t *ctx, struct imap_cmd *tcmd )
/* not reached */
}
-static void
-imap_close_server( imap_store_t *ictx )
+static void imap_close_server(imap_store_t *ictx)
{
imap_t *imap = ictx->imap;
if (imap->buf.sock.fd != -1) {
- imap_exec( ictx, NULL, "LOGOUT" );
- socket_shutdown( &imap->buf.sock );
+ imap_exec(ictx, NULL, "LOGOUT");
+ socket_shutdown(&imap->buf.sock);
}
- free_list( imap->ns_personal );
- free_list( imap->ns_other );
- free_list( imap->ns_shared );
- free( imap );
+ free_list(imap->ns_personal);
+ free_list(imap->ns_other);
+ free_list(imap->ns_shared);
+ free(imap);
}
-static void
-imap_close_store( store_t *ctx )
+static void imap_close_store(store_t *ctx)
{
- imap_close_server( (imap_store_t *)ctx );
- free_generic_messages( ctx->msgs );
- free( ctx );
+ imap_close_server((imap_store_t *)ctx);
+ free_generic_messages(ctx->msgs);
+ free(ctx);
}
-static store_t *
-imap_open_store( imap_server_conf_t *srvc )
+static store_t *imap_open_store(imap_server_conf_t *srvc)
{
imap_store_t *ctx;
imap_t *imap;
@@ -1012,9 +991,9 @@ imap_open_store( imap_server_conf_t *srvc )
int s, a[2], preauth;
pid_t pid;
- ctx = xcalloc( sizeof(*ctx), 1 );
+ ctx = xcalloc(sizeof(*ctx), 1);
- ctx->imap = imap = xcalloc( sizeof(*imap), 1 );
+ ctx->imap = imap = xcalloc(sizeof(*imap), 1);
imap->buf.sock.fd = -1;
imap->buf.sock.ssl = NULL;
imap->in_progress_append = &imap->in_progress;
@@ -1022,51 +1001,51 @@ imap_open_store( imap_server_conf_t *srvc )
/* open connection to IMAP server */
if (srvc->tunnel) {
- imap_info( "Starting tunnel '%s'... ", srvc->tunnel );
+ imap_info("Starting tunnel '%s'... ", srvc->tunnel);
- if (socketpair( PF_UNIX, SOCK_STREAM, 0, a )) {
- perror( "socketpair" );
- exit( 1 );
+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, a)) {
+ perror("socketpair");
+ exit(1);
}
pid = fork();
if (pid < 0)
- _exit( 127 );
+ _exit(127);
if (!pid) {
- if (dup2( a[0], 0 ) == -1 || dup2( a[0], 1 ) == -1)
- _exit( 127 );
- close( a[0] );
- close( a[1] );
- execl( "/bin/sh", "sh", "-c", srvc->tunnel, NULL );
- _exit( 127 );
+ if (dup2(a[0], 0) == -1 || dup2(a[0], 1) == -1)
+ _exit(127);
+ close(a[0]);
+ close(a[1]);
+ execl("/bin/sh", "sh", "-c", srvc->tunnel, NULL);
+ _exit(127);
}
- close (a[0]);
+ close(a[0]);
imap->buf.sock.fd = a[1];
- imap_info( "ok\n" );
+ imap_info("ok\n");
} else {
- memset( &addr, 0, sizeof(addr) );
- addr.sin_port = htons( srvc->port );
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_port = htons(srvc->port);
addr.sin_family = AF_INET;
- imap_info( "Resolving %s... ", srvc->host );
- he = gethostbyname( srvc->host );
+ imap_info("Resolving %s... ", srvc->host);
+ he = gethostbyname(srvc->host);
if (!he) {
- perror( "gethostbyname" );
+ perror("gethostbyname");
goto bail;
}
- imap_info( "ok\n" );
+ imap_info("ok\n");
addr.sin_addr.s_addr = *((int *) he->h_addr_list[0]);
- s = socket( PF_INET, SOCK_STREAM, 0 );
+ s = socket(PF_INET, SOCK_STREAM, 0);
- imap_info( "Connecting to %s:%hu... ", inet_ntoa( addr.sin_addr ), ntohs( addr.sin_port ) );
- if (connect( s, (struct sockaddr *)&addr, sizeof(addr) )) {
- close( s );
- perror( "connect" );
+ imap_info("Connecting to %s:%hu... ", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ if (connect(s, (struct sockaddr *)&addr, sizeof(addr))) {
+ close(s);
+ perror("connect");
goto bail;
}
@@ -1077,28 +1056,28 @@ imap_open_store( imap_server_conf_t *srvc )
close(s);
goto bail;
}
- imap_info( "ok\n" );
+ imap_info("ok\n");
}
/* read the greeting string */
- if (buffer_gets( &imap->buf, &rsp )) {
- fprintf( stderr, "IMAP error: no greeting response\n" );
+ if (buffer_gets(&imap->buf, &rsp)) {
+ fprintf(stderr, "IMAP error: no greeting response\n");
goto bail;
}
- arg = next_arg( &rsp );
- if (!arg || *arg != '*' || (arg = next_arg( &rsp )) == NULL) {
- fprintf( stderr, "IMAP error: invalid greeting response\n" );
+ arg = next_arg(&rsp);
+ if (!arg || *arg != '*' || (arg = next_arg(&rsp)) == NULL) {
+ fprintf(stderr, "IMAP error: invalid greeting response\n");
goto bail;
}
preauth = 0;
- if (!strcmp( "PREAUTH", arg ))
+ if (!strcmp("PREAUTH", arg))
preauth = 1;
- else if (strcmp( "OK", arg ) != 0) {
- fprintf( stderr, "IMAP error: unknown greeting response\n" );
+ else if (strcmp("OK", arg) != 0) {
+ fprintf(stderr, "IMAP error: unknown greeting response\n");
goto bail;
}
- parse_response_code( ctx, NULL, rsp );
- if (!imap->caps && imap_exec( ctx, NULL, "CAPABILITY" ) != RESP_OK)
+ parse_response_code(ctx, NULL, rsp);
+ if (!imap->caps && imap_exec(ctx, NULL, "CAPABILITY") != RESP_OK)
goto bail;
if (!preauth) {
@@ -1114,38 +1093,38 @@ imap_open_store( imap_server_conf_t *srvc )
goto bail;
}
#endif
- imap_info ("Logging in...\n");
+ imap_info("Logging in...\n");
if (!srvc->user) {
- fprintf( stderr, "Skipping server %s, no user\n", srvc->host );
+ fprintf(stderr, "Skipping server %s, no user\n", srvc->host);
goto bail;
}
if (!srvc->pass) {
char prompt[80];
- sprintf( prompt, "Password (%s@%s): ", srvc->user, srvc->host );
- arg = getpass( prompt );
+ sprintf(prompt, "Password (%s@%s): ", srvc->user, srvc->host);
+ arg = getpass(prompt);
if (!arg) {
- perror( "getpass" );
- exit( 1 );
+ perror("getpass");
+ exit(1);
}
if (!*arg) {
- fprintf( stderr, "Skipping account %s@%s, no password\n", srvc->user, srvc->host );
+ fprintf(stderr, "Skipping account %s@%s, no password\n", srvc->user, srvc->host);
goto bail;
}
/*
* getpass() returns a pointer to a static buffer. make a copy
* for long term storage.
*/
- srvc->pass = xstrdup( arg );
+ srvc->pass = xstrdup(arg);
}
if (CAP(NOLOGIN)) {
- fprintf( stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host );
+ fprintf(stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host);
goto bail;
}
if (!imap->buf.sock.ssl)
imap_warn( "*** IMAP Warning *** Password is being "
"sent in the clear\n" );
- if (imap_exec( ctx, NULL, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass ) != RESP_OK) {
- fprintf( stderr, "IMAP error: LOGIN failed\n" );
+ if (imap_exec(ctx, NULL, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass) != RESP_OK) {
+ fprintf(stderr, "IMAP error: LOGIN failed\n");
goto bail;
}
} /* !preauth */
@@ -1155,12 +1134,11 @@ imap_open_store( imap_server_conf_t *srvc )
return (store_t *)ctx;
bail:
- imap_close_store( &ctx->gen );
+ imap_close_store(&ctx->gen);
return NULL;
}
-static int
-imap_make_flags( int flags, char *buf )
+static int imap_make_flags(int flags, char *buf)
{
const char *s;
unsigned i, d;
@@ -1179,8 +1157,7 @@ imap_make_flags( int flags, char *buf )
#define TUIDL 8
-static int
-imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
+static int imap_store_msg(store_t *gctx, msg_data_t *data, int *uid)
{
imap_store_t *ctx = (imap_store_t *)gctx;
imap_t *imap = ctx->imap;
@@ -1191,7 +1168,7 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
int start, sbreak = 0, ebreak = 0;
char flagstr[128], tuid[TUIDL * 2 + 1];
- memset( &cb, 0, sizeof(cb) );
+ memset(&cb, 0, sizeof(cb));
fmap = data->data;
len = data->len;
@@ -1207,18 +1184,18 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
sbreak = ebreak = i - 2 + nocr;
goto mktid;
}
- if (!memcmp( fmap + start, "X-TUID: ", 8 )) {
+ if (!memcmp(fmap + start, "X-TUID: ", 8)) {
extra -= (ebreak = i) - (sbreak = start) + nocr;
goto mktid;
}
goto nloop;
}
/* invalid message */
- free( fmap );
+ free(fmap);
return DRV_MSG_BAD;
mktid:
for (j = 0; j < TUIDL; j++)
- sprintf( tuid + j * 2, "%02x", arc4_getbyte() );
+ sprintf(tuid + j * 2, "%02x", arc4_getbyte());
extra += 8 + TUIDL * 2 + 2;
}
if (nocr)
@@ -1227,7 +1204,7 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
extra++;
cb.dlen = len + extra;
- buf = cb.data = xmalloc( cb.dlen );
+ buf = cb.data = xmalloc(cb.dlen);
i = 0;
if (!CAP(UIDPLUS) && uid) {
if (nocr) {
@@ -1238,12 +1215,12 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
} else
*buf++ = fmap[i];
} else {
- memcpy( buf, fmap, sbreak );
+ memcpy(buf, fmap, sbreak);
buf += sbreak;
}
- memcpy( buf, "X-TUID: ", 8 );
+ memcpy(buf, "X-TUID: ", 8);
buf += 8;
- memcpy( buf, tuid, TUIDL * 2 );
+ memcpy(buf, tuid, TUIDL * 2);
buf += TUIDL * 2;
*buf++ = '\r';
*buf++ = '\n';
@@ -1257,13 +1234,13 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
} else
*buf++ = fmap[i];
} else
- memcpy( buf, fmap + i, len - i );
+ memcpy(buf, fmap + i, len - i);
- free( fmap );
+ free(fmap);
d = 0;
if (data->flags) {
- d = imap_make_flags( data->flags, flagstr );
+ d = imap_make_flags(data->flags, flagstr);
flagstr[d++] = ' ';
}
flagstr[d] = 0;
@@ -1276,11 +1253,11 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
imap->caps = imap->rcaps & ~(1 << LITERALPLUS);
} else {
box = gctx->name;
- prefix = !strcmp( box, "INBOX" ) ? "" : ctx->prefix;
+ prefix = !strcmp(box, "INBOX") ? "" : ctx->prefix;
cb.create = 0;
}
cb.ctx = uid;
- ret = imap_exec_m( ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr );
+ ret = imap_exec_m(ctx, &cb, "APPEND \"%s%s\" %s", prefix, box, flagstr);
imap->caps = imap->rcaps;
if (ret != DRV_OK)
return ret;
@@ -1294,8 +1271,7 @@ imap_store_msg( store_t *gctx, msg_data_t *data, int *uid )
#define CHUNKSIZE 0x1000
-static int
-read_message( FILE *f, msg_data_t *msg )
+static int read_message(FILE *f, msg_data_t *msg)
{
struct strbuf buf;
@@ -1312,8 +1288,7 @@ read_message( FILE *f, msg_data_t *msg )
return msg->len;
}
-static int
-count_messages( msg_data_t *msg )
+static int count_messages(msg_data_t *msg)
{
int count = 0;
char *p = msg->data;
@@ -1323,7 +1298,7 @@ count_messages( msg_data_t *msg )
count++;
p += 5;
}
- p = strstr( p+5, "\nFrom ");
+ p = strstr(p+5, "\nFrom ");
if (!p)
break;
p++;
@@ -1331,22 +1306,21 @@ count_messages( msg_data_t *msg )
return count;
}
-static int
-split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs )
+static int split_msg(msg_data_t *all_msgs, msg_data_t *msg, int *ofs)
{
char *p, *data;
- memset( msg, 0, sizeof *msg );
+ memset(msg, 0, sizeof *msg);
if (*ofs >= all_msgs->len)
return 0;
- data = &all_msgs->data[ *ofs ];
+ data = &all_msgs->data[*ofs];
msg->len = all_msgs->len - *ofs;
if (msg->len < 5 || prefixcmp(data, "From "))
return 0;
- p = strchr( data, '\n' );
+ p = strchr(data, '\n');
if (p) {
p = &p[1];
msg->len -= p-data;
@@ -1354,7 +1328,7 @@ split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs )
data = p;
}
- p = strstr( data, "\nFrom " );
+ p = strstr(data, "\nFrom ");
if (p)
msg->len = &p[1] - data;
@@ -1363,8 +1337,7 @@ split_msg( msg_data_t *all_msgs, msg_data_t *msg, int *ofs )
return 1;
}
-static imap_server_conf_t server =
-{
+static imap_server_conf_t server = {
NULL, /* name */
NULL, /* tunnel */
NULL, /* host */
@@ -1377,12 +1350,11 @@ static imap_server_conf_t server =
static char *imap_folder;
-static int
-git_imap_config(const char *key, const char *val, void *cb)
+static int git_imap_config(const char *key, const char *val, void *cb)
{
char imap_key[] = "imap.";
- if (strncmp( key, imap_key, sizeof imap_key - 1 ))
+ if (strncmp(key, imap_key, sizeof imap_key - 1))
return 0;
if (!val)
@@ -1390,9 +1362,9 @@ git_imap_config(const char *key, const char *val, void *cb)
key += sizeof imap_key - 1;
- if (!strcmp( "folder", key )) {
- imap_folder = xstrdup( val );
- } else if (!strcmp( "host", key )) {
+ if (!strcmp("folder", key)) {
+ imap_folder = xstrdup(val);
+ } else if (!strcmp("host", key)) {
if (!prefixcmp(val, "imap:"))
val += 5;
else if (!prefixcmp(val, "imaps:")) {
@@ -1401,23 +1373,22 @@ git_imap_config(const char *key, const char *val, void *cb)
}
if (!prefixcmp(val, "//"))
val += 2;
- server.host = xstrdup( val );
+ server.host = xstrdup(val);
}
- else if (!strcmp( "user", key ))
- server.user = xstrdup( val );
- else if (!strcmp( "pass", key ))
- server.pass = xstrdup( val );
- else if (!strcmp( "port", key ))
- server.port = git_config_int( key, val );
- else if (!strcmp( "tunnel", key ))
- server.tunnel = xstrdup( val );
- else if (!strcmp( "ssl_verify", key ))
- server.ssl_verify = git_config_bool( key, val );
+ else if (!strcmp("user", key))
+ server.user = xstrdup(val);
+ else if (!strcmp("pass", key))
+ server.pass = xstrdup(val);
+ else if (!strcmp("port", key))
+ server.port = git_config_int(key, val);
+ else if (!strcmp("tunnel", key))
+ server.tunnel = xstrdup(val);
+ else if (!strcmp("sslverify", key))
+ server.ssl_verify = git_config_bool(key, val);
return 0;
}
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
{
msg_data_t all_msgs, msg;
store_t *ctx = NULL;
@@ -1437,50 +1408,50 @@ main(int argc, char **argv)
server.port = server.use_ssl ? 993 : 143;
if (!imap_folder) {
- fprintf( stderr, "no imap store specified\n" );
+ fprintf(stderr, "no imap store specified\n");
return 1;
}
if (!server.host) {
if (!server.tunnel) {
- fprintf( stderr, "no imap host specified\n" );
+ fprintf(stderr, "no imap host specified\n");
return 1;
}
server.host = "tunnel";
}
/* read the messages */
- if (!read_message( stdin, &all_msgs )) {
+ if (!read_message(stdin, &all_msgs)) {
fprintf(stderr,"nothing to send\n");
return 1;
}
- total = count_messages( &all_msgs );
+ total = count_messages(&all_msgs);
if (!total) {
fprintf(stderr,"no messages to send\n");
return 1;
}
/* write it to the imap server */
- ctx = imap_open_store( &server );
+ ctx = imap_open_store(&server);
if (!ctx) {
- fprintf( stderr,"failed to open store\n");
+ fprintf(stderr,"failed to open store\n");
return 1;
}
- fprintf( stderr, "sending %d message%s\n", total, (total!=1)?"s":"" );
+ fprintf(stderr, "sending %d message%s\n", total, (total!=1)?"s":"");
ctx->name = imap_folder;
while (1) {
unsigned percent = n * 100 / total;
- fprintf( stderr, "%4u%% (%d/%d) done\r", percent, n, total );
- if (!split_msg( &all_msgs, &msg, &ofs ))
+ fprintf(stderr, "%4u%% (%d/%d) done\r", percent, n, total);
+ if (!split_msg(&all_msgs, &msg, &ofs))
break;
- r = imap_store_msg( ctx, &msg, &uid );
+ r = imap_store_msg(ctx, &msg, &uid);
if (r != DRV_OK) break;
n++;
}
- fprintf( stderr,"\n" );
+ fprintf(stderr, "\n");
- imap_close_store( ctx );
+ imap_close_store(ctx);
return 0;
}
--
1.5.6.2.224.g26efb.dirty
^ permalink raw reply related
* [PATCH 2/4] git-imap-send: Add support for SSL.
From: Robert Shearman @ 2008-07-09 21:29 UTC (permalink / raw)
To: git; +Cc: Robert Shearman, Robert Shearman
From: Robert Shearman <rob@codeweavers.com>
Allow SSL to be used when a imaps:// URL is used for the host name.
Also, automatically use TLS when not using imaps:// by using the IMAP STARTTLS command, if the server supports it.
Tested with Courier and Gimap IMAP servers.
Signed-off-by: Robert Shearman <robertshearman@gmail.com>
---
Documentation/git-imap-send.txt | 3 +-
Makefile | 4 +-
imap-send.c | 166 +++++++++++++++++++++++++++++++++++----
3 files changed, 156 insertions(+), 17 deletions(-)
diff --git a/Documentation/git-imap-send.txt b/Documentation/git-imap-send.txt
index b3d8da3..136c82b 100644
--- a/Documentation/git-imap-send.txt
+++ b/Documentation/git-imap-send.txt
@@ -37,10 +37,11 @@ configuration file (shown with examples):
Tunnel = "ssh -q user@server.com /usr/bin/imapd ./Maildir 2> /dev/null"
[imap]
- Host = imap.server.com
+ Host = imap://imap.example.com
User = bob
Pass = pwd
Port = 143
+ sslverify = false
..........................
diff --git a/Makefile b/Makefile
index 4796565..55ec6ee 100644
--- a/Makefile
+++ b/Makefile
@@ -1193,7 +1193,9 @@ endif
git-%$X: %.o $(GITLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
-git-imap-send$X: imap-send.o $(LIB_FILE)
+git-imap-send$X: imap-send.o $(GITLIBS)
+ $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
+ $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL)
http.o http-walker.o http-push.o transport.o: http.h
diff --git a/imap-send.c b/imap-send.c
index 24d76a7..26d1dba 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -23,6 +23,12 @@
*/
#include "cache.h"
+#ifdef NO_OPENSSL
+typedef void *SSL;
+#else
+# include <openssl/ssl.h>
+# include <openssl/err.h>
+#endif
typedef struct store_conf {
char *name;
@@ -129,6 +135,8 @@ typedef struct imap_server_conf {
int port;
char *user;
char *pass;
+ int use_ssl;
+ int ssl_verify;
} imap_server_conf_t;
typedef struct imap_store_conf {
@@ -148,6 +156,7 @@ typedef struct _list {
typedef struct {
int fd;
+ SSL *ssl;
} Socket_t;
typedef struct {
@@ -201,6 +210,7 @@ enum CAPABILITY {
UIDPLUS,
LITERALPLUS,
NAMESPACE,
+ STARTTLS,
};
static const char *cap_list[] = {
@@ -208,6 +218,7 @@ static const char *cap_list[] = {
"UIDPLUS",
"LITERAL+",
"NAMESPACE",
+ "STARTTLS",
};
#define RESP_OK 0
@@ -225,19 +236,101 @@ static const char *Flags[] = {
"Deleted",
};
+#ifndef NO_OPENSSL
+static void ssl_socket_perror(const char *func)
+{
+ fprintf(stderr, "%s: %s\n", func, ERR_error_string(ERR_get_error(), 0));
+}
+#endif
+
static void
socket_perror( const char *func, Socket_t *sock, int ret )
{
- if (ret < 0)
- perror( func );
+#ifndef NO_OPENSSL
+ if (sock->ssl) {
+ int sslerr = SSL_get_error(sock->ssl, ret);
+ switch (sslerr) {
+ case SSL_ERROR_NONE:
+ break;
+ case SSL_ERROR_SYSCALL:
+ perror("SSL_connect");
+ break;
+ default:
+ ssl_socket_perror("SSL_connect");
+ break;
+ }
+ } else
+#endif
+ {
+ if (ret < 0)
+ perror(func);
+ else
+ fprintf(stderr, "%s: unexpected EOF\n", func);
+ }
+}
+
+static int ssl_socket_connect(Socket_t *sock, int use_tls_only, int verify)
+{
+#ifdef NO_OPENSSL
+ fprintf(stderr, "SSL requested but SSL support not compiled in\n");
+ return -1;
+#else
+ SSL_METHOD *meth;
+ SSL_CTX *ctx;
+ int ret;
+
+ SSL_library_init();
+ SSL_load_error_strings();
+
+ if (use_tls_only)
+ meth = TLSv1_method();
else
- fprintf( stderr, "%s: unexpected EOF\n", func );
+ meth = SSLv23_method();
+
+ if (!meth) {
+ ssl_socket_perror("SSLv23_method");
+ return -1;
+ }
+
+ ctx = SSL_CTX_new(meth);
+
+ if (verify)
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
+
+ if (!SSL_CTX_set_default_verify_paths(ctx)) {
+ ssl_socket_perror("SSL_CTX_set_default_verify_paths");
+ return -1;
+ }
+ sock->ssl = SSL_new(ctx);
+ if (!sock->ssl) {
+ ssl_socket_perror("SSL_new");
+ return -1;
+ }
+ if (!SSL_set_fd(sock->ssl, sock->fd)) {
+ ssl_socket_perror("SSL_set_fd");
+ return -1;
+ }
+
+ ret = SSL_connect(sock->ssl);
+ if (ret <= 0) {
+ socket_perror("SSL_connect", sock, ret);
+ return -1;
+ }
+
+ return 0;
+#endif
}
static int
socket_read( Socket_t *sock, char *buf, int len )
{
- ssize_t n = xread( sock->fd, buf, len );
+ ssize_t n;
+#ifndef NO_OPENSSL
+ if (sock->ssl)
+ n = SSL_read(sock->ssl, buf, len);
+ else
+#endif
+ n = xread( sock->fd, buf, len );
if (n <= 0) {
socket_perror( "read", sock, n );
close( sock->fd );
@@ -249,7 +342,13 @@ socket_read( Socket_t *sock, char *buf, int len )
static int
socket_write( Socket_t *sock, const char *buf, int len )
{
- int n = write_in_full( sock->fd, buf, len );
+ int n;
+#ifndef NO_OPENSSL
+ if (sock->ssl)
+ n = SSL_write(sock->ssl, buf, len);
+ else
+#endif
+ n = write_in_full( sock->fd, buf, len );
if (n != len) {
socket_perror( "write", sock, n );
close( sock->fd );
@@ -258,6 +357,17 @@ socket_write( Socket_t *sock, const char *buf, int len )
return n;
}
+static void socket_shutdown(Socket_t *sock)
+{
+#ifndef NO_OPENSSL
+ if (sock->ssl) {
+ SSL_shutdown(sock->ssl);
+ SSL_free(sock->ssl);
+ }
+#endif
+ close(sock->fd);
+}
+
/* simple line buffering */
static int
buffer_gets( buffer_t * b, char **s )
@@ -875,7 +985,7 @@ imap_close_server( imap_store_t *ictx )
if (imap->buf.sock.fd != -1) {
imap_exec( ictx, NULL, "LOGOUT" );
- close( imap->buf.sock.fd );
+ socket_shutdown( &imap->buf.sock );
}
free_list( imap->ns_personal );
free_list( imap->ns_other );
@@ -906,6 +1016,7 @@ imap_open_store( imap_server_conf_t *srvc )
ctx->imap = imap = xcalloc( sizeof(*imap), 1 );
imap->buf.sock.fd = -1;
+ imap->buf.sock.ssl = NULL;
imap->in_progress_append = &imap->in_progress;
/* open connection to IMAP server */
@@ -958,10 +1069,15 @@ imap_open_store( imap_server_conf_t *srvc )
perror( "connect" );
goto bail;
}
- imap_info( "ok\n" );
-
+
imap->buf.sock.fd = s;
+ if (srvc->use_ssl &&
+ ssl_socket_connect(&imap->buf.sock, 0, srvc->ssl_verify)) {
+ close(s);
+ goto bail;
+ }
+ imap_info( "ok\n" );
}
/* read the greeting string */
@@ -986,7 +1102,18 @@ imap_open_store( imap_server_conf_t *srvc )
goto bail;
if (!preauth) {
-
+#ifndef NO_OPENSSL
+ if (!srvc->use_ssl && CAP(STARTTLS)) {
+ if (imap_exec(ctx, 0, "STARTTLS") != RESP_OK)
+ goto bail;
+ if (ssl_socket_connect(&imap->buf.sock, 1,
+ srvc->ssl_verify))
+ goto bail;
+ /* capabilities may have changed, so get the new capabilities */
+ if (imap_exec(ctx, 0, "CAPABILITY") != RESP_OK)
+ goto bail;
+ }
+#endif
imap_info ("Logging in...\n");
if (!srvc->user) {
fprintf( stderr, "Skipping server %s, no user\n", srvc->host );
@@ -1014,7 +1141,9 @@ imap_open_store( imap_server_conf_t *srvc )
fprintf( stderr, "Skipping account %s@%s, server forbids LOGIN\n", srvc->user, srvc->host );
goto bail;
}
- imap_warn( "*** IMAP Warning *** Password is being sent in the clear\n" );
+ if (!imap->buf.sock.ssl)
+ imap_warn( "*** IMAP Warning *** Password is being "
+ "sent in the clear\n" );
if (imap_exec( ctx, NULL, "LOGIN \"%s\" \"%s\"", srvc->user, srvc->pass ) != RESP_OK) {
fprintf( stderr, "IMAP error: LOGIN failed\n" );
goto bail;
@@ -1242,6 +1371,8 @@ static imap_server_conf_t server =
0, /* port */
NULL, /* user */
NULL, /* pass */
+ 0, /* use_ssl */
+ 1, /* ssl_verify */
};
static char *imap_folder;
@@ -1262,11 +1393,11 @@ git_imap_config(const char *key, const char *val, void *cb)
if (!strcmp( "folder", key )) {
imap_folder = xstrdup( val );
} else if (!strcmp( "host", key )) {
- {
- if (!prefixcmp(val, "imap:"))
- val += 5;
- if (!server.port)
- server.port = 143;
+ if (!prefixcmp(val, "imap:"))
+ val += 5;
+ else if (!prefixcmp(val, "imaps:")) {
+ val += 6;
+ server.use_ssl = 1;
}
if (!prefixcmp(val, "//"))
val += 2;
@@ -1280,6 +1411,8 @@ git_imap_config(const char *key, const char *val, void *cb)
server.port = git_config_int( key, val );
else if (!strcmp( "tunnel", key ))
server.tunnel = xstrdup( val );
+ else if (!strcmp( "ssl_verify", key ))
+ server.ssl_verify = git_config_bool( key, val );
return 0;
}
@@ -1300,6 +1433,9 @@ main(int argc, char **argv)
setup_git_directory_gently(&nongit_ok);
git_config(git_imap_config, NULL);
+ if (!server.port)
+ server.port = server.use_ssl ? 993 : 143;
+
if (!imap_folder) {
fprintf( stderr, "no imap store specified\n" );
return 1;
--
1.5.6.2.224.g26efb.dirty
^ permalink raw reply related
* [PATCH 1/4] git-imap-send: Allow the program to be run from subdirectories of a git tree.
From: Robert Shearman @ 2008-07-09 21:28 UTC (permalink / raw)
To: git; +Cc: Robert Shearman
Call setup_git_directory_gently to allow git-imap-send to be used from subdirectories of a git tree.
Signed-off-by: Robert Shearman <robertshearman@gmail.com>
---
imap-send.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/imap-send.c b/imap-send.c
index 1ec1310..24d76a7 100644
--- a/imap-send.c
+++ b/imap-send.c
@@ -1292,10 +1292,12 @@ main(int argc, char **argv)
int ofs = 0;
int r;
int total, n = 0;
+ int nongit_ok;
/* init the random number generator */
arc4_init();
+ setup_git_directory_gently(&nongit_ok);
git_config(git_imap_config, NULL);
if (!imap_folder) {
--
1.5.6.2.224.g26efb.dirty
^ permalink raw reply related
* Re: [PATCH 2/4] git-imap-send: Add support for SSL.
From: Rob Shearman @ 2008-07-09 21:24 UTC (permalink / raw)
To: Josh Triplett; +Cc: git
In-Reply-To: <1215616484.3053.6.camel@josh-work.beaverton.ibm.com>
2008/7/9 Josh Triplett <josht@linux.vnet.ibm.com>:
> On Tue, 2008-07-08 at 23:18 +0100, Robert Shearman wrote:
>> --- a/Documentation/git-imap-send.txt
>> +++ b/Documentation/git-imap-send.txt
>> @@ -37,10 +37,11 @@ configuration file (shown with examples):
>> Tunnel = "ssh -q user@server.com /usr/bin/imapd ./Maildir 2> /dev/null"
>>
>> [imap]
>> - Host = imap.server.com
>> + Host = imaps://imap.example.com
>> User = bob
>> Pass = pwd
>> - Port = 143
>> + Port = 993
>> + sslverify = false
> [...]
>> @@ -1280,6 +1411,8 @@ git_imap_config(const char *key, const char *val, void *cb)
>> server.port = git_config_int( key, val );
>> else if (!strcmp( "tunnel", key ))
>> server.tunnel = xstrdup( val );
>> + else if (!strcmp( "ssl_verify", key ))
>> + server.ssl_verify = git_config_bool( key, val );
>
> The example and the code disagree on the name of the
> sslverify/ssl_verify option.
I wouldn't exactly call it "disagree". The config variable is limited
by not allowing underscores, whereas the C language does allow them.
> Also, ssl_verify needs explanation.
See patch 4/4.
--
Rob Shearman
^ permalink raw reply
* Merging "merge-in-c" to next.
From: Junio C Hamano @ 2008-07-09 21:20 UTC (permalink / raw)
To: git; +Cc: Miklos Vajna, Johannes Schindelin
I am preparing to merge the 'merge-in-c' topic from Miklos to 'next'. The
topic introduces builtin-merge.c to rewrite git-merge.sh script in C.
One interesting aspect of this merge is that 'next' has an enhanced
git-merge that can pass extra options that git-merge itself does not have
to understand to the strategy backends, when the user gives -X<option> to
it. This is analogous to how gcc uses -Wl,* option to pass options to the
linker. This new feature comes from a separate merge-theirs topic
developed independently. Naturally, merge-in-c does not know about it.
The approach I am taking with this integration is to first fork a new
branch (a mini-integration branch) 'xx/merge-in-c-into-next' from
'mv/merge-in-c', and then:
- Merge 'ph/parseopt-step-blame' topic to it;
- Convert the use of parse_options() in 'git-merge' to use "incremental
parsing" that is introduced by the 'ph/parseopt-step-blame' topic;
- Merge 'jc/merge-theirs' topic, marking "git merge -Xtheirs" feature is
temporarily broken in the test suite;
- Add support for -X<option>;
- And finally merge the whole thing to 'next'.
The idea is that:
* This would hopefully not break 'next', obviously;
* If either one of merge-theirs or merge-in-c (but not both) matures
early and needs to graduate to master, it can do so; this fact is
indepent from today's merge;
* After one of these interacting topics graduates to 'master', merging
the other one to 'master' will need to resolve the same semantic
conflict as I am resolving today. Merging this mini-integration topic
to 'master' instead of mergint the other one would be straightforward
and much less error prone.
This approach takes the aggregation hostage to ph/parseopt-step-blame; in
order to merge both merge-in-c and merge-theirs to master, we must merge
the incremental option parser to master as well. But I think that is not
a problem -- the parseopt change in question is something we would want to
have in 'master' fairly soon.
The commit log messages for merge commits in this series are actually
interesting. Output of "git log --reverse --stat --first-parent" is
attached at the end.
commit 1c7b76be7d620bbaf2e6b8417f04012326bbb9df
Author: Miklos Vajna <vmiklos@frugalware.org>
Date: Mon Jul 7 19:24:20 2008 +0200
Build in merge
Mentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Makefile | 2 +-
builtin-merge.c | 1153 +++++++++++++++++++++++++++++++++++++++++
builtin.h | 1 +
contrib/examples/git-merge.sh | 554 ++++++++++++++++++++
git-merge.sh | 554 --------------------
git.c | 1 +
t/t7602-merge-octopus-many.sh | 2 +-
7 files changed, 1711 insertions(+), 556 deletions(-)
commit ff0d8a01410d1d2363dec660fc87b99905691d57
Merge: 1c7b76b... 3f8d520...
Author: Junio C Hamano <gitster@pobox.com>
Date: Wed Jul 9 11:11:48 2008 -0700
Merge branch 'ph/parseopt-step-blame' into xx/merge-in-c-into-next
The purpose of this branch is to resolve interactions with the merge-in-c
and the merge-theirs topics before merging the former into 'next'. Use of
parse_options_step() would be a good way to support -X<option> where
git-merge needs to passes it through to the strategy modules without
having to understand what <option> is.
This will be needed when merge-in-c is merged to 'next', which already has
the merge-theirs topic. We do not merge this mini-integration branch to
'master' if we later decide to drop merge-theirs, or merge merge-in-c
first to 'master', If we are to merge both to 'master', then merging this
branch would suffice.
commit ffa6e85e1cfca7ce3f41f5bfd420b94a26aa57bf
Author: Junio C Hamano <gitster@pobox.com>
Date: Wed Jul 9 12:58:22 2008 -0700
builtin-merge.c: use parse_options_step() "incremental parsing" machinery
This prepares the option parser for "git-merge" to use the incremental
parsing machinery, so that we can add support for -X<options> passthru
that is hard to parse with the stop parse_options() machinery.
This is just a conversion; it does not add any new options nor features
yet.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-merge.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 40 insertions(+), 5 deletions(-)
commit fd6fd913327812ecce7d638846b88908b350b904
Merge: ffa6e85... 7eda236...
Author: Junio C Hamano <gitster@pobox.com>
Date: Wed Jul 9 13:00:24 2008 -0700
Merge branch 'jc/merge-theirs' into xx/merge-in-c-into-next
This is an evil merge that tentatively marks that the "git merge -Xtheirs"
is broken in the testsuite, because "git merge" reimplementation in C does
not know about it yet.
* jc/merge-theirs:
Make "subtree" part more orthogonal to the rest of merge-recursive.
Teach git-pull to pass -X<option> to git-merge
Teach git-merge to pass -X<option> to the backend strategy module
git-merge-recursive-{ours,theirs}
git-merge-file --ours, --theirs
commit aa85524eacdfa9fa84727dd700265f3a70b8fd01
Author: Junio C Hamano <gitster@pobox.com>
Date: Wed Jul 9 13:51:46 2008 -0700
Teach git-merge -X<option> again.
This fixes the tentative regression of git-merge rewritten in C by
teaching it to pass -X<option> to the strategy backends.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-merge.c | 55 ++++++++++++++++++++++++++++++-----------
t/t6034-merge-ours-theirs.sh | 4 +-
2 files changed, 42 insertions(+), 17 deletions(-)
^ permalink raw reply
* Re: Bug: /usr/local/bin/git-daemon starts /usr/sbin/git-upload-pack?
From: Junio C Hamano @ 2008-07-09 21:14 UTC (permalink / raw)
To: Jan Wielemaker; +Cc: Git Mailing List
In-Reply-To: <200807092220.10655.J.Wielemaker@uva.nl>
Jan Wielemaker <J.Wielemaker@uva.nl> writes:
> After upgrade to SuSE 11.0 I was forced to update GIT (changed libcurl).
> I did (with some trickery) a pull of the latest git and built it using
> make prefix=/usr/local ..., to find out that /usr/local/bin/git-daemon
> starts /usr/sbin/git-upload-pack.
>
> After creating a symlink to /usr/local/bin/git-upload-pack all works fine
> again, but I guess this is a mistake?
I think this is a distro issue.
Pre-1.6.0 git installs git-everything in $(bindir) and knows things are
there. Current 'master' we are preparing for 1.6.0 instead installs
git-mostofthem in $(prefix)/libexec/git-core and git-someofthem in
$(bindir); our executables know which binaries are installed in $(bindir)
and which ones are installed in $(prefix)/libexec/git-core.
The point is we never install $anywhere/sbin unless the person who is
building explicitly does so (either by futzing the Makefile or giving
bindir=$somewhere from the command line of "make"). The reason your
/usr/local/bin/git-daemon (we do not know who compiled it and how) spawns
something in /usr/sbin is not our doing. Find out who configured it and
why, and more importantly, what _other_ changes are made in the build and
installation procedure to support that change in location.
^ permalink raw reply
* Re: Merging a foreign tree into a bare repository.
From: Eric Raible @ 2008-07-09 21:04 UTC (permalink / raw)
To: git
In-Reply-To: <alpine.DEB.1.00.0807092040360.4010@eeepc-johanness>
Johannes Schindelin <Johannes.Schindelin <at> gmx.de> writes:
>
> Hi,
>
> On Wed, 9 Jul 2008, Jakub Narebski wrote:
> >
> > Or, alternatively, you can tell git where you want to have working
> > directory with '--work-tree' parameter to git wrapper,
>
> ... which runs the risk of you forgetting to specify the same working
> directory all the time.
>
> Which is the reason I did not suggest it.
How about:
GIT_WORK_TREE=<some-dir>; export GIT_WORK_TREE
Combined with a PS1 which include an indication that GIT_WORK_TREE is set?
- Eric
^ permalink raw reply
* [PATCH] git-blame: fix lapsus
From: Pierre Habouzit @ 2008-07-09 20:47 UTC (permalink / raw)
To: git; +Cc: gitster, Pierre Habouzit
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
builtin-blame.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/builtin-blame.c b/builtin-blame.c
index 99f5140..73d26c6 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -25,7 +25,7 @@ static char blame_usage[] = "git-blame [options] [rev-opts] [rev] [--] file";
static const char *blame_opt_usage[] = {
blame_usage,
"",
- "[rev-opts] are documented in git-rev-parse(1)",
+ "[rev-opts] are documented in git-rev-list(1)",
NULL
};
--
1.5.6.2.397.gf2a8c
^ permalink raw reply related
* [PATCH] Provide fallback definitions of PRIu32 and PRIx32
From: Johannes Sixt @ 2008-07-09 20:38 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
Since 6e1c23442 we make use of these C99 constructs, but this commit did
not provide fallbacks for non-C99 systems.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
git-compat-util.h | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/git-compat-util.h b/git-compat-util.h
index 545df59..8c7e114 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -110,6 +110,14 @@
#define PRIuMAX "llu"
#endif
+#ifndef PRIu32
+#define PRIu32 "u"
+#endif
+
+#ifndef PRIx32
+#define PRIx32 "x"
+#endif
+
#ifndef PATH_SEP
#define PATH_SEP ':'
#endif
--
1.5.6.1.216.g8c89b
^ permalink raw reply related
* Re: git over rsync+ssh
From: Stephen Sinclair @ 2008-07-09 20:33 UTC (permalink / raw)
To: Michael J Gruber; +Cc: git
In-Reply-To: <g52gbg$si9$1@ger.gmane.org>
On Wed, Jul 9, 2008 at 10:01 AM, Michael J Gruber
<michaeljgruber+gmane@fastmail.fm> wrote:
> I want to put a git repo on a server where I have ssh access but failed to
> compile git (AIX 5.1, has libz.a but no .so nor headers; compiling
> prerequisite zlib failed, probably due to a botched build environment).
>
> As far as I can see my only option for a private repo is using rsync over
> ssh.
Have you tried sshfs?
It allows you to mount an ssh-accessible file system onto your local
file system.
This might make it possible to use your local git to access the remote account.
Not sure of the implications for data integrity...
Steve
^ permalink raw reply
* Bug: /usr/local/bin/git-daemon starts /usr/sbin/git-upload-pack?
From: Jan Wielemaker @ 2008-07-09 20:20 UTC (permalink / raw)
To: Git Mailing List
Hi,
After upgrade to SuSE 11.0 I was forced to update GIT (changed libcurl).
I did (with some trickery) a pull of the latest git and built it using
make prefix=/usr/local ..., to find out that /usr/local/bin/git-daemon
starts /usr/sbin/git-upload-pack.
After creating a symlink to /usr/local/bin/git-upload-pack all works fine
again, but I guess this is a mistake?
Cheers --- Jan
P.s. This is quite nasty to debug. I was forced to to run git-daemon
stand-alone (not xinetd) another port and run strace -f -p <pid>
to discover the cause of this problem. Even with --verbose, the
only error response was the client complaining on unexpected EOF.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox