/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
444 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
1
/*  -*- coding: utf-8 -*- */
2
/*
462 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
3
 * Plymouth - Read a password from Plymouth and output it
444 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
4
 * 
899 by Teddy Hogeborn
Update copyright year to 2017
5
 * Copyright © 2010-2017 Teddy Hogeborn
6
 * Copyright © 2010-2017 Björn Påhlsson
444 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
7
 * 
907 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
444 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
907 by Teddy Hogeborn
Alter copyright notices slightly. Actual license is unchanged!
21
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
444 by Teddy Hogeborn
Update copyright year to "2010" wherever appropriate.
22
 * 
505.1.2 by Teddy Hogeborn
Change "fukt.bsnet.se" to "recompile.se" throughout.
23
 * Contact the authors at <mandos@recompile.se>.
444 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*/
436 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() */
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
39
#include <stdio.h>		/* asprintf(), perror(), fopen(),
485 by Teddy Hogeborn
Merge from Björn.
40
				   fscanf(), vasprintf(), fprintf(),
41
				   vfprintf() */
436 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() */
436 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 */
431 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;
504 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";
436 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 */
533 by teddy at bsnet
* plugins.d/splashy.c (error_plus): Check format string.
79
__attribute__((format (gnu_printf, 3, 4)))
485 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);
670 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
88
  if(ret == -1){
485 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");
462 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){
462 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 {
462 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){
462 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 {
462 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
534 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,
620 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
    }
462 by Teddy Hogeborn
* plugins.d/plymouth.c: Fixed comment to "Plymouth" instead of "Usplash".
177
    
833 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
    }
462 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;
890 by Teddy Hogeborn
Add spaces around all '=' signs in all C code.
185
    for (; argv[i] != NULL; i++){
833 by Teddy Hogeborn
Client: Fix plymouth agent; broken since 1.7.2.
186
      tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 2));
670 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);
436 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
      }
462 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
    }
462 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
  }
436 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
534 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
  {
536 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;
536 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
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
231
    if(errno != 0 or *tmp != '\0'
536 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
  }
237.5.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
  }
436 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
  }
436 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);
237.5.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;
536 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");
504 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){
536 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){
536 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
  }
504 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
283
  /* Try the old pid file location */
536 by Björn Påhlsson
renamed some foomax values to what they actually represent
284
  if(proc_id == 0){
914 by Teddy Hogeborn
Plymouth plugin bug fix: Actually try the old PID file location
285
    pidfile = fopen(plymouth_old_pid, "r");
504 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
286
    if(pidfile != NULL){
536 by Björn Påhlsson
renamed some foomax values to what they actually represent
287
      ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
504 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
288
      if(ret != 1){
536 by Björn Påhlsson
renamed some foomax values to what they actually represent
289
	proc_id = 0;
504 by Teddy Hogeborn
* plugins.d/plymouth.c (plymouth_pid): Changed to
290
      }
291
      fclose(pidfile);
292
    }
293
  }
294
  /* Look for a plymouth process */
536 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);
670 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");
237.5.1 by Björn Påhlsson
password-prompt: added conflic handling with plymouth daemon.
300
    }
670 by Teddy Hogeborn
White space fix: change "if (" to "if(" in C code.
301
    if(ret > 0){
913 by Teddy Hogeborn
Fix another memory leak in plymouth plugin
302
      for(int i = ret-1; i >= 0; i--){
303
	if(proc_id == 0){
304
	  ret = sscanf(direntries[i]->d_name, "%" SCNuMAX, &proc_id);
305
	  if(ret < 0){
306
	    error_plus(0, errno, "sscanf");
307
	  }
308
	}
309
	free(direntries[i]);
237.5.1 by Björn Påhlsson
password-prompt: added conflic handling with plymouth daemon.
310
      }
311
    }
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
312
    /* scandir might preallocate for this variable (man page unclear).
485 by Teddy Hogeborn
Merge from Björn.
313
       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.
314
    free(direntries);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
315
  }
316
  pid_t pid;
536 by Björn Påhlsson
renamed some foomax values to what they actually represent
317
  pid = (pid_t)proc_id;
318
  if((uintmax_t)pid == proc_id){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
319
    return pid;
320
  }
321
  
322
  return 0;
323
}
324
912 by Teddy Hogeborn
Fix memory leak in plymouth plugin
325
char **getargv(pid_t pid){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
326
  int cl_fd;
327
  char *cmdline_filename;
328
  ssize_t sret;
329
  int ret;
330
  
331
  ret = asprintf(&cmdline_filename, "/proc/%" PRIuMAX "/cmdline",
332
		 (uintmax_t)pid);
333
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
334
    error_plus(0, errno, "asprintf");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
335
    return NULL;
336
  }
337
  
338
  /* Open /proc/<pid>/cmdline  */
