#include <NetInfo/config.h>
#ifdef _OS_APPLE_
static int aborted = 0;
static enum {
ALERT_FRESH,
ALERT_OPENED,
ALERT_PRINTED,
ALERT_CLOSED
} alert_state = ALERT_CLOSED;
void
alert_enable(int enable)
{
if (enable) alert_state = ALERT_FRESH;
else alert_state = ALERT_CLOSED;
}
int
alert_aborted(void)
{
return aborted;
}
void
alert_close(void)
{
if (alert_state != ALERT_PRINTED) return;
alert_state = ALERT_CLOSED;
}
void alert_open(const char *language)
{
if (alert_state != ALERT_FRESH) return;
alert_state = ALERT_PRINTED;
}
#else
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/file.h>
#include <sys/param.h>
#include <errno.h>
#ifdef _OS_NEXT_
#define BUNDLE_PATH "/usr/lib/NextStep/Resources"
#define _PATH_CONSOLE "/dev/console"
#else
#define BUNDLE_PATH "/System/Library/CoreServices/Resources"
#include <sys/ioctl_compat.h>
#endif
#ifndef _PATH_CONSOLE
#include <paths.h>
#endif
#include "ni_globals.h"
#include "system.h"
#include <NetInfo/system_log.h>
#define KERNEL_PRIVATE
#include <dev/kmreg_com.h>
#undef KERNEL_PRIVATE
#define MAXLINE 4096
#define STRING_TABLE "NetInfo"
static const char SEARCH_MESSAGE[] =
"\\nStill searching for parent network administration (NetInfo) "
"server.\\nPlease wait, or press 'c' to continue without network "
"user accounts.\\n\\nSee your system administrator if you need help.\\n";
static const char MESSAGE[] =
"\nStill searching for parent network administration (NetInfo) "
"server.\nPlease wait, or press 'c' to continue without network "
"user accounts.\n\nSee your system administrator if you need help.\n";
static int aborted = 0;
static int console;
static int console_flags;
static struct sgttyb console_sg;
static enum {
ALERT_FRESH,
ALERT_OPENED,
ALERT_PRINTED,
ALERT_CLOSED
} alert_state = ALERT_CLOSED;
void
alert_enable(int enable)
{
if (enable) alert_state = ALERT_FRESH;
else alert_state = ALERT_CLOSED;
}
int
alert_aborted(void)
{
return (aborted);
}
void
alert_close(void)
{
if (alert_state != ALERT_PRINTED) return;
alert_state = ALERT_CLOSED;
fcntl(console, F_SETFL, console_flags);
ioctl(console, TIOCSETP, &console_sg);
ioctl(console, KMIOCRESTORE, 0);
close(console);
}
static void
handle_io(int ignored)
{
char buf[512];
char *cp;
int nchars;
while ((nchars = read(console, (char *)&buf, sizeof(buf))) > 0)
{
cp = buf;
while (nchars--)
{
if ((*cp == 'c') || (*cp == 'C'))
{
system_log(LOG_DEBUG, "Binding aborted");
aborted = 1;
alert_close();
return;
}
cp++;
}
}
if (errno != EWOULDBLOCK) alert_close();
}
void
alert_open(const char *language)
{
struct sgttyb sg;
FILE *fp;
char filename[MAXPATHLEN + 1];
char buf[MAXLINE];
char outmsg[MAXLINE];
int i, j, len;
if (alert_state != ALERT_FRESH) return;
alert_state = ALERT_OPENED;
if ((console = open(_PATH_CONSOLE, (O_RDWR|O_ALERT), 0)) < 0)
{
system_log(LOG_ERR, "console open failed: %s", strerror(errno));
aborted = 1;
return;
}
ioctl(console, TIOCFLUSH, FREAD);
if ((console_flags = fcntl(console, F_GETFL, 0)) == -1)
{
system_log(LOG_ERR, "console F_GETFL fcntl failed: %s",
strerror(errno));
aborted = 1;
close(console);
return;
}
if (fcntl(console, F_SETFL, (console_flags|FASYNC|FNDELAY)) == -1)
{
system_log(LOG_ERR, "console F_SETFL fcntl failed: %s",
strerror(errno));
aborted = 1;
close(console);
return;
}
signal(SIGIO, handle_io);
if (ioctl(console, TIOCGETP, &sg) == -1)
{
system_log(LOG_ERR, "console TIOCGETP ioctl failed: %s",
strerror(errno));
aborted = 1;
close(console);
return;
}
console_sg = sg;
sg.sg_flags |= CBREAK;
sg.sg_flags &= ~ECHO;
if (ioctl(console, TIOCSETP, &sg) == -1)
{
system_log(LOG_ERR, "console TIOCSETP ioctl failed: %s",
strerror(errno));
aborted = 1;
close(console);
return;
}
alert_state = ALERT_PRINTED;
sprintf(filename, "%s/%s.lproj/%s.strings",
BUNDLE_PATH, language, STRING_TABLE);
len = strlen(MESSAGE);
fp = fopen(filename, "r");
if (fp == NULL)
{
write(console, MESSAGE, len);
return;
}
while (fgets(buf, MAXLINE, fp) != NULL)
{
if (!strncmp(buf+1, SEARCH_MESSAGE, len))
{
for (i = strlen(buf); ((buf[i] != '\"') && (i > 0)); i--);
if (i <= 0) break;
buf[i] = '\0';
for (i = strlen(SEARCH_MESSAGE) + 2; ((buf[i] != '\0') && (buf[i] != '\"')); i++);
if (buf[i] == '\0') break;
i++;
j = 0;
for (; buf[i] != '\0'; i++)
{
if ((buf[i] == '\\') && (buf[i+1] == 'n'))
{
i++;
outmsg[j++] = '\n';
}
else outmsg[j++] = buf[i];
}
if (j == 0) break;
fclose(fp);
outmsg[j] = '\0';
write(console, outmsg, j);
return;
}
}
fclose(fp);
write(console, MESSAGE, len);
}
#endif NO_CONSOLE_SUPPORT