/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release
237.2.207 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
1
/*  -*- coding: utf-8 -*- */
2
/*
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
3
 * Plymouth - Read a password from Plymouth and output it
237.2.207 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
4
 * 
237.7.447 by Teddy Hogeborn
Update copyright year to 2017
5
 * Copyright © 2010-2017 Teddy Hogeborn
6
 * Copyright © 2010-2017 Björn Påhlsson
237.2.207 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
7
 * 
237.7.455 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
8
 * This file is part of Mandos.
9
 * 
10
 * Mandos is free software: you can redistribute it and/or modify it
11
 * under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 * 
15
 * Mandos is distributed in the hope that it will be useful, but
237.2.207 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * General Public License for more details.
19
 * 
20
 * You should have received a copy of the GNU General Public License
237.7.455 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
21
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
237.2.207 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
22
 * 
237.11.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
23
 * Contact the authors at <mandos@recompile.se>.
237.2.207 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
24
 */
25
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
26
#define _GNU_SOURCE		/* asprintf(), TEMP_FAILURE_RETRY() */
27
#include <signal.h>		/* sig_atomic_t, struct sigaction,
28
				   sigemptyset(), sigaddset(), SIGINT,
29
				   SIGHUP, SIGTERM, sigaction(),
30
				   kill(), SIG_IGN */
31
#include <stdbool.h>		/* bool, false, true */
32
#include <fcntl.h>		/* open(), O_RDONLY */
33
#include <iso646.h>		/* and, or, not*/
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
34
#include <sys/types.h>		/* size_t, ssize_t, pid_t, struct
35
				   dirent, waitpid() */
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
36
#include <sys/wait.h>		/* waitpid() */
37
#include <stddef.h>		/* NULL */
38
#include <string.h>		/* strchr(), memcmp() */
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
39
#include <stdio.h>		/* asprintf(), perror(), fopen(),
237.7.33 by Teddy Hogeborn
Merge from Björn.
40
				   fscanf(), vasprintf(), fprintf(),
41
				   vfprintf() */
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
42
#include <unistd.h>		/* close(), readlink(), read(),
43
				   fork(), setsid(), chdir(), dup2(),
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
44
				   STDERR_FILENO, execv(), access() */
45
#include <stdlib.h>		/* free(), EXIT_FAILURE, realloc(),
46
				   EXIT_SUCCESS, malloc(), _exit(),
47
				   getenv() */
48
#include <dirent.h>		/* scandir(), alphasort() */
49
#include <inttypes.h>		/* intmax_t, strtoumax(), SCNuMAX */
50
#include <sys/stat.h>		/* struct stat, lstat() */
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
51
#include <sysexits.h>		/* EX_OSERR, EX_UNAVAILABLE */
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
52
#include <error.h>		/* error() */
53
#include <errno.h>		/* TEMP_FAILURE_RETRY */
237.2.194 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
54
#include <argz.h>		/* argz_count(), argz_extract() */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
55
#include <stdarg.h>		/* va_list, va_start(), ... */
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
56
57
sig_atomic_t interrupted_by_signal = 0;
237.7.52 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
58
59
/* Used by Ubuntu 11.04 (Natty Narwahl) */
60
const char plymouth_old_pid[] = "/dev/.initramfs/plymouth.pid";
61
/* Used by Ubuntu 11.10 (Oneiric Ocelot) */
62
const char plymouth_pid[] = "/run/initramfs/plymouth.pid";
63
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
64
const char plymouth_path[] = "/bin/plymouth";
65
const char plymouthd_path[] = "/sbin/plymouthd";
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
66
const char *plymouthd_default_argv[] = {"/sbin/plymouthd",
67
					"--mode=boot",
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
68
					"--attach-to-session",
69
					NULL };