339
  cl_fd = open(cmdline_filename, O_RDONLY);
340
  free(cmdline_filename);
341
  if(cl_fd == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
342
    error_plus(0, errno, "open");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
343
    return NULL;
344
  }
345
  
346
  size_t cmdline_allocated = 0;
347
  size_t cmdline_len = 0;
348
  char *cmdline = NULL;
349
  char *tmp;
350
  const size_t blocksize = 1024;
351
  do {
352
    /* Allocate more space? */
353
    if(cmdline_len + blocksize > cmdline_allocated){
354
      tmp = realloc(cmdline, cmdline_allocated + blocksize);
355
      if(tmp == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
356
	error_plus(0, errno, "realloc");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
357
	free(cmdline);
358
	close(cl_fd);
359
	return NULL;
360
      }
361
      cmdline = tmp;
362
      cmdline_allocated += blocksize;
363
    }
364
    
365
    /* Read data */
366
    sret = read(cl_fd, cmdline + cmdline_len,
367
		cmdline_allocated - cmdline_len);
368
    if(sret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
369
      error_plus(0, errno, "read");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
370
      free(cmdline);
371
      close(cl_fd);
372
      return NULL;
373
    }
374
    cmdline_len += (size_t)sret;
375
  } while(sret != 0);
376
  ret = close(cl_fd);
377
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
378
    error_plus(0, errno, "close");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
379
    free(cmdline);
380
    return NULL;
381
  }
382
  
383
  /* we got cmdline and cmdline_len, ignore rest... */
432 by teddy at bsnet
* plugins.d/usplash.c (main): BUG FIX: allocate space for the final
384
  char **argv = malloc((argz_count(cmdline, cmdline_len) + 1)
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
385
		       * sizeof(char *)); /* Get number of args */
386
  if(argv == NULL){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
387
    error_plus(0, errno, "argv = malloc()");
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
388
    free(cmdline);
389
    return NULL;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
390
  }
431 by teddy at bsnet
* debian/watch: Also watch for "*.tar.xz" files.
391
  argz_extract(cmdline, cmdline_len, argv); /* Create argv */
912 by Teddy Hogeborn
Fix memory leak in plymouth plugin
392
  return argv;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
393
}
394
395
int main(__attribute__((unused))int argc,
396
	 __attribute__((unused))char **argv){
397
  char *prompt;
398
  char *prompt_arg;
399
  pid_t plymouth_command_pid;
400
  int ret;
401
  bool bret;
402
403
  /* test -x /bin/plymouth */
404
  ret = access(plymouth_path, X_OK);
405
  if(ret == -1){
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
406
    /* Plymouth is probably not installed.  Don't print an error
407
       message, just exit. */
408
    exit(EX_UNAVAILABLE);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
409
  }
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
410
  
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
411
  { /* Add signal handlers */
412
    struct sigaction old_action,
413
      new_action = { .sa_handler = termination_handler,
414
		     .sa_flags = 0 };
415
    sigemptyset(&new_action.sa_mask);
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
416
    for(int *sig = (int[]){ SIGINT, SIGHUP, SIGTERM, 0 };
417
	*sig != 0; sig++){
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
418
      ret = sigaddset(&new_action.sa_mask, *sig);
419
      if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
420
	error_plus(EX_OSERR, errno, "sigaddset");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
421
      }
422
      ret = sigaction(*sig, NULL, &old_action);
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
      if(old_action.sa_handler != SIG_IGN){
427
	ret = sigaction(*sig, &new_action, NULL);
428
	if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
429
	  error_plus(EX_OSERR, errno, "sigaction");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
430
	}
431
      }
432
    }
