1/*
2 * periodic-wrapper.c
3 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
4 */
5
6#include <xpc/xpc.h>
7#include <xpc/private.h>
8#include <asl.h>
9#include <vproc_priv.h>
10
11extern char **environ;
12
13int
14main(int argc, char *argv[])
15{
16	int64_t is_managed;
17	char activity_name[32];
18	static dispatch_source_t sigterm_source;
19
20	xpc_track_activity();
21
22	is_managed = 0;
23	(void)vproc_swap_integer(NULL, VPROC_GSK_IS_MANAGED, NULL, &is_managed);
24	if (!is_managed) {
25		exit(1);
26	}
27
28	if (argc != 2) {
29		exit(1);
30	}
31
32	if (strcmp(argv[1], "daily") == 0) {
33	} else if (strcmp(argv[1], "weekly") == 0) {
34	} else if (strcmp(argv[1], "monthly") == 0) {
35	} else {
36		exit(1);
37	}
38
39	sigterm_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_SIGNAL, SIGTERM, 0, dispatch_get_main_queue());
40	dispatch_source_set_event_handler(sigterm_source, ^{
41		exit(0);
42	});
43	dispatch_resume(sigterm_source);
44
45	snprintf(activity_name, sizeof(activity_name), "com.apple.periodic-%s", argv[1]);
46
47	xpc_activity_register(activity_name, XPC_ACTIVITY_CHECK_IN, ^(xpc_activity_t activity) {
48		xpc_activity_state_t state;
49
50		state = xpc_activity_get_state(activity);
51		if (state == XPC_ACTIVITY_STATE_RUN) {
52			pid_t pid;
53			int status;
54			bool success = false;
55
56			asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "Running %s periodic task.", argv[1]);
57
58			const char *args[] = { "periodic", argv[1], NULL };
59			if (posix_spawn(&pid, "/usr/sbin/periodic", NULL, NULL, (char * const *)args, environ) == 0) {
60				if (waitpid(pid, &status, 0) != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) {
61					success = true;
62				}
63			}
64
65			if (!success) {
66				asl_log(NULL, NULL, ASL_LEVEL_NOTICE, "Error running %s periodic task.", argv[1]);
67			}
68		}
69	});
70
71	dispatch_main();
72}
73