70
71
static void termination_handler(__attribute__((unused))int signum){
72
  if(interrupted_by_signal){
73
    return;
74
  }
75
  interrupted_by_signal = 1;
76
}
77
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
78
/* Function to use when printing errors */
237.7.81 by teddy at bsnet
* plugins.d/splashy.c (error_plus): Check format string.
79
__attribute__((format (gnu_printf, 3, 4)))
237.7.33 by Teddy Hogeborn
Merge from Björn.
80
void error_plus(int status, int errnum, const char *formatstring,
81
		...){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
82
  va_list ap;
83
  char *text;
84
  int ret;
85
  
86
  va_start(ap, formatstring);
87
  ret = vasprintf(&text, formatstring, ap);
237.7.218 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
88
  if(ret == -1){
237.7.33 by Teddy Hogeborn
Merge from Björn.
89
    fprintf(stderr, "Mandos plugin %s: ",
90
	    program_invocation_short_name);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
91
    vfprintf(stderr, formatstring, ap);
92
    fprintf(stderr, ": ");
93
    fprintf(stderr, "%s\n", strerror(errnum));
94
    error(status, errno, "vasprintf while printing error");
95
    return;
96
  }
97
  fprintf(stderr, "Mandos plugin ");
98
  error(status, errnum, "%s", text);
99
  free(text);
100
}
101
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
102
/* Create prompt string */
103
char *makeprompt(void){
104
  int ret = 0;
105
  char *prompt;
106
  const char *const cryptsource = getenv("cryptsource");
107
  const char *const crypttarget = getenv("crypttarget");
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
108
  const char prompt_start[] = "Unlocking the disk";
109
  const char prompt_end[] = "Enter passphrase";
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
110
  
111
  if(cryptsource == NULL){
112
    if(crypttarget == NULL){
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
113
      ret = asprintf(&prompt, "%s\n%s", prompt_start, prompt_end);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
114
    } else {
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
115
      ret = asprintf(&prompt, "%s (%s)\n%s", prompt_start,
116
		     crypttarget, prompt_end);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
117
    }
118
  } else {
119
    if(crypttarget == NULL){
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
120
      ret = asprintf(&prompt, "%s %s\n%s", prompt_start, cryptsource,
121
		     prompt_end);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
122
    } else {
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
123
      ret = asprintf(&prompt, "%s %s (%s)\n%s", prompt_start,
124
		     cryptsource, crypttarget, prompt_end);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
125
    }
126
  }
127
  if(ret == -1){
128
    return NULL;
129
  }
130
  return prompt;
131
}
132
133
void kill_and_wait(pid_t pid){
134
  TEMP_FAILURE_RETRY(kill(pid, SIGTERM));
135
  TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0));
136
}
137
138
bool become_a_daemon(void){
139
  int ret = setuid(geteuid());
140
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
141
    error_plus(0, errno, "setuid");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
142
  }
143
    
144
  setsid();
145
  ret = chdir("/");
146
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
147
    error_plus(0, errno, "chdir");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
148
    return false;
149
  }
150
  ret = dup2(STDERR_FILENO, STDOUT_FILENO); /* replace our stdout */
151
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
152
    error_plus(0, errno, "dup2");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
153
    return false;
154
  }
155
  return true;
156
}
157
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
158
__attribute__((nonnull (2, 3)))
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
159
bool exec_and_wait(pid_t *pid_return, const char *path,
237.7.168 by Teddy Hogeborn
* plugin-runner.c (main): Bug fix; do not ignore return value of
160
		   const char * const *argv, bool interruptable,
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
161
		   bool daemonize){
162
  int status;
163
  int ret;
164
  pid_t pid;
165
  pid = fork();
166
  if(pid == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
167
    error_plus(0, errno, "fork");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
168
    return false;
169
  }
170
  if(pid == 0){
171
    /* Child */
172
    if(daemonize){
173
      if(not become_a_daemon()){
174
	_exit(EX_OSERR);
175
      }
176
    }
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
177
    
237.7.381 by Teddy Hogeborn
Client: Fix plymouth agent; broken since 1.7.2.
178
    char **new_argv = malloc(sizeof(const char *));
179
    if(new_argv == NULL){
180
      error_plus(0, errno, "malloc");
181
      _exit(EX_OSERR);
182
    }
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
183
    char **tmp;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
184
    int i = 0;
237.7.438 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
185
    for (; argv[i] != NULL; i++){
237.7.381 by Teddy Hogeborn
Client: Fix plymouth agent; broken since 1.7.2.
186
      tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 2));
237.7.218 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
187
      if(tmp == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
188
	error_plus(0, errno, "realloc");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
189
	free(new_argv);
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
190
	_exit(EX_OSERR);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
191
      }
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
192
      new_argv = tmp;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
193
      new_argv[i] = strdup(argv[i]);
194
    }
