aboutsummaryrefslogtreecommitdiffstats
path: root/pseudo_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'pseudo_client.c')
-rw-r--r--pseudo_client.c140
1 files changed, 69 insertions, 71 deletions
diff --git a/pseudo_client.c b/pseudo_client.c
index b6d11a6..9e0de96 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -225,7 +225,7 @@ pseudo_init_client(void) {
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "prefix directory doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -248,7 +248,7 @@ pseudo_init_client(void) {
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "local state directory doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "local state directory doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -468,7 +468,7 @@ pseudo_client_chroot(const char *path) {
/* free old value */
free(pseudo_chroot);
- pseudo_debug(2, "client chroot: %s\n", path);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_CHROOT, "client chroot: %s\n", path);
if (!strcmp(path, "/")) {
pseudo_chroot_len = 0;
pseudo_chroot = 0;
@@ -499,7 +499,7 @@ pseudo_root_path(const char *func, int line, int dirfd, const char *path, int le
pseudo_diag("couldn't allocate absolute path for '%s'.\n",
path);
}
- pseudo_debug(3, "root_path [%s, %d]: '%s' from '%s'\n",
+ pseudo_debug(PDBGF_CHROOT, "root_path [%s, %d]: '%s' from '%s'\n",
func, line,
rc ? rc : "<nil>",
path ? path : "<nil>");
@@ -514,13 +514,13 @@ pseudo_client_getcwd(void) {
pseudo_diag("Can't allocate CWD buffer!\n");
return -1;
}
- pseudo_debug(3, "getcwd: trying to find cwd.\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "getcwd: trying to find cwd.\n");
if (getcwd(cwd, pseudo_path_max())) {
/* cwd now holds a canonical path to current directory */
free(pseudo_cwd);
pseudo_cwd = cwd;
pseudo_cwd_len = strlen(pseudo_cwd);
- pseudo_debug(3, "getcwd okay: [%s] %d bytes\n", pseudo_cwd, (int) pseudo_cwd_len);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "getcwd okay: [%s] %d bytes\n", pseudo_cwd, (int) pseudo_cwd_len);
if (pseudo_chroot_len &&
pseudo_cwd_len >= pseudo_chroot_len &&
!memcmp(pseudo_cwd, pseudo_chroot, pseudo_chroot_len) &&
@@ -530,9 +530,9 @@ pseudo_client_getcwd(void) {
} else {
pseudo_cwd_rel = pseudo_cwd;
}
- pseudo_debug(4, "abscwd: <%s>\n", pseudo_cwd);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "abscwd: <%s>\n", pseudo_cwd);
if (pseudo_cwd_rel != pseudo_cwd) {
- pseudo_debug(4, "relcwd: <%s>\n", pseudo_cwd_rel);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "relcwd: <%s>\n", pseudo_cwd_rel);
}
return 0;
} else {
@@ -559,7 +559,7 @@ pseudo_client_path(int fd, const char *path) {
if (fd >= nfds) {
int i;
- pseudo_debug(2, "expanding fds from %d to %d\n",
+ pseudo_debug(PDBGF_CLIENT, "expanding fds from %d to %d\n",
nfds, fd + 1);
fd_paths = realloc(fd_paths, (fd + 1) * sizeof(char *));
for (i = nfds; i < fd + 1; ++i)
@@ -567,7 +567,7 @@ pseudo_client_path(int fd, const char *path) {
nfds = fd + 1;
} else {
if (fd_paths[fd]) {
- pseudo_debug(2, "reopening fd %d [%s] -- didn't see close\n",
+ pseudo_debug(PDBGF_CLIENT, "reopening fd %d [%s] -- didn't see close\n",
fd, fd_paths[fd]);
}
/* yes, it is safe to free null pointers. yay for C89 */
@@ -600,7 +600,7 @@ client_spawn_server(void) {
pseudo_diag("couldn't fork server: %s\n", strerror(errno));
return 1;
}
- pseudo_debug(4, "spawned server, pid %d\n", server_pid);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER, "spawned server, pid %d\n", server_pid);
/* wait for the child process to terminate, indicating server
* is ready
*/
@@ -610,14 +610,14 @@ client_spawn_server(void) {
fp = fopen(pseudo_pidfile, "r");
if (fp) {
if (fscanf(fp, "%d", &server_pid) != 1) {
- pseudo_debug(1, "Opened server PID file, but didn't get a pid.\n");
+ pseudo_debug(PDBGF_CLIENT, "Opened server PID file, but didn't get a pid.\n");
}
fclose(fp);
} else {
- pseudo_debug(1, "no pid file (%s): %s\n",
+ pseudo_debug(PDBGF_CLIENT, "no pid file (%s): %s\n",
pseudo_pidfile, strerror(errno));
}
- pseudo_debug(2, "read new pid file: %d\n", server_pid);
+ pseudo_debug(PDBGF_CLIENT, "read new pid file: %d\n", server_pid);
free(pseudo_pidfile);
/* at this point, we should have a new server_pid */
return 0;
@@ -679,7 +679,7 @@ client_spawn_server(void) {
pseudo_setupenv();
pseudo_dropenv(); /* drop PRELINK_LIBRARIES */
- pseudo_debug(4, "calling execv on %s\n", argv[0]);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER | PDBGF_INVOKE, "calling execv on %s\n", argv[0]);
execv(argv[0], argv);
pseudo_diag("critical failure: exec of pseudo daemon failed: %s\n", strerror(errno));
@@ -707,25 +707,25 @@ client_ping(void) {
ping.client = getpid();
ping.result = 0;
errno = 0;
- pseudo_debug(4, "sending ping\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending ping\n");
if (pseudo_msg_send(connect_fd, &ping, ping.pathlen, tagbuf)) {
- pseudo_debug(3, "error pinging server: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "error pinging server: %s\n", strerror(errno));
return 1;
}
ack = pseudo_msg_receive(connect_fd);
if (!ack) {
- pseudo_debug(2, "no ping response from server: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT, "no ping response from server: %s\n", strerror(errno));
/* and that's not good, so... */
server_pid = 0;
return 1;
}
if (ack->type != PSEUDO_MSG_ACK) {
- pseudo_debug(1, "invalid ping response from server: expected ack, got %d\n", ack->type);
+ pseudo_debug(PDBGF_CLIENT, "invalid ping response from server: expected ack, got %d\n", ack->type);
/* and that's not good, so... */
server_pid = 0;
return 1;
}
- pseudo_debug(5, "ping ok\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "ping ok\n");
return 0;
}
@@ -771,7 +771,7 @@ client_connect(void) {
return 1;
}
- pseudo_debug(3, "connecting socket...\n");
+ pseudo_debug(PDBGF_CLIENT, "connecting socket...\n");
cwd_fd = open(".", O_RDONLY);
if (cwd_fd == -1) {
pseudo_diag("Couldn't stash directory before opening socket: %s",
@@ -789,7 +789,7 @@ client_connect(void) {
return 1;
}
if (connect(connect_fd, (struct sockaddr *) &sun, sizeof(sun)) == -1) {
- pseudo_debug(3, "can't connect socket to pseudo.socket: (%s)\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT, "can't connect socket to pseudo.socket: (%s)\n", strerror(errno));
close(connect_fd);
if (fchdir(cwd_fd) == -1) {
pseudo_diag("return to previous directory failed: %s\n",
@@ -804,7 +804,7 @@ client_connect(void) {
strerror(errno));
}
close(cwd_fd);
- pseudo_debug(4, "connected socket.\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "connected socket.\n");
return 0;
}
@@ -824,13 +824,13 @@ pseudo_client_setup(void) {
fp = fopen(pseudo_pidfile, "r");
if (fp) {
if (fscanf(fp, "%d", &server_pid) != 1) {
- pseudo_debug(1, "Opened server PID file, but didn't get a pid.\n");
+ pseudo_debug(PDBGF_CLIENT, "Opened server PID file, but didn't get a pid.\n");
}
fclose(fp);
}
if (server_pid) {
if (kill(server_pid, 0) == -1) {
- pseudo_debug(1, "couldn't find server at pid %d: %s\n",
+ pseudo_debug(PDBGF_CLIENT, "couldn't find server at pid %d: %s\n",
server_pid, strerror(errno));
server_pid = 0;
}
@@ -843,20 +843,17 @@ pseudo_client_setup(void) {
if (!client_connect() && !client_ping()) {
return 0;
}
- pseudo_debug(2, "server seems to be gone, trying to restart\n");
+ pseudo_debug(PDBGF_CLIENT, "server seems to be gone, trying to restart\n");
if (client_spawn_server()) {
- pseudo_debug(1, "failed to spawn server, giving up.\n");
+ pseudo_debug(PDBGF_CLIENT, "failed to spawn server, giving up.\n");
return 1;
} else {
- pseudo_debug_verbose();
- pseudo_debug(2, "restarted, new pid %d\n", server_pid);
+ pseudo_debug(PDBGF_CLIENT, "restarted, new pid %d\n", server_pid);
if (!client_connect() && !client_ping()) {
- pseudo_debug_terse();
return 0;
}
- pseudo_debug_terse();
}
- pseudo_debug(1, "couldn't get a server, giving up.\n");
+ pseudo_debug(PDBGF_CLIENT, "couldn't get a server, giving up.\n");
return 1;
}
@@ -871,35 +868,35 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
do {
do {
- pseudo_debug(4, "sending a message: ino %llu\n",
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending a message: ino %llu\n",
(unsigned long long) msg->ino);
if (connect_fd < 0) {
- pseudo_debug(2, "trying to get server\n");
+ pseudo_debug(PDBGF_CLIENT, "trying to get server\n");
if (pseudo_client_setup()) {
return 0;
}
}
rc = pseudo_msg_send(connect_fd, msg, len, path);
if (rc != 0) {
- pseudo_debug(2, "msg_send: %d%s\n",
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "msg_send: %d%s\n",
rc,
rc == -1 ? " (sigpipe)" :
" (short write)");
pseudo_client_setup();
++tries;
if (tries > 3) {
- pseudo_debug(1, "can't get server going again.\n");
+ pseudo_debug(PDBGF_CLIENT, "can't get server going again.\n");
return 0;
}
}
} while (rc != 0);
- pseudo_debug(5, "sent!\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sent!\n");
if (msg->type != PSEUDO_MSG_FASTOP) {
response = pseudo_msg_receive(connect_fd);
if (!response) {
++tries;
if (tries > 3) {
- pseudo_debug(1, "can't get responses.\n");
+ pseudo_debug(PDBGF_CLIENT, "can't get responses.\n");
return 0;
}
}
@@ -908,10 +905,10 @@ pseudo_client_request(pseudo_msg_t *msg, size_t len, const char *path) {
}
} while (response == 0);
if (response->type != PSEUDO_MSG_ACK) {
- pseudo_debug(2, "got non-ack response %d\n", response->type);
+ pseudo_debug(PDBGF_CLIENT, "got non-ack response %d\n", response->type);
return 0;
} else {
- pseudo_debug(4, "got response type %d\n", response->type);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "got response type %d\n", response->type);
}
return response;
}
@@ -922,13 +919,14 @@ pseudo_client_shutdown(void) {
pseudo_msg_t *ack;
char *pseudo_path;
+ pseudo_debug(PDBGF_INVOKE, "attempting to shut down server.\n");
pseudo_path = pseudo_prefix_path(NULL);
if (pseudo_prefix_dir_fd == -1) {
if (pseudo_path) {
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "prefix directory doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -952,7 +950,7 @@ pseudo_client_shutdown(void) {
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
/* directory is missing? */
if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
- pseudo_debug(1, "local state dir doesn't exist, trying to create\n");
+ pseudo_debug(PDBGF_CLIENT, "local state dir doesn't exist, trying to create\n");
mkdir_p(pseudo_path);
pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
}
@@ -977,9 +975,9 @@ pseudo_client_shutdown(void) {
msg.type = PSEUDO_MSG_SHUTDOWN;
msg.op = OP_NONE;
msg.client = getpid();
- pseudo_debug(2, "sending shutdown request\n");
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER, "sending shutdown request\n");
if (pseudo_msg_send(connect_fd, &msg, 0, NULL)) {
- pseudo_debug(1, "error requesting shutdown: %s\n", strerror(errno));
+ pseudo_debug(PDBGF_CLIENT | PDBGF_SERVER, "error requesting shutdown: %s\n", strerror(errno));
return 1;
}
ack = pseudo_msg_receive(connect_fd);
@@ -1043,7 +1041,7 @@ base_path(int dirfd, const char *path, int leave_last) {
}
newpath = pseudo_fix_path(basepath, path, minlen, baselen, NULL, leave_last);
- pseudo_debug(4, "base_path: %s</>%s\n",
+ pseudo_debug(PDBGF_PATH, "base_path: %s</>%s\n",
basepath ? basepath : "<nil>",
path ? path : "<nil>");
return newpath;
@@ -1103,7 +1101,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
snprintf(both_paths, full_len, "%.*s%c%s",
(int) (pathlen - 1 - strip_slash),
path, 0, oldpath);
- pseudo_debug(2, "rename: %s -> %s [%d]\n",
+ pseudo_debug(PDBGF_PATH | PDBGF_FILE, "rename: %s -> %s [%d]\n",
both_paths + pathlen, both_paths, (int) full_len);
alloced_path = both_paths;
path = alloced_path;
@@ -1125,30 +1123,30 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
path = 0;
msg.pathlen = 0;
}
- pseudo_debug(2, "%s%s", pseudo_op_name(op),
+ pseudo_debug(PDBGF_OP, "%s%s", pseudo_op_name(op),
(dirfd != -1 && dirfd != AT_FDCWD && op != OP_DUP) ? "at" : "");
if (oldpath) {
- pseudo_debug(2, " %s ->", (char *) oldpath);
+ pseudo_debug(PDBGF_OP, " %s ->", (char *) oldpath);
}
if (path) {
- pseudo_debug(2, " %s", path);
+ pseudo_debug(PDBGF_OP, " %s", path);
}
/* for OP_RENAME in renameat, "fd" is also used for the
* second dirfd.
*/
if (fd != -1 && op != OP_RENAME) {
- pseudo_debug(2, " [fd %d]", fd);
+ pseudo_debug(PDBGF_OP, " [fd %d]", fd);
}
if (buf) {
- pseudo_debug(2, " (+buf)");
+ pseudo_debug(PDBGF_OP, " (+buf)");
pseudo_msg_stat(&msg, buf);
if (buf && fd != -1) {
- pseudo_debug(2, " [dev/ino: %d/%llu]",
+ pseudo_debug(PDBGF_OP, " [dev/ino: %d/%llu]",
(int) buf->st_dev, (unsigned long long) buf->st_ino);
}
- pseudo_debug(2, " (0%o)", (int) buf->st_mode);
+ pseudo_debug(PDBGF_OP, " (0%o)", (int) buf->st_mode);
}
- pseudo_debug(2, ": ");
+ pseudo_debug(PDBGF_OP, ": ");
msg.type = PSEUDO_MSG_OP;
msg.op = op;
msg.fd = fd;
@@ -1157,7 +1155,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
msg.client = getpid();
/* do stuff */
- pseudo_debug(4, "processing request [ino %llu]\n", (unsigned long long) msg.ino);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "processing request [ino %llu]\n", (unsigned long long) msg.ino);
switch (msg.op) {
case OP_CHDIR:
pseudo_client_getcwd();
@@ -1207,7 +1205,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
break;
case OP_DUP:
/* just copy the path over */
- pseudo_debug(2, "dup: fd_path(%d) = %p [%s], dup to %d\n",
+ pseudo_debug(PDBGF_CLIENT, "dup: fd_path(%d) = %p [%s], dup to %d\n",
fd, fd_path(fd), fd_path(fd) ? fd_path(fd) : "<nil>",
dirfd);
pseudo_client_path(dirfd, fd_path(fd));
@@ -1221,7 +1219,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
case OP_SYMLINK:
msg.uid = pseudo_fuid;
msg.gid = pseudo_fgid;
- pseudo_debug(2, "fuid: %d ", pseudo_fuid);
+ pseudo_debug(PDBGF_OP, "fuid: %d ", pseudo_fuid);
/* FALLTHROUGH */
/* chown/fchown uid/gid already calculated, and
* a link or rename should not change a file's ownership.
@@ -1249,7 +1247,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
struct timeval tv1, tv2;
if (!pseudo_op_wait(msg.op))
msg.type = PSEUDO_MSG_FASTOP;
- pseudo_debug(4, "sending request [ino %llu]\n", (unsigned long long) msg.ino);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "sending request [ino %llu]\n", (unsigned long long) msg.ino);
gettimeofday(&tv1, NULL);
if (pseudo_local_only) {
/* disable server */
@@ -1269,27 +1267,27 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
++message_time.tv_sec;
}
if (result) {
- pseudo_debug(2, "(%d) %s", getpid(), pseudo_res_name(result->result));
+ pseudo_debug(PDBGF_OP, "(%d) %s", getpid(), pseudo_res_name(result->result));
if (op == OP_STAT || op == OP_FSTAT) {
- pseudo_debug(2, " mode 0%o uid %d:%d",
+ pseudo_debug(PDBGF_OP, " mode 0%o uid %d:%d",
(int) result->mode,
(int) result->uid,
(int) result->gid);
} else if (op == OP_CHMOD || op == OP_FCHMOD) {
- pseudo_debug(2, " mode 0%o",
+ pseudo_debug(PDBGF_OP, " mode 0%o",
(int) result->mode);
} else if (op == OP_CHOWN || op == OP_FCHOWN) {
- pseudo_debug(2, " uid %d:%d",
+ pseudo_debug(PDBGF_OP, " uid %d:%d",
(int) result->uid,
(int) result->gid);
}
} else {
- pseudo_debug(2, "(%d) no answer", getpid());
+ pseudo_debug(PDBGF_OP, "(%d) no answer", getpid());
}
} else {
- pseudo_debug(2, "(%d) (no request)", getpid());
+ pseudo_debug(PDBGF_OP, "(%d) (no request)", getpid());
}
- pseudo_debug(2, "\n");
+ pseudo_debug(PDBGF_OP, "\n");
/* if not NULL, alloced_path is an allocated buffer for both
* paths, or for modified paths...
@@ -1297,7 +1295,7 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
free(alloced_path);
if (do_request && (messages % 1000 == 0)) {
- pseudo_debug(2, "%d messages handled in %.4f seconds\n",
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE | PDBGF_BENCHMARK, "%d messages handled in %.4f seconds\n",
messages,
(double) message_time.tv_sec +
(double) message_time.tv_usec / 1000000.0);
@@ -1418,21 +1416,21 @@ pseudo_exec_path(const char *filename, int search_path) {
for (i = 0; path_segs[i]; ++i) {
path = path_segs[i];
- pseudo_debug(2, "exec_path: checking %s for %s\n", path, filename);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: checking %s for %s\n", path, filename);
if (!*path || (*path == '.' && path_lens[i] == 1)) {
/* empty path or . is cwd */
candidate = pseudo_fix_path(pseudo_cwd, filename, 0, pseudo_cwd_len, NULL, 0);
- pseudo_debug(2, "exec_path: in cwd, got %s\n", candidate);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: in cwd, got %s\n", candidate);
} else if (*path == '/') {
candidate = pseudo_fix_path(path, filename, 0, path_lens[i], NULL, 0);
- pseudo_debug(2, "exec_path: got %s\n", candidate);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: got %s\n", candidate);
} else {
/* oh you jerk, making me do extra work */
size_t len;
char *dir = pseudo_fix_path(pseudo_cwd, path, 0, pseudo_cwd_len, &len, 0);
if (dir) {
candidate = pseudo_fix_path(dir, filename, 0, len, NULL, 0);
- pseudo_debug(2, "exec_path: got %s for non-absolute path\n", candidate);
+ pseudo_debug(PDBGF_CLIENT, "exec_path: got %s for non-absolute path\n", candidate);
} else {
pseudo_diag("couldn't allocate intermediate path.\n");
candidate = NULL;
@@ -1440,7 +1438,7 @@ pseudo_exec_path(const char *filename, int search_path) {
free(dir);
}
if (candidate && !stat(candidate, &buf) && !S_ISDIR(buf.st_mode) && (buf.st_mode & 0111)) {
- pseudo_debug(1, "exec_path: %s => %s\n", filename, candidate);
+ pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "exec_path: %s => %s\n", filename, candidate);
pseudo_magic();
return candidate;
} else {