433
  }
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
434
  
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
435
  /* plymouth --ping */
436
  bret = exec_and_wait(&plymouth_command_pid, plymouth_path,
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
437
		       (const char *[])
438
		       { plymouth_path, "--ping", NULL },
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
439
		       true, false);
440
  if(not bret){
441
    if(interrupted_by_signal){
442
      kill_and_wait(plymouth_command_pid);
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
443
      exit(EXIT_FAILURE);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
444
    }
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
445
    /* Plymouth is probably not running.  Don't print an error
446
       message, just exit. */
447
    exit(EX_UNAVAILABLE);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
448
  }
449
  
450
  prompt = makeprompt();
451
  ret = asprintf(&prompt_arg, "--prompt=%s", prompt);
452
  free(prompt);
453
  if(ret == -1){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
454
    error_plus(EX_OSERR, errno, "asprintf");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
455
  }
456
  
457
  /* plymouth ask-for-password --prompt="$prompt" */
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
458
  bret = exec_and_wait(&plymouth_command_pid,
459
		       plymouth_path, (const char *[])
460
		       { plymouth_path, "ask-for-password",
461
			   prompt_arg, NULL },
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
462
		       true, false);
463
  free(prompt_arg);
464
  if(bret){
465
    exit(EXIT_SUCCESS);
466
  }
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
467
  if(not interrupted_by_signal){
468
    /* exec_and_wait failed for some other reason */
469
    exit(EXIT_FAILURE);
470
  }
471
  kill_and_wait(plymouth_command_pid);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
472
  
912 by Teddy Hogeborn
Fix memory leak in plymouth plugin
473
  char **plymouthd_argv = NULL;
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
474
  pid_t pid = get_pid();
475
  if(pid == 0){
24.1.174 by Björn Påhlsson
* Makefile (CFLAGS): Added "-lrt" to include real time library.
476
    error_plus(0, 0, "plymouthd pid not found");
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
477
  } else {
478
    plymouthd_argv = getargv(pid);
479
  }
480
  
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
481
  bret = exec_and_wait(NULL, plymouth_path, (const char *[])
482
		       { plymouth_path, "quit", NULL },
483
		       false, false);
484
  if(not bret){
912 by Teddy Hogeborn
Fix memory leak in plymouth plugin
485
    if(plymouthd_argv != NULL){
486
      free(*plymouthd_argv);
487
      free(plymouthd_argv);
488
    }
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
489
    exit(EXIT_FAILURE);
490
  }
912 by Teddy Hogeborn
Fix memory leak in plymouth plugin
491
  bret = exec_and_wait(NULL, plymouthd_path,
492
		       (plymouthd_argv != NULL)
493
		       ? (const char * const *)plymouthd_argv
494
		       : plymouthd_default_argv,
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
495
		       false, true);
912 by Teddy Hogeborn
Fix memory leak in plymouth plugin
496
  if(plymouthd_argv != NULL){
497
    free(*plymouthd_argv);
498
    free(plymouthd_argv);
499
  }
436 by teddy at bsnet
* plugins.d/plymouth.c: Break lines, fix whitespace. Remove
500
  if(not bret){
501
    exit(EXIT_FAILURE);
502
  }
503
  exec_and_wait(NULL, plymouth_path, (const char *[])
504
		{ plymouth_path, "show-splash", NULL },
505
		false, false);
24.1.157 by Björn Påhlsson
added the actually plugin file for plymouth
506
  exit(EXIT_FAILURE);
507
}