237.7.10 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
195
    new_argv[i] = NULL;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
196
    
197
    execv(path, (char *const *)new_argv);
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
198
    error_plus(0, errno, "execv");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
199
    _exit(EXIT_FAILURE);
200
  }
201
  if(pid_return != NULL){
202
    *pid_return = pid;
203
  }
204
  do {
205
    ret = waitpid(pid, &status, 0);
206
  } while(ret == -1 and errno == EINTR
207
	  and ((not interrupted_by_signal)
208
	       or (not interruptable)));
209
  if(interrupted_by_signal and interruptable){
210
    return false;
211
  }
212
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
213
    error_plus(0, errno, "waitpid");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
214
    return false;
215
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
216
  if(WIFEXITED(status) and (WEXITSTATUS(status) == 0)){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
217
    return true;
218
  }
219
  return false;
220
}
221
237.7.82 by teddy at bsnet
* plugin-runner.c (add_to_char_array): Added "nonnull" attribute.
222
__attribute__((nonnull))
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
223
int is_plymouth(const struct dirent *proc_entry){
224
  int ret;
225
  {
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
226
    uintmax_t proc_id;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
227
    char *tmp;
228
    errno = 0;
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
229
    proc_id = strtoumax(proc_entry->d_name, &tmp, 10);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
230
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
231
    if(errno != 0 or *tmp != '\0'
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
232
       or proc_id != (uintmax_t)((pid_t)proc_id)){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
233
      return 0;
234
    }
235
  }
275.1.1 by Björn Påhlsson
password-prompt: added conflic handling with plymouth daemon.
236
  char exe_target[sizeof(plymouthd_path)];
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
237
  char *exe_link;
238
  ret = asprintf(&exe_link, "/proc/%s/exe", proc_entry->d_name);
239
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
240
    error_plus(0, errno, "asprintf");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
241
    return 0;
242
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
243
  
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
244
  struct stat exe_stat;
245
  ret = lstat(exe_link, &exe_stat);
246
  if(ret == -1){
247
    free(exe_link);
248
    if(errno != ENOENT){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
249
      error_plus(0, errno, "lstat");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
250
    }
251
    return 0;
252
  }
253
  
254
  if(not S_ISLNK(exe_stat.st_mode)
255
     or exe_stat.st_uid != 0
256
     or exe_stat.st_gid != 0){
257
    free(exe_link);
258
    return 0;
259
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
260
  
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
261
  ssize_t sret = readlink(exe_link, exe_target, sizeof(exe_target));
262
  free(exe_link);
275.1.1 by Björn Påhlsson
password-prompt: added conflic handling with plymouth daemon.
263
  if((sret != (ssize_t)sizeof(plymouthd_path)-1) or
264
      (memcmp(plymouthd_path, exe_target,
265
	      sizeof(plymouthd_path)-1) != 0)){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
266
    return 0;
267
  }
268
  return 1;
269
}
270
271
pid_t get_pid(void){
272
  int ret;
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
273
  uintmax_t proc_id = 0;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
274
  FILE *pidfile = fopen(plymouth_pid, "r");
237.7.52 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
275
  /* Try the new pid file location */
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
276
  if(pidfile != NULL){
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
277
    ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
278
    if(ret != 1){
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
279
      proc_id = 0;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
280
    }
281
    fclose(pidfile);
282
  }
237.7.52 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
283
  /* Try the old pid file location */
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
284
  if(proc_id == 0){
237.7.52 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
285
    pidfile = fopen(plymouth_pid, "r");
286
    if(pidfile != NULL){
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
287
      ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
237.7.52 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
288
      if(ret != 1){
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
289
	proc_id = 0;
237.7.52 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
290
      }
291
      fclose(pidfile);
292
    }
293
  }
294
  /* Look for a plymouth process */
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
295
  if(proc_id == 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
296
    struct dirent **direntries = NULL;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
297
    ret = scandir("/proc", &direntries, is_plymouth, alphasort);
237.7.218 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
298
    if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
299
      error_plus(0, errno, "scandir");
275.1.1 by Björn Påhlsson
password-prompt: added conflic handling with plymouth daemon.
300
    }
237.7.218 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
301
    if(ret > 0){
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
302
      ret = sscanf(direntries[0]->d_name, "%" SCNuMAX, &proc_id);
237.7.218 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
303
      if(ret < 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
304
	error_plus(0, errno, "sscanf");
275.1.1 by Björn Påhlsson
password-prompt: added conflic handling with plymouth daemon.
305
      }
306
    }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
307
    /* scandir might preallocate for this variable (man page unclear).
237.7.33 by Teddy Hogeborn
Merge from Björn.
308
       even if ret == 0, therefore we need to free it. */
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
309
    free(direntries);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
310
  }
311
  pid_t pid;
237.7.84 by Björn Påhlsson
renamed some foomax values to what they actually represent
312
  pid = (pid_t)proc_id;
313
  if((uintmax_t)pid == proc_id){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
314
    return pid;
315
  }
316
  
317
  return 0;
318
}
319
237.7.460 by Teddy Hogeborn
Fix memory leak in plymouth plugin
320
char **getargv(pid_t pid){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
321
  int cl_fd;
322
  char *cmdline_filename;
323
  ssize_t sret;
324
  int ret;
325
  
326
  ret = asprintf(&cmdline_filename, "/proc/%" PRIuMAX "/cmdline",
327
		 (uintmax_t)pid);
328
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
329
    error_plus(0, errno, "asprintf");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
330
    return NULL;
331
  }
