2 #include "credential.h"
3 #include "string-list.h"
4 #include "parse-options.h"
5 #include "unix-socket.h"
6 #include "run-command.h"
11 static int send_request(const char *socket
, const struct strbuf
*out
)
14 int fd
= unix_stream_connect(socket
);
19 if (write_in_full(fd
, out
->buf
, out
->len
) < 0)
20 die_errno("unable to write to cache daemon");
21 shutdown(fd
, SHUT_WR
);
27 r
= read_in_full(fd
, in
, sizeof(in
));
31 die_errno("read error from cache daemon");
32 write_or_die(1, in
, r
);
39 static void spawn_daemon(const char *socket
)
41 struct child_process daemon
= CHILD_PROCESS_INIT
;
42 const char *argv
[] = { NULL
, NULL
, NULL
};
46 argv
[0] = "git-credential-cache--daemon";
52 if (start_command(&daemon
))
53 die_errno("unable to start cache daemon");
54 r
= read_in_full(daemon
.out
, buf
, sizeof(buf
));
56 die_errno("unable to read result code from cache daemon");
57 if (r
!= 3 || memcmp(buf
, "ok\n", 3))
58 die("cache daemon did not start: %.*s", r
, buf
);
62 static void do_cache(const char *socket
, const char *action
, int timeout
,
65 struct strbuf buf
= STRBUF_INIT
;
67 strbuf_addf(&buf
, "action=%s\n", action
);
68 strbuf_addf(&buf
, "timeout=%d\n", timeout
);
69 if (flags
& FLAG_RELAY
) {
70 if (strbuf_read(&buf
, 0, 0) < 0)
71 die_errno("unable to relay credential");
74 if (send_request(socket
, &buf
) < 0) {
75 if (errno
!= ENOENT
&& errno
!= ECONNREFUSED
)
76 die_errno("unable to connect to cache daemon");
77 if (flags
& FLAG_SPAWN
) {
79 if (send_request(socket
, &buf
) < 0)
80 die_errno("unable to connect to cache daemon");
86 static char *get_socket_path(void)
89 char *old_dir
, *socket
;
90 old_dir
= expand_user_path("~/.git-credential-cache", 0);
91 if (old_dir
&& !stat(old_dir
, &sb
) && S_ISDIR(sb
.st_mode
))
92 socket
= xstrfmt("%s/socket", old_dir
);
94 socket
= xdg_cache_home("credential/socket");
99 int cmd_main(int argc
, const char **argv
)
101 char *socket_path
= NULL
;
104 const char * const usage
[] = {
105 "git credential-cache [<options>] <action>",
108 struct option options
[] = {
109 OPT_INTEGER(0, "timeout", &timeout
,
110 "number of seconds to cache credentials"),
111 OPT_STRING(0, "socket", &socket_path
, "path",
112 "path of cache-daemon socket"),
116 argc
= parse_options(argc
, argv
, NULL
, options
, usage
, 0);
118 usage_with_options(usage
, options
);
122 socket_path
= get_socket_path();
124 die("unable to find a suitable socket path; use --socket");
126 if (!strcmp(op
, "exit"))
127 do_cache(socket_path
, op
, timeout
, 0);
128 else if (!strcmp(op
, "get") || !strcmp(op
, "erase"))
129 do_cache(socket_path
, op
, timeout
, FLAG_RELAY
);
130 else if (!strcmp(op
, "store"))
131 do_cache(socket_path
, op
, timeout
, FLAG_RELAY
|FLAG_SPAWN
);
133 ; /* ignore unknown operation */