]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/reply-password.c
relicense to LGPLv2.1 (with exceptions)
[thirdparty/systemd.git] / src / reply-password.c
CommitLineData
490aed58
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
490aed58
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
490aed58 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
490aed58
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <sys/socket.h>
23#include <sys/poll.h>
24#include <sys/types.h>
25#include <assert.h>
26#include <string.h>
27#include <errno.h>
28#include <unistd.h>
29#include <fcntl.h>
30#include <sys/un.h>
31#include <sys/stat.h>
32#include <sys/signalfd.h>
33#include <getopt.h>
0e098b15 34#include <stddef.h>
490aed58
LP
35
36#include "log.h"
37#include "macro.h"
38#include "util.h"
39
40static int send_on_socket(int fd, const char *socket_name, const void *packet, size_t size) {
41 union {
42 struct sockaddr sa;
43 struct sockaddr_un un;
44 } sa;
45
46 assert(fd >= 0);
47 assert(socket_name);
48 assert(packet);
49
50 zero(sa);
51 sa.un.sun_family = AF_UNIX;
ec863ba6 52 strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
490aed58 53
ec863ba6 54 if (sendto(fd, packet, size, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
490aed58
LP
55 log_error("Failed to send: %m");
56 return -1;
57 }
58
59 return 0;
60}
61
62int main(int argc, char *argv[]) {
63 int fd = -1, r = EXIT_FAILURE;
64 char packet[LINE_MAX];
65 size_t length;
66
4cfa2c99 67 log_set_target(LOG_TARGET_AUTO);
490aed58
LP
68 log_parse_environment();
69 log_open();
70
71 if (argc != 3) {
72 log_error("Wrong number of arguments.");
73 goto finish;
74 }
75
76 if (streq(argv[1], "1")) {
77
78 packet[0] = '+';
79 if (!fgets(packet+1, sizeof(packet)-1, stdin)) {
80 log_error("Failed to read password: %m");
81 goto finish;
82 }
83
84 truncate_nl(packet+1);
d55f4f3f 85 length = 1 + strlen(packet+1) + 1;
490aed58
LP
86 } else if (streq(argv[1], "0")) {
87 packet[0] = '-';
88 length = 1;
89 } else {
90 log_error("Invalid first argument %s", argv[1]);
91 goto finish;
92 }
93
94 if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
95 log_error("socket() failed: %m");
96 goto finish;
97 }
98
99 if (send_on_socket(fd, argv[2], packet, length) < 0)
100 goto finish;
101
102 r = EXIT_SUCCESS;
103
104finish:
105 if (fd >= 0)
106 close_nointr_nofail(fd);
107
108 return r;
109}