332
  
333
  /* Open /proc/<pid>/cmdline  */
334
  cl_fd = open(cmdline_filename, O_RDONLY);
335
  free(cmdline_filename);
336
  if(cl_fd == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
337
    error_plus(0, errno, "open");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
338
    return NULL;
339
  }
340
  
341
  size_t cmdline_allocated = 0;
342
  size_t cmdline_len = 0;
343
  char *cmdline = NULL;
344
  char *tmp;
345
  const size_t blocksize = 1024;
346
  do {
347
    /* Allocate more space? */
348
    if(cmdline_len + blocksize > cmdline_allocated){
349
      tmp = realloc(cmdline, cmdline_allocated + blocksize);
350
      if(tmp == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
351
	error_plus(0, errno, "realloc");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
352
	free(cmdline);
353
	close(cl_fd);
354
	return NULL;
355
      }
356
      cmdline = tmp;
357
      cmdline_allocated += blocksize;
358
    }
359
    
360
    /* Read data */
361
    sret = read(cl_fd, cmdline + cmdline_len,
362
		cmdline_allocated - cmdline_len);
363
    if(sret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
364
      error_plus(0, errno, "read");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
365
      free(cmdline);
366
      close(cl_fd);
367
      return NULL;
368
    }
369
    cmdline_len += (size_t)sret;
370
  } while(sret != 0);
371
  ret = close(cl_fd);
372
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
373
    error_plus(0, errno, "close");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
374
    free(cmdline);
375
    return NULL;
376
  }
377
  
378
  /* we got cmdline and cmdline_len, ignore rest... */
237.2.195 by teddy at bsnet
* plugins.d/usplash.c (main): BUG FIX: allocate space for the final
379
  char **argv = malloc((argz_count(cmdline, cmdline_len) + 1)
237.2.194 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
380
		       * sizeof(char *)); /* Get number of args */
381
  if(argv == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
382
    error_plus(0, errno, "argv = malloc()");
237.2.194 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
383
    free(cmdline);
384
    return NULL;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
385
  }
237.2.194 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
386
  argz_extract(cmdline, cmdline_len, argv); /* Create argv */
237.7.460 by Teddy Hogeborn
Fix memory leak in plymouth plugin
387
  return argv;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
