1 /*
2  * Copyright (c) 2014 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Chris Pressey <cpressey@catseye.mine.nu>.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 /*
36  * test.c
37  * Test some libinstaller functions.
38  */
39 
40 #include <stdio.h>
41 #include <err.h>
42 #include <unistd.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45 
46 #define NEEDS_DFUI_STRUCTURE_DEFINITIONS
47 #define NEEDS_DISKUTIL_STRUCTURE_DEFINITIONS
48 #include "libdfui/dfui.h"
49 
50 #include "libinstaller/functions.h"
51 #include "libinstaller/diskutil.h"
52 #include "libinstaller/commands.h"
53 
54 #ifdef DEBUG
55 #include "libdfui/dump.h"
56 #endif
57 #include "libaura/fspred.h"
58 
59 #define TMPDIR "/tmp/installer/temp"
60 
61 void test_storage(struct i_fn_args *);
62 void libinstaller_backend(struct i_fn_args **);
63 void libinstaller_frontend(struct dfui_connection **);
64 void libinstaller_form_dump(struct dfui_form *);
65 
66 void (*tstate)(struct i_fn_args *) = NULL;
67 
68 void
69 check_user(void)
70 {
71 	if (getuid() != 0) {
72 		warnx(
73 			"\n--------------------------------------------------\n"
74 			"It is not recommended that you run this program\n"
75 			"as a regular user since many of the tasks the\n"
76 			"installer performs must be run as root\n"
77 			"(such as fdisk, disklabel, ...)\n"
78 			"Please run as root to get correct results.\n"
79 			"--------------------------------------------------\n"
80 			);
81 		sleep(2);
82 	}
83 }
84 
85 void
86 test_storage(struct i_fn_args *a)
87 {
88 	struct disk *dsk, *dsk_next;
89 	int r;
90 
91 	r = survey_storage(a);
92 	printf("survey_storage rc=%d\n", r);
93 
94 	printf("Found disks:\n");
95 
96 	dsk = a->s->disk_head;
97 	while (dsk != NULL) {
98 		dsk_next = dsk->next;
99 		printf("%s %ld MB\n",
100 		       dsk->device, dsk->capacity);
101 		dsk = dsk_next;
102 	}
103 	tstate = NULL;
104 }
105 
106 void
107 libinstaller_backend(struct i_fn_args **a)
108 {
109 	struct i_fn_args *ap = *a;
110 
111 	ap = i_fn_args_new("/", TMPDIR, "tmp/cmdnames.conf",
112 	    DFUI_TRANSPORT_TCP, "9999");
113 
114 	if (ap == NULL)
115 		errx(1, "Failed to start the installer backend");
116 
117 	tstate = test_storage;
118 
119 	for (; tstate != NULL; ) {
120 		tstate(ap);
121 	}
122 
123 	i_fn_args_free(ap);
124 }
125 
126 void
127 libinstaller_frontend(struct dfui_connection **c) {
128 	struct dfui_connection *cp = *c;
129 	struct dfui_response *r;
130 	char msgtype;
131 	void *payload;
132 	int done = 0;
133 
134 	usleep(100000);	/* Not really necessary */
135 	cp = dfui_connection_new(DFUI_TRANSPORT_TCP, "9999");
136 	dfui_fe_connect(cp);
137 
138 	while (!done) {
139 		dfui_fe_receive(cp, &msgtype, &payload);
140 		switch (msgtype) {
141 		case DFUI_BE_MSG_PRESENT:
142 #ifdef DEBUG
143 			struct dfui_form *f;
144 			f = (struct dfui_form *)payload;
145 			dfui_form_dump(f);
146 #endif
147 			r = dfui_response_new("dialog", "Cancel");
148 			dfui_fe_submit(cp, r);
149 			dfui_response_free(r);
150 			sleep(1);
151 			break;
152 		case DFUI_BE_MSG_PROG_BEGIN:
153 		case DFUI_BE_MSG_PROG_UPDATE:
154 		case DFUI_BE_MSG_PROG_END:
155 			/* Details about the progress can go here */
156 			dfui_fe_progress_continue(cp);
157 			break;
158 		case DFUI_BE_MSG_STOP:
159 			dfui_fe_confirm_stop(cp);
160 			done = 1;
161 			break;
162 		default:
163 			printf("msgtype=%c\n", msgtype);
164 			sleep(1);
165 		}
166 	}
167 	dfui_fe_disconnect(cp);
168 }
169 
170 int
171 main(int argc __unused, char **argv __unused)
172 {
173 	struct dfui_connection *c;
174 	struct i_fn_args *a;
175 	int error;
176 	char *path;
177 	int r;
178 
179 	check_user();
180 
181 	asprintf(&path, "mkdir -p %s", TMPDIR);
182 	system(path);
183 	free(path);
184 
185 	r = fork();
186 	switch(r) {
187 	case -1:
188 		err(1, "Failed to fork");
189 		/* NOT REACHED */
190 	case 0:
191 		libinstaller_backend(&a);
192 		break; 		/* NOT REACHED */
193 	default:
194 		libinstaller_frontend(&c);
195 	}
196 
197 	return(0);
198 }
199