388
}
389
390
int main(__attribute__((unused))int argc,
391
	 __attribute__((unused))char **argv){
392
  char *prompt;
393
  char *prompt_arg;
394
  pid_t plymouth_command_pid;
395
  int ret;
396
  bool bret;
397
398
  /* test -x /bin/plymouth */
399
  ret = access(plymouth_path, X_OK);
400
  if(ret == -1){
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
401
    /* Plymouth is probably not installed.  Don't print an error
402
       message, just exit. */
403
    exit(EX_UNAVAILABLE);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
404
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
405
  
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
406
  { /* Add signal handlers */
407
    struct sigaction old_action,
408
      new_action = { .sa_handler = termination_handler,
409
		     .sa_flags = 0 };
410
    sigemptyset(&new_action.sa_mask);
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
411
    for(int *sig = (int[]){ SIGINT, SIGHUP, SIGTERM, 0 };
412
	*sig != 0; sig++){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
413
      ret = sigaddset(&new_action.sa_mask, *sig);
414
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
415
	error_plus(EX_OSERR, errno, "sigaddset");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
416
      }
417
      ret = sigaction(*sig, NULL, &old_action);
418
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
419
	error_plus(EX_OSERR, errno, "sigaction");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
420
      }
421
      if(old_action.sa_handler != SIG_IGN){
422
	ret = sigaction(*sig, &new_action, NULL);
423
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
424
	  error_plus(EX_OSERR, errno, "sigaction");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
425
	}
426
      }
427
    }
428
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
429
  
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
430
  /* plymouth --ping */
431
  bret = exec_and_wait(&plymouth_command_pid, plymouth_path,
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
432
		       (const char *[])
433
		       { plymouth_path, "--ping", NULL },
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
434
		       true, false);
435
  if(not bret){
436
    if(interrupted_by_signal){
437
      kill_and_wait(plymouth_command_pid);
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
438
      exit(EXIT_FAILURE);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
439
    }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
440
    /* Plymouth is probably not running.  Don't print an error
441
       message, just exit. */
442
    exit(EX_UNAVAILABLE);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
443
  }
444
  
445
  prompt = makeprompt();
446
  ret = asprintf(&prompt_arg, "--prompt=%s", prompt);
447
  free(prompt);
448
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
449
    error_plus(EX_OSERR, errno, "asprintf");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
450
  }
451
  
452
  /* plymouth ask-for-password --prompt="$prompt" */
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
453
  bret = exec_and_wait(&plymouth_command_pid,
454
		       plymouth_path, (const char *[])
455
		       { plymouth_path, "ask-for-password",
456
			   prompt_arg, NULL },
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
457
		       true, false);
458
  free(prompt_arg);
459
  if(bret){
460
    exit(EXIT_SUCCESS);
461
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
462
  if(not interrupted_by_signal){
463
    /* exec_and_wait failed for some other reason */
464
    exit(EXIT_FAILURE);
465
  }
466
  kill_and_wait(plymouth_command_pid);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
467
  
237.7.460 by Teddy Hogeborn
Fix memory leak in plymouth plugin
468
  char **plymouthd_argv = NULL;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
469
  pid_t pid = get_pid();
470
  if(pid == 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
471
    error_plus(0, 0, "plymouthd pid not found");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
472
  } else {
473
    plymouthd_argv = getargv(pid);
474
  }
475
  
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
476
  bret = exec_and_wait(NULL, plymouth_path, (const char *[])
477
		       { plymouth_path, "quit", NULL },
478
		       false, false);
479
  if(not bret){
237.7.460 by Teddy Hogeborn
Fix memory leak in plymouth plugin
480
    if(plymouthd_argv != NULL){
481
      free(*plymouthd_argv);
482
      free(plymouthd_argv);
483
    }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
484
    exit(EXIT_FAILURE);
485
  }
237.7.460 by Teddy Hogeborn
Fix memory leak in plymouth plugin
486
  bret = exec_and_wait(NULL, plymouthd_path,
487
		       (plymouthd_argv != NULL)
488
		       ? (const char * const *)plymouthd_argv
489
		       : plymouthd_default_argv,
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
490
		       false, true);
237.7.460 by Teddy Hogeborn
Fix memory leak in plymouth plugin
491
  if(plymouthd_argv != NULL){
492
    free(*plymouthd_argv);
493
    free(plymouthd_argv);
494
  }
237.2.199 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
495
  if(not bret){
496
    exit(EXIT_FAILURE);
497
  }
498
  exec_and_wait(NULL, plymouth_path, (const char *[])
499
		{ plymouth_path, "show-splash", NULL },
500
		false, false);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
501
  exit(EXIT_FAILURE);
502
}