2004-01-04 03:54:01 +01:00
/* dgamelaunch.c
2003-12-30 22:30:32 +01:00
*
2004-01-25 23:34:35 +01:00
* ( c ) 2001 - 4 M . Drew Streib < dtype @ dtype . org >
* also parts ( c ) 2003 - 4 Joshua Kwan < joshk @ triplehelix . org > ,
2004-01-04 03:54:01 +01:00
* Brett Carrington < brettcar @ segvio . org > ,
* Jilles Tjoelker < jilles @ stack . nl >
*
2003-12-30 22:30:32 +01:00
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
2004-01-04 03:54:01 +01:00
* See this program in action at http : //alt.org/nethack/
2003-12-30 22:30:32 +01:00
*
* This is a little wrapper for nethack ( and soon other programs ) that
* will allow them to be run from a telnetd session , chroot , shed privs ,
* make a simple login , then play the game .
*/
2004-01-02 05:35:46 +01:00
# define _GNU_SOURCE
2004-01-30 03:49:29 +01:00
2003-12-31 03:39:10 +01:00
# include "dgamelaunch.h"
2004-06-18 19:57:29 +02:00
# include "config.h"
2004-01-30 03:49:29 +01:00
# include "ttyplay.h"
# include "ttyrec.h"
2003-12-31 03:39:10 +01:00
2003-12-30 22:30:32 +01:00
/* a request from the author: please leave some remnance of
* ' based on dgamelaunch version xxx ' in any derivative works , or
* even keep the line the same altogether . I ' m probably happy
* to make any changes you need . */
/* ************************************************************* */
/* ************************************************************* */
/* ************************************************************* */
/* program stuff */
# include <sys/types.h>
2004-01-02 21:47:53 +01:00
# include <sys/time.h>
2004-01-23 19:14:48 +01:00
# include <sys/wait.h>
2004-01-25 23:34:35 +01:00
# include <sys/ioctl.h> /* ttyrec */
# include <sys/stat.h>
2010-02-25 17:40:55 +01:00
# ifdef USE_RLIMIT
# include <sys/resource.h>
# endif
2010-05-01 16:41:54 +02:00
# ifdef USE_SHMEM
# include <sys/ipc.h>
# include <sys/shm.h>
# endif
2004-07-04 01:34:13 +02:00
# include <libgen.h>
2004-01-25 23:34:35 +01:00
# include <stdlib.h>
# include <curses.h>
2004-01-02 21:47:53 +01:00
2007-12-27 20:52:48 +01:00
# ifdef USE_SQLITE3
# include <sqlite3.h>
# endif
2004-01-02 21:47:53 +01:00
# ifndef __FreeBSD__
2004-03-10 01:18:30 +01:00
# ifdef __APPLE__
# include <unistd.h>
# else
# include <crypt.h>
# endif
2004-01-02 21:47:53 +01:00
# else
# include <libutil.h>
# endif
2004-01-02 22:00:54 +01:00
# ifdef __linux__
# include <pty.h>
2004-01-03 03:10:35 +01:00
# endif
2004-01-12 18:32:47 +01:00
# include <fcntl.h>
2004-01-05 02:25:38 +01:00
# include <pwd.h>
2004-01-02 22:00:54 +01:00
# include <grp.h>
2004-01-02 21:47:53 +01:00
# include <time.h>
2003-12-30 22:30:32 +01:00
# include <errno.h>
# include <dirent.h>
# include <string.h>
2004-01-02 21:47:53 +01:00
# include <signal.h>
2003-12-30 22:30:32 +01:00
# include <assert.h>
# include <ctype.h>
# include <unistd.h>
# include <termios.h>
2004-01-05 02:25:38 +01:00
extern FILE * yyin ;
extern int yyparse ( ) ;
2004-01-25 23:44:34 +01:00
extern int editor_main ( int argc , char * * argv ) ;
2003-12-30 22:30:32 +01:00
/* global variables */
2004-07-03 21:19:28 +02:00
char * __progname ;
2010-03-02 19:32:57 +01:00
int g_idle_alarm_enabled = 0 ;
2003-12-30 22:30:32 +01:00
2007-12-27 20:52:48 +01:00
# ifndef USE_SQLITE3
2003-12-30 22:30:32 +01:00
int f_num = 0 ;
2003-12-31 02:58:56 +01:00
struct dg_user * * users = NULL ;
2007-12-27 20:52:48 +01:00
# endif
2003-12-31 02:58:56 +01:00
struct dg_user * me = NULL ;
2003-12-31 20:47:49 +01:00
struct dg_banner banner ;
2003-12-30 22:30:32 +01:00
2007-12-27 20:52:48 +01:00
struct dg_user *
cpy_me ( struct dg_user * me )
{
struct dg_user * tmp = malloc ( sizeof ( struct dg_user ) ) ;
if ( tmp & & me ) {
2007-12-30 09:29:28 +01:00
# ifdef USE_SQLITE3
2007-12-27 20:52:48 +01:00
tmp - > id = me - > id ;
2007-12-30 09:29:28 +01:00
# endif
2007-12-27 20:52:48 +01:00
if ( me - > username ) tmp - > username = strdup ( me - > username ) ;
if ( me - > email ) tmp - > email = strdup ( me - > email ) ;
if ( me - > env ) tmp - > env = strdup ( me - > env ) ;
if ( me - > password ) tmp - > password = strdup ( me - > password ) ;
tmp - > flags = me - > flags ;
}
return tmp ;
}
2004-06-18 20:16:22 +02:00
# ifndef HAVE_SETENV
2004-01-16 03:00:47 +01:00
int
mysetenv ( const char * name , const char * value , int overwrite )
{
int retval ;
char * buf = NULL ;
if ( getenv ( name ) = = NULL | | overwrite )
{
size_t len = strlen ( name ) + 1 + strlen ( value ) + 1 ; /* NAME=VALUE\0 */
buf = malloc ( len ) ;
snprintf ( buf , len , " %s=%s " , name , value ) ;
retval = putenv ( buf ) ;
}
else
retval = - 1 ;
return retval ;
}
2004-01-23 17:40:51 +01:00
# else /* use native setenv */
# define mysetenv setenv
2004-06-18 20:16:22 +02:00
# endif
2004-01-16 03:00:47 +01:00
2003-12-30 22:30:32 +01:00
/* ************************************************************* */
/* for ttyrec */
void
2004-02-20 18:57:29 +01:00
ttyrec_getpty ( )
2003-12-30 22:30:32 +01:00
{
2004-06-18 20:04:36 +02:00
# ifdef HAVE_OPENPTY
2009-10-17 22:26:56 +02:00
if ( openpty ( & master , & slave , NULL , NULL , NULL ) = = - 1 ) {
debug_write ( " cannot openpty " ) ;
graceful_exit ( 62 ) ;
}
2004-01-02 21:47:53 +01:00
# else
2009-10-17 22:26:56 +02:00
if ( ( master = open ( " /dev/ptmx " , O_RDWR ) ) < 0 ) {
debug_write ( " cannot open /dev/ptmx " ) ;
graceful_exit ( 62 ) ;
}
2004-02-20 18:57:29 +01:00
grantpt ( master ) ;
unlockpt ( master ) ;
if ( ( slave = open ( ( const char * ) ptsname ( master ) , O_RDWR ) ) < 0 )
{
2009-10-17 22:26:56 +02:00
debug_write ( " cannot open master ptsname " ) ;
2004-02-20 18:57:29 +01:00
graceful_exit ( 65 ) ;
}
# endif
ioctl ( slave , TIOCSWINSZ , ( char * ) & win ) ;
tcsetattr ( slave , TCSANOW , & tt ) ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2004-01-25 23:34:35 +01:00
char *
2003-12-30 22:30:32 +01:00
gen_ttyrec_filename ( )
{
2003-12-31 20:47:49 +01:00
time_t rawtime ;
struct tm * ptm ;
2004-01-25 23:34:35 +01:00
char * ttyrec_filename = calloc ( 100 , sizeof ( char ) ) ;
2003-12-31 20:47:49 +01:00
/* append time to filename */
time ( & rawtime ) ;
ptm = gmtime ( & rawtime ) ;
snprintf ( ttyrec_filename , 100 , " %04i-%02i-%02i.%02i:%02i:%02i.ttyrec " ,
ptm - > tm_year + 1900 , ptm - > tm_mon + 1 , ptm - > tm_mday ,
ptm - > tm_hour , ptm - > tm_min , ptm - > tm_sec ) ;
2004-01-25 23:34:35 +01:00
return ttyrec_filename ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2004-04-21 18:22:55 +02:00
char *
gen_nhext_filename ( )
{
time_t rawtime ;
struct tm * ptm ;
char * nhext_filename = calloc ( 100 , sizeof ( char ) ) ;
/* append time to filename */
time ( & rawtime ) ;
ptm = gmtime ( & rawtime ) ;
snprintf ( nhext_filename , 100 , " %04i-%02i-%02i.%02i:%02i:%02i.nhext " ,
ptm - > tm_year + 1900 , ptm - > tm_mon + 1 , ptm - > tm_mday ,
ptm - > tm_hour , ptm - > tm_min , ptm - > tm_sec ) ;
return nhext_filename ;
}
/* ************************************************************* */
2004-01-28 17:31:37 +01:00
char *
2007-03-29 22:14:55 +02:00
gen_inprogress_lock ( int game , pid_t pid , char * ttyrec_filename )
2003-12-30 22:30:32 +01:00
{
2004-03-04 14:58:03 +01:00
char * lockfile = NULL , filebuf [ 80 ] ;
2003-12-31 20:47:49 +01:00
int fd ;
2004-01-28 17:31:37 +01:00
size_t len ;
2004-01-30 18:32:12 +01:00
struct flock fl = { 0 } ;
2004-01-04 01:59:48 +01:00
2004-03-04 14:58:03 +01:00
snprintf ( filebuf , sizeof ( filebuf ) , " %d \n %d \n %d \n " ,
pid , win . ws_row , win . ws_col ) ;
2004-01-04 03:19:12 +01:00
2004-01-30 18:32:12 +01:00
fl . l_type = F_WRLCK ;
fl . l_whence = SEEK_SET ;
fl . l_start = 0 ;
fl . l_len = 0 ;
2009-10-17 22:26:56 +02:00
len = strlen ( dgl_format_str ( game , me , myconfig [ game ] - > inprogressdir , NULL ) ) + strlen ( me - > username ) + strlen ( ttyrec_filename ) + 13 ;
2004-01-28 17:31:37 +01:00
lockfile = calloc ( len , sizeof ( char ) ) ;
2009-10-17 19:34:36 +02:00
2009-10-17 22:26:56 +02:00
snprintf ( lockfile , len , " %s%s:%s " , dgl_format_str ( game , me , myconfig [ game ] - > inprogressdir , NULL ) ,
2003-12-31 20:47:49 +01:00
me - > username , ttyrec_filename ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
fd = open ( lockfile , O_WRONLY | O_CREAT , 0644 ) ;
2009-10-17 22:26:56 +02:00
if ( fcntl ( fd , F_SETLKW , & fl ) = = - 1 ) {
debug_write ( " cannot fnctl inprogress-lock " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 68 ) ;
2009-10-17 22:26:56 +02:00
}
2004-01-04 03:03:26 +01:00
2004-03-04 14:58:03 +01:00
write ( fd , filebuf , strlen ( filebuf ) ) ;
2004-01-28 17:31:37 +01:00
return lockfile ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2010-05-06 18:01:08 +02:00
# ifdef USE_SHMEM
int hup_shm_idx = - 1 ;
char * hup_shm_ttyrec_fn = NULL ;
# endif
2003-12-30 22:30:32 +01:00
void
2004-01-02 07:14:34 +01:00
catch_sighup ( int signum )
2003-12-30 22:30:32 +01:00
{
2004-01-25 23:34:35 +01:00
if ( child )
2003-12-31 20:47:49 +01:00
{
sleep ( 10 ) ;
2004-01-25 23:34:35 +01:00
kill ( child , SIGHUP ) ;
2003-12-31 20:47:49 +01:00
sleep ( 5 ) ;
}
2010-05-06 18:01:08 +02:00
# ifdef USE_SHMEM
if ( hup_shm_idx ! = - 1 ) {
struct dg_shm * shm_dg_data = NULL ;
struct dg_shm_game * shm_dg_game = NULL ;
shm_init ( & shm_dg_data , & shm_dg_game ) ;
shm_sem_wait ( shm_dg_data ) ;
if ( shm_dg_game [ hup_shm_idx ] . in_use & &
! strcmp ( shm_dg_game [ hup_shm_idx ] . ttyrec_fn , hup_shm_ttyrec_fn ) & &
( shm_dg_game [ hup_shm_idx ] . nwatchers > 0 ) ) {
shm_dg_game [ hup_shm_idx ] . nwatchers - - ;
}
shm_sem_post ( shm_dg_data ) ;
hup_shm_idx = - 1 ;
free ( hup_shm_ttyrec_fn ) ;
}
# endif
2009-10-17 22:26:56 +02:00
debug_write ( " catchup sighup " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 2 ) ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2010-03-02 19:32:57 +01:00
int
dgl_getch ( void )
{
const int c = getch ( ) ;
idle_alarm_reset ( ) ;
return c ;
}
/* ************************************************************* */
static void
dgl_idle_kill ( int signal )
{
kill ( 0 , SIGHUP ) ;
}
void
idle_alarm_set_enabled ( int enabled )
{
signal ( SIGALRM , SIG_IGN ) ;
g_idle_alarm_enabled = enabled ;
idle_alarm_reset ( ) ;
if ( enabled )
signal ( SIGALRM , dgl_idle_kill ) ;
}
void
idle_alarm_reset ( void )
{
if ( g_idle_alarm_enabled & & globalconfig . menu_max_idle_time > 0 )
alarm ( globalconfig . menu_max_idle_time ) ;
}
/* ************************************************************* */
2008-04-05 15:29:19 +02:00
char *
bannerstrmangle ( char * buf , char * fromstr , char * tostr )
{
static char bufnew [ 81 ] ;
char * loc ;
char * b = buf ;
memset ( bufnew , 0 , 80 ) ;
if ( strstr ( b , fromstr ) ) {
int i = 0 ;
while ( ( loc = strstr ( b , fromstr ) ) ! = NULL ) {
for ( ; i < 80 ; i + + ) {
if ( loc ! = b )
bufnew [ i ] = * ( b + + ) ;
else {
strlcat ( bufnew , tostr , 80 ) ;
b + = strlen ( fromstr ) ;
i + = strlen ( tostr ) ;
break ;
}
if ( strlen ( b ) = = 0 )
break ;
}
}
if ( * b )
strlcat ( bufnew , b , 80 ) ;
} else strncpy ( bufnew , buf , 80 ) ;
return bufnew ;
}
2010-05-03 19:54:13 +02:00
void
freebanner ( struct dg_banner * ban )
{
unsigned int l ;
if ( ! ban ) return ;
l = ban - > len ;
while ( l > 0 ) {
l - - ;
free ( ban - > lines [ l ] ) ;
}
free ( ban - > lines ) ;
ban - > len = 0 ;
ban - > lines = NULL ;
}
void
banner_addline ( struct dg_banner * ban , char * line )
{
size_t len = strlen ( line ) ;
if ( ! ban ) return ;
ban - > len + + ;
ban - > lines = realloc ( ban - > lines , sizeof ( char * ) * ban - > len ) ;
if ( len > = 80 ) {
len = 80 ;
ban - > lines [ ban - > len - 1 ] = malloc ( len ) ;
strncpy ( ban - > lines [ ban - > len - 1 ] , line , len ) ;
ban - > lines [ ban - > len - 1 ] [ len - 1 ] = ' \0 ' ;
} else
ban - > lines [ ban - > len - 1 ] = strdup ( line ) ;
}
2003-12-31 20:47:49 +01:00
void
2008-04-05 15:29:19 +02:00
loadbanner ( char * fname , struct dg_banner * ban )
2003-12-31 20:47:49 +01:00
{
2003-12-31 21:21:00 +01:00
FILE * bannerfile ;
2003-12-31 20:47:49 +01:00
char buf [ 80 ] ;
2010-05-03 19:54:13 +02:00
if ( ban - > len > 23 ) return ;
2003-12-31 20:47:49 +01:00
memset ( buf , 0 , 80 ) ;
2008-04-05 15:29:19 +02:00
bannerfile = fopen ( fname , " r " ) ;
2003-12-31 20:47:49 +01:00
2003-12-31 21:21:00 +01:00
if ( ! bannerfile )
2003-12-31 20:47:49 +01:00
{
2010-05-03 19:54:13 +02:00
if ( ban - > len = = 0 )
banner_addline ( ban , " ### dgamelaunch " PACKAGE_VERSION " - network console game launcher " ) ;
snprintf ( buf , 80 , " ### NOTE: administrator has not installed a %s file " , fname ) ;
banner_addline ( ban , buf ) ;
return ;
2003-12-31 20:47:49 +01:00
}
2003-12-31 21:21:00 +01:00
while ( fgets ( buf , 80 , bannerfile ) ! = NULL )
2003-12-31 20:47:49 +01:00
{
2004-01-06 03:08:53 +01:00
char bufnew [ 80 ] ;
2008-04-06 13:35:26 +02:00
int slen ;
2008-04-05 15:29:19 +02:00
2004-01-06 03:08:53 +01:00
memset ( bufnew , 0 , 80 ) ;
2003-12-31 20:47:49 +01:00
2008-04-06 13:35:26 +02:00
slen = strlen ( buf ) ;
if ( ( slen > 0 ) & & ( buf [ slen - 1 ] = = ' \n ' ) ) buf [ slen - 1 ] = ' \0 ' ;
2008-04-05 15:29:19 +02:00
strncpy ( bufnew , buf , 80 ) ;
2010-05-03 19:54:13 +02:00
if ( strstr ( bufnew , " $INCLUDE( " ) ) {
char * fn = bufnew + 9 ;
char * fn_end = strchr ( fn , ' ) ' ) ;
if ( fn_end ) {
* fn_end = ' \0 ' ;
if ( strcmp ( fname , fn ) ) {
banner_addline ( ban , fn ) ;
loadbanner ( fn , ban ) ;
}
}
2008-04-06 13:21:29 +02:00
} else {
2010-05-03 19:54:13 +02:00
strncpy ( bufnew , bannerstrmangle ( bufnew , " $VERSION " , PACKAGE_STRING ) , 80 ) ;
strncpy ( bufnew , bannerstrmangle ( bufnew , " $SERVERID " , globalconfig . server_id ? globalconfig . server_id : " " ) , 80 ) ;
if ( me & & loggedin ) {
strncpy ( bufnew , bannerstrmangle ( bufnew , " $USERNAME " , me - > username ) , 80 ) ;
} else {
strncpy ( bufnew , bannerstrmangle ( bufnew , " $USERNAME " , " [Anonymous] " ) , 80 ) ;
}
banner_addline ( ban , bufnew ) ;
2004-01-06 03:08:53 +01:00
}
2003-12-31 20:47:49 +01:00
memset ( buf , 0 , 80 ) ;
2004-01-01 03:06:19 +01:00
2010-05-03 19:54:13 +02:00
if ( ban - > len > = 24 )
2008-04-05 15:29:19 +02:00
break ;
2004-01-06 06:03:30 +01:00
}
2004-01-01 03:06:19 +01:00
fclose ( bannerfile ) ;
2003-12-31 20:47:49 +01:00
}
void
2008-04-05 15:29:19 +02:00
drawbanner ( struct dg_banner * ban , unsigned int start_line , unsigned int howmany )
2003-12-31 20:47:49 +01:00
{
unsigned int i ;
2008-04-05 15:29:19 +02:00
if ( ! ban ) return ;
2003-12-31 20:47:49 +01:00
2008-04-05 15:29:19 +02:00
if ( howmany > ban - > len | | howmany = = 0 )
howmany = ban - > len ;
2003-12-31 20:47:49 +01:00
for ( i = 0 ; i < howmany ; i + + )
2008-04-05 15:29:19 +02:00
mvaddstr ( start_line + i , 1 , ban - > lines [ i ] ) ;
2003-12-31 20:47:49 +01:00
}
2010-05-01 16:41:54 +02:00
void
shm_sem_wait ( struct dg_shm * shm_dg_data )
{
# ifdef USE_SHMEM
if ( sem_wait ( & ( shm_dg_data - > dg_sem ) ) = = - 1 ) {
debug_write ( " sem_wait " ) ;
graceful_exit ( 77 ) ;
}
# endif
}
void
shm_sem_post ( struct dg_shm * shm_dg_data )
{
# ifdef USE_SHMEM
if ( sem_post ( & ( shm_dg_data - > dg_sem ) ) = = - 1 ) {
debug_write ( " sem_post " ) ;
graceful_exit ( 78 ) ;
}
# endif
}
void
shm_update ( struct dg_shm * shm_dg_data , struct dg_game * * games , int len )
{
# ifdef USE_SHMEM
int di , i ;
struct dg_shm_game * shm_dg_game = ( struct dg_shm_game * ) ( shm_dg_data + sizeof ( struct dg_shm ) ) ;
shm_sem_wait ( shm_dg_data ) ;
for ( di = 0 ; di < shm_dg_data - > max_n_games ; di + + )
if ( shm_dg_game [ di ] . in_use ) {
int delgame = 1 ;
for ( i = 0 ; i < len ; i + + ) {
if ( ! strcmp ( games [ i ] - > ttyrec_fn , shm_dg_game [ di ] . ttyrec_fn ) ) {
delgame = 0 ;
games [ i ] - > is_in_shm = 1 ;
games [ i ] - > shm_idx = di ;
games [ i ] - > nwatchers = shm_dg_game [ di ] . nwatchers ;
break ;
}
}
if ( delgame ) {
shm_dg_game [ di ] . in_use = 0 ;
if ( shm_dg_data - > cur_n_games > 0 ) shm_dg_data - > cur_n_games - - ;
}
}
if ( shm_dg_data - > cur_n_games < shm_dg_data - > max_n_games ) {
for ( i = 0 ; i < len ; i + + )
if ( ! games [ i ] - > is_in_shm ) {
for ( di = 0 ; di < shm_dg_data - > max_n_games ; di + + )
if ( ! shm_dg_game [ di ] . in_use ) {
shm_dg_game [ di ] . in_use = 1 ;
shm_dg_game [ di ] . nwatchers = 0 ;
games [ i ] - > nwatchers = 0 ;
games [ i ] - > is_in_shm = 1 ;
games [ i ] - > shm_idx = di ;
shm_dg_data - > cur_n_games + + ;
strncpy ( shm_dg_game [ di ] . ttyrec_fn , games [ i ] - > ttyrec_fn , 150 ) ;
break ;
}
}
}
shm_sem_post ( shm_dg_data ) ;
# endif
}
void
shm_mk_keys ( key_t * shm_key , key_t * shm_sem_key )
{
# ifdef USE_SHMEM
if ( ( * shm_key = ftok ( " dgamelaunch " , ' R ' ) ) = = - 1 ) {
debug_write ( " ftok shm_key " ) ;
graceful_exit ( 71 ) ;
}
if ( ( * shm_sem_key = ftok ( " dgamelaunch " , ' S ' ) ) = = - 1 ) {
debug_write ( " ftok shm_sem_key " ) ;
graceful_exit ( 72 ) ;
}
# endif
}
void
shm_init ( struct dg_shm * * shm_dg_data , struct dg_shm_game * * shm_dg_game )
{
# ifdef USE_SHMEM
key_t shm_key ;
key_t shm_sem_key ;
int shm_id ;
int shm_size ;
void * shm_data = NULL ;
int shm_data_existed = 0 ;
shm_mk_keys ( & shm_key , & shm_sem_key ) ;
/* max. shm_n_games simultaneous games recorded in the shared memory */
shm_size = sizeof ( struct dg_shm ) + shm_n_games * sizeof ( struct dg_shm_game ) ;
/* connect to (and possibly create) the segment */
if ( ( shm_id = shmget ( shm_key , shm_size , 0644 | IPC_CREAT | IPC_EXCL ) ) = = - 1 ) {
/* creation failed, so it already exists. attach to it */
shm_data_existed = 1 ;
if ( ( shm_id = shmget ( shm_key , shm_size , 0644 ) ) = = - 1 ) {
debug_write ( " shmget " ) ;
graceful_exit ( 73 ) ;
}
}
/* attach to the segment to get a pointer to it: */
shm_data = shmat ( shm_id , ( void * ) 0 , 0 ) ;
if ( shm_data = = ( char * ) ( - 1 ) ) {
debug_write ( " shmat " ) ;
graceful_exit ( 74 ) ;
}
if ( ! shm_data ) {
debug_write ( " shm_data == null " ) ;
graceful_exit ( 75 ) ;
}
( * shm_dg_data ) = ( struct dg_shm * ) shm_data ;
2010-05-02 10:34:19 +02:00
( * shm_dg_game ) = ( struct dg_shm_game * ) ( ( * shm_dg_data ) + sizeof ( struct dg_shm ) ) ;
2010-05-01 16:41:54 +02:00
if ( ! shm_data_existed & & shm_data ) {
memset ( * shm_dg_game , 0 , shm_n_games * sizeof ( struct dg_shm_game ) ) ;
( * shm_dg_data ) - > max_n_games = shm_n_games ;
( * shm_dg_data ) - > cur_n_games = 0 ;
if ( sem_init ( & ( ( * shm_dg_data ) - > dg_sem ) , 1 , 1 ) = = - 1 ) {
debug_write ( " sem_init " ) ;
graceful_exit ( 76 ) ;
}
}
# endif /* USE_SHMEM */
}
2004-01-02 05:35:46 +01:00
void
2007-03-29 22:14:55 +02:00
inprogressmenu ( int gameid )
2004-01-02 05:35:46 +01:00
{
2009-10-18 10:29:33 +02:00
const char * selectorchars = " abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPRSTUVWXYZ " ;
2009-10-18 20:24:22 +02:00
int i , menuchoice , len = 20 , offset = 0 ;
2008-04-06 11:13:50 +02:00
static dg_sortmode sortmode = NUM_SORTMODES ;
2009-10-18 10:39:19 +02:00
struct dg_game * * games = NULL ;
2010-05-01 16:41:54 +02:00
char ttyrecname [ 130 ] , gametype [ 10 ] , idletime [ 10 ] ;
2009-10-18 10:29:33 +02:00
int * is_nhext ;
2004-03-04 15:38:02 +01:00
sigset_t oldmask , toblock ;
2009-10-18 00:40:45 +02:00
int idx = - 1 ;
2010-05-01 16:41:54 +02:00
int shm_idx = - 1 ;
2009-10-18 02:17:50 +02:00
int max_height = - 1 ;
2009-10-18 03:03:27 +02:00
int selected = - 1 ;
2009-10-18 20:24:22 +02:00
int resizex = - 1 ;
int resizey = - 1 ;
2009-10-18 16:29:46 +02:00
char * selectedgame = NULL ;
2009-10-18 10:29:33 +02:00
int abs_max_height ;
2009-10-18 12:31:45 +02:00
int top_banner_hei = 5 ;
int btm_banner_hei = 3 ;
2009-10-18 11:19:49 +02:00
int btm ;
2003-12-31 20:47:49 +01:00
2009-10-18 12:31:45 +02:00
int title_attr = A_STANDOUT ;
int selected_attr = A_BOLD ;
2009-10-18 19:09:27 +02:00
int require_enter = 0 ; /* TODO: make configurable */
2010-05-01 16:41:54 +02:00
int di ;
2010-05-03 21:15:09 +02:00
struct dg_watchcols {
int dat ;
int sortmode ;
int x ;
char * colname ;
char * fmt ;
} watchcols [ ] = {
{ 0 , SORTMODE_NONE , 1 , " " , " %s) " } ,
{ 1 , SORTMODE_USERNAME , 4 , " Username " , " %-15s " } ,
{ 2 , SORTMODE_GAMENUM , 21 , " Game " , " %-5s " } ,
2010-05-04 16:54:07 +02:00
{ 3 , SORTMODE_WINDOWSIZE , 28 , " Size " , " %s " } ,
2010-05-03 21:15:09 +02:00
{ 4 , SORTMODE_STARTTIME , 37 , " Start date & time " , " %s " } ,
{ 5 , SORTMODE_IDLETIME , 58 , " Idle time " , " %-10s " } ,
# ifdef USE_SHMEM
{ 6 , SORTMODE_WATCHERS , 70 , " Watchers " , " %s " } ,
# endif
} ;
2010-05-01 16:41:54 +02:00
struct dg_shm * shm_dg_data = NULL ;
struct dg_shm_game * shm_dg_game = NULL ;
2008-04-06 11:13:50 +02:00
if ( sortmode = = NUM_SORTMODES )
sortmode = globalconfig . sortmode ;
2009-10-18 10:29:33 +02:00
abs_max_height = strlen ( selectorchars ) ;
is_nhext = ( int * ) calloc ( abs_max_height + 1 , sizeof ( int ) ) ;
if ( ! is_nhext ) {
debug_write ( " could not calloc is_nhext " ) ;
graceful_exit ( 70 ) ;
}
2010-05-01 16:41:54 +02:00
shm_init ( & shm_dg_data , & shm_dg_game ) ;
2009-10-18 21:15:46 +02:00
games = populate_games ( gameid , & len , NULL ) ; /* FIXME: should be 'me' instead of 'NULL' */
2010-05-01 16:41:54 +02:00
shm_update ( shm_dg_data , games , len ) ;
2007-12-24 19:09:15 +01:00
games = sort_games ( games , len , sortmode ) ;
2003-12-31 20:47:49 +01:00
2004-01-02 05:35:46 +01:00
while ( 1 )
2003-12-31 20:47:49 +01:00
{
2009-10-18 02:17:50 +02:00
term_resize_check ( ) ;
2009-10-18 15:57:12 +02:00
max_height = dgl_local_LINES - ( top_banner_hei + btm_banner_hei ) - 1 ;
2009-10-18 10:29:33 +02:00
if ( max_height < 2 ) {
free ( is_nhext ) ;
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2009-10-18 10:29:33 +02:00
return ;
}
if ( max_height > abs_max_height ) max_height = abs_max_height ;
2009-10-18 02:17:50 +02:00
2004-03-12 17:24:18 +01:00
if ( len = = 0 )
offset = 0 ;
2004-03-21 17:53:07 +01:00
erase ( ) ;
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2009-10-18 12:31:45 +02:00
2009-10-18 15:03:22 +02:00
if ( len > 0 ) {
mvaddstr ( 3 , 1 , " The following games are in progress: " ) ;
2010-05-03 21:15:09 +02:00
for ( di = 0 ; di < ARRAY_SIZE ( watchcols ) ; di + + ) {
2010-05-04 16:54:07 +02:00
char * col = watchcols [ di ] . colname ;
int x = watchcols [ di ] . x ;
while ( * col = = ' ' ) { x + + ; col + + ; }
2010-05-03 21:15:09 +02:00
if ( sortmode = = watchcols [ di ] . sortmode ) attron ( title_attr ) ;
2010-05-04 16:54:07 +02:00
mvprintw ( top_banner_hei , x , col ) ;
2010-05-03 21:15:09 +02:00
if ( sortmode = = watchcols [ di ] . sortmode ) attroff ( title_attr ) ;
}
2009-10-18 15:03:22 +02:00
}
2009-10-18 12:31:45 +02:00
2010-05-01 16:41:54 +02:00
shm_sem_wait ( shm_dg_data ) ;
2009-10-18 02:17:50 +02:00
for ( i = 0 ; i < max_height ; i + + )
2003-12-31 20:47:49 +01:00
{
2004-01-02 05:35:46 +01:00
if ( i + offset > = len )
break ;
2009-10-18 12:31:45 +02:00
if ( i + offset = = selected ) attron ( selected_attr ) ;
2009-10-18 03:03:27 +02:00
2004-04-21 18:22:55 +02:00
is_nhext [ i ] = ! strcmp ( games [ i + offset ] - > ttyrec_fn + strlen ( games [ i + offset ] - > ttyrec_fn ) - 6 , " .nhext " ) ;
if ( is_nhext [ i ] )
strcpy ( gametype , " NhExt " ) ;
else
snprintf ( gametype , sizeof gametype , " %3dx%3d " ,
games [ i + offset ] - > ws_col , games [ i + offset ] - > ws_row ) ;
2010-05-01 16:41:54 +02:00
{
time_t ctime ;
2010-05-01 17:30:04 +02:00
long secs , mins , hours ;
2010-05-01 16:41:54 +02:00
( void ) time ( & ctime ) ;
2010-05-01 17:30:04 +02:00
secs = ( ctime - games [ i + offset ] - > idle_time ) ;
hours = ( secs / 3600 ) ;
secs - = ( hours * 3600 ) ;
mins = ( secs / 60 ) % 60 ;
secs - = ( mins * 60 ) ;
2010-05-01 16:41:54 +02:00
if ( hours )
snprintf ( idletime , 10 , " %ldh %ldm " , hours , mins ) ;
else
snprintf ( idletime , 10 , " %ldm %lds " , mins , secs ) ;
}
2010-05-03 21:15:09 +02:00
for ( di = 0 ; di < ARRAY_SIZE ( watchcols ) ; di + + ) {
char tmpbuf [ 80 ] ;
switch ( watchcols [ di ] . dat ) {
default : break ;
case 0 : tmpbuf [ 0 ] = selectorchars [ i ] ; tmpbuf [ 1 ] = ' \0 ' ; break ;
case 1 : snprintf ( tmpbuf , 80 , " %s " , games [ i + offset ] - > name ) ; break ;
case 2 : snprintf ( tmpbuf , 80 , " %s " , myconfig [ games [ i + offset ] - > gamenum ] - > shortname ) ; break ;
case 3 : snprintf ( tmpbuf , 80 , " %s " , gametype ) ; break ;
case 4 : snprintf ( tmpbuf , 80 , " %s %s " , games [ i + offset ] - > date , games [ i + offset ] - > time ) ; break ;
case 5 : snprintf ( tmpbuf , 80 , " %s " , idletime ) ; break ;
2010-05-01 16:41:54 +02:00
# ifdef USE_SHMEM
2010-05-03 21:15:09 +02:00
case 6 : snprintf ( tmpbuf , 80 , " %li " , ( games [ i + offset ] - > is_in_shm ? shm_dg_game [ games [ i + offset ] - > shm_idx ] . nwatchers : - 1 ) ) ; break ;
2010-05-01 16:41:54 +02:00
# endif
2010-05-03 21:15:09 +02:00
}
tmpbuf [ 79 ] = ' \0 ' ;
mvprintw ( top_banner_hei + 1 + i , watchcols [ di ] . x , watchcols [ di ] . fmt , tmpbuf ) ;
}
2009-10-18 03:03:27 +02:00
2009-10-18 12:31:45 +02:00
if ( i + offset = = selected ) attroff ( selected_attr ) ;
2009-10-18 03:03:27 +02:00
2003-12-31 20:47:49 +01:00
}
2010-05-01 16:41:54 +02:00
shm_sem_post ( shm_dg_data ) ;
2009-10-18 15:57:12 +02:00
btm = dgl_local_LINES - btm_banner_hei - top_banner_hei ;
2010-05-03 18:27:42 +02:00
if ( len < = max_height )
btm = i + 1 ;
2009-10-18 11:19:49 +02:00
if ( len > 0 ) {
2010-05-03 18:17:28 +02:00
mvprintw ( ( btm + top_banner_hei ) , 1 , " (%d-%d of %d) " , offset + 1 , offset + i , len ) ;
2009-10-18 15:03:22 +02:00
mvaddstr ( ( btm + 2 + top_banner_hei ) , 1 , " Watch which game? ('?' for help) => " ) ;
} else {
mvprintw ( top_banner_hei , 4 , " Sorry, no games available for viewing. " ) ;
mvaddstr ( ( btm + 2 + top_banner_hei ) , 1 , " Press 'q' to return, or '?' for help => " ) ;
2009-10-18 11:19:49 +02:00
}
2009-10-18 02:17:50 +02:00
2003-12-31 20:47:49 +01:00
refresh ( ) ;
2010-03-02 19:32:57 +01:00
switch ( ( menuchoice = dgl_getch ( ) ) )
2003-12-31 20:47:49 +01:00
{
2009-10-18 15:10:45 +02:00
case ' * ' :
if ( len > 0 ) {
idx = random ( ) % len ;
2009-10-18 15:20:55 +02:00
selected = idx ;
2009-10-18 15:10:45 +02:00
goto watchgame ;
}
break ;
2009-10-18 11:45:42 +02:00
case ' ? ' :
( void ) runmenuloop ( dgl_find_menu ( " watchmenu_help " ) ) ;
break ;
2009-10-18 00:40:45 +02:00
case ' / ' :
{
int match = - 1 ;
2009-10-18 19:52:12 +02:00
int firstmatch = - 1 ;
int nmatches = 0 ;
2009-11-27 19:41:35 +01:00
char findname [ DGL_PLAYERNAMELEN + 1 ] ;
2009-10-18 19:25:18 +02:00
if ( len < = 0 ) break ;
2009-10-18 00:40:45 +02:00
findname [ 0 ] = ' \0 ' ;
2009-10-18 19:21:56 +02:00
mvprintw ( ( btm + 2 + top_banner_hei ) , 1 , " Watch which player? => " ) ; /* stupid... */
mvaddstr ( ( btm + 2 + top_banner_hei ) , 1 , " Watch which player? => " ) ;
2009-11-27 19:41:35 +01:00
if ( ( mygetnstr ( findname , DGL_PLAYERNAMELEN , 1 ) = = OK ) & & ( strlen ( findname ) > 1 ) ) {
2009-10-18 19:52:12 +02:00
int mlen = strlen ( findname ) ;
2009-10-18 00:40:45 +02:00
for ( i = 0 ; i < len ; i + + )
2009-10-18 19:52:12 +02:00
if ( ! strncasecmp ( games [ i ] - > name , findname , mlen ) ) {
if ( firstmatch = = - 1 ) firstmatch = i ;
2009-10-18 00:40:45 +02:00
match = i ;
2009-10-18 19:52:12 +02:00
nmatches + + ;
2009-10-18 00:40:45 +02:00
}
2009-10-18 19:52:12 +02:00
if ( nmatches > 1 )
match = firstmatch ;
2009-10-18 00:40:45 +02:00
if ( match > - 1 ) {
if ( ! strcmp ( games [ match ] - > ttyrec_fn + strlen ( games [ match ] - > ttyrec_fn ) - 6 , " .nhext " ) ) break ;
idx = match ;
2009-10-18 15:20:55 +02:00
selected = idx ;
2009-10-18 00:40:45 +02:00
goto watchgame ;
}
}
}
break ;
2004-01-03 04:51:29 +01:00
case ' > ' :
2010-05-03 18:17:28 +02:00
if ( ( offset + max_height ) < len ) offset + = max_height ;
2004-01-02 05:35:46 +01:00
break ;
2004-01-01 20:57:58 +01:00
2004-01-03 04:51:29 +01:00
case ' < ' :
2009-10-18 02:17:50 +02:00
if ( ( offset - max_height ) < 0 )
2009-10-18 04:11:31 +02:00
offset = 0 ;
2004-01-02 05:35:46 +01:00
else
2009-10-18 02:17:50 +02:00
offset - = max_height ;
2004-01-02 05:35:46 +01:00
break ;
2004-01-01 20:57:58 +01:00
2008-01-12 23:29:13 +01:00
case ERR :
2004-03-04 15:38:02 +01:00
case ' q ' : case ' Q ' :
2009-10-18 10:29:33 +02:00
if ( is_nhext ) free ( is_nhext ) ;
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2010-05-01 16:41:54 +02:00
# ifdef USE_SHMEM
shmdt ( shm_dg_data ) ;
# endif
2004-01-02 05:35:46 +01:00
return ;
2004-01-01 03:06:19 +01:00
2009-10-18 03:03:27 +02:00
case ' . ' :
2009-10-21 11:06:44 +02:00
if ( sortmode < ( NUM_SORTMODES - 1 ) ) sortmode + + ; else sortmode = SORTMODE_USERNAME ;
2007-12-24 19:09:15 +01:00
break ;
2009-10-19 22:45:27 +02:00
case ' , ' :
2009-10-21 11:06:44 +02:00
if ( sortmode > SORTMODE_USERNAME ) sortmode - - ; else sortmode = ( NUM_SORTMODES - 1 ) ;
2009-10-19 22:45:27 +02:00
break ;
2004-08-23 14:59:33 +02:00
case 12 : case 18 : /* ^L, ^R */
clear ( ) ;
break ;
2009-10-18 03:03:27 +02:00
case 13 :
case 10 :
case KEY_ENTER :
if ( selected > = 0 & & selected < len ) {
idx = selected ;
goto watchgame ;
2004-03-04 15:38:02 +01:00
}
2009-10-18 03:03:27 +02:00
break ;
2004-04-21 18:22:55 +02:00
2009-10-18 03:03:27 +02:00
default :
2009-10-18 19:25:18 +02:00
if ( strchr ( selectorchars , menuchoice ) & & ( len > 0 ) ) {
2009-10-18 03:03:27 +02:00
int sidx = strchr ( selectorchars , menuchoice ) - selectorchars ;
2009-10-18 04:11:31 +02:00
2009-12-23 19:04:26 +01:00
if ( ( sidx > max_height ) | | ( sidx > = len ) ) {
2009-10-18 04:11:31 +02:00
selected = - 1 ;
break ;
}
2009-10-18 03:03:27 +02:00
if ( is_nhext [ sidx ] ) /* Cannot watch NhExt game */
break ;
2009-10-18 00:40:45 +02:00
2009-10-18 03:03:27 +02:00
idx = sidx + offset ;
2009-10-18 19:09:27 +02:00
if ( require_enter ) {
if ( selected = = idx ) selected = - 1 ;
else selected = idx ;
break ;
} else selected = idx ;
2009-10-18 00:40:45 +02:00
watchgame :
2004-01-02 05:35:46 +01:00
/* valid choice has been made */
2009-10-18 00:40:45 +02:00
chosen_name = strdup ( games [ idx ] - > name ) ;
2009-10-17 19:34:36 +02:00
snprintf ( ttyrecname , 130 , " %s " ,
2009-10-18 00:40:45 +02:00
games [ idx ] - > ttyrec_fn ) ;
2003-12-31 20:47:49 +01:00
2004-01-02 05:35:46 +01:00
clear ( ) ;
refresh ( ) ;
endwin ( ) ;
2010-05-01 16:41:54 +02:00
# ifdef USE_SHMEM
if ( games [ idx ] - > is_in_shm ) {
shm_idx = games [ idx ] - > shm_idx ;
shm_sem_wait ( shm_dg_data ) ;
if ( shm_dg_game [ shm_idx ] . in_use & &
2010-05-02 09:28:46 +02:00
! strcmp ( shm_dg_game [ shm_idx ] . ttyrec_fn , games [ idx ] - > ttyrec_fn ) ) {
2010-05-01 16:41:54 +02:00
shm_dg_game [ shm_idx ] . nwatchers + + ;
2010-05-02 09:28:46 +02:00
games [ idx ] - > nwatchers + + ;
}
2010-05-06 18:01:08 +02:00
hup_shm_idx = shm_idx ;
hup_shm_ttyrec_fn = strdup ( games [ idx ] - > ttyrec_fn ) ;
2010-05-01 16:41:54 +02:00
shm_sem_post ( shm_dg_data ) ;
}
# endif
2009-10-18 20:24:22 +02:00
resizey = games [ idx ] - > ws_row ;
resizex = games [ idx ] - > ws_col ;
2008-01-13 00:15:30 +01:00
if ( loggedin )
setproctitle ( " %s [watching %s] " , me - > username , chosen_name ) ;
else
setproctitle ( " <Anonymous> [watching %s] " , chosen_name ) ;
2009-10-18 20:24:22 +02:00
ttyplay_main ( ttyrecname , 1 , resizex , resizey ) ;
2008-01-13 00:15:30 +01:00
if ( loggedin )
setproctitle ( " %s " , me - > username ) ;
else
setproctitle ( " <Anonymous> " ) ;
2010-05-01 16:41:54 +02:00
# ifdef USE_SHMEM
if ( games [ idx ] - > is_in_shm ) {
2010-05-06 18:01:08 +02:00
hup_shm_idx = - 1 ;
free ( hup_shm_ttyrec_fn ) ;
2010-05-01 16:41:54 +02:00
shm_sem_wait ( shm_dg_data ) ;
if ( shm_dg_game [ shm_idx ] . in_use & &
! strcmp ( shm_dg_game [ shm_idx ] . ttyrec_fn , games [ idx ] - > ttyrec_fn ) & &
2010-05-02 09:28:46 +02:00
( shm_dg_game [ shm_idx ] . nwatchers > 0 ) ) {
2010-05-01 16:41:54 +02:00
shm_dg_game [ shm_idx ] . nwatchers - - ;
2010-05-02 09:28:46 +02:00
games [ idx ] - > nwatchers - - ;
}
2010-05-01 16:41:54 +02:00
shm_sem_post ( shm_dg_data ) ;
}
# endif
2004-01-26 09:29:04 +01:00
initcurses ( ) ;
2004-01-02 05:35:46 +01:00
}
2003-12-31 20:47:49 +01:00
}
2009-10-18 16:29:46 +02:00
if ( selected > = 0 & & selected < len )
selectedgame = strdup ( games [ selected ] - > name ) ;
2009-10-18 21:15:46 +02:00
games = populate_games ( gameid , & len , NULL ) ; /* FIXME: should be 'me' instead of 'NULL' */
2010-05-01 16:41:54 +02:00
shm_update ( shm_dg_data , games , len ) ;
2007-12-24 19:09:15 +01:00
games = sort_games ( games , len , sortmode ) ;
2009-10-18 16:29:46 +02:00
if ( selectedgame ) {
selected = - 1 ;
for ( i = 0 ; i < len ; i + + )
if ( ! strcmp ( games [ i ] - > name , selectedgame ) ) {
selected = i ;
break ;
}
free ( selectedgame ) ;
selectedgame = NULL ;
}
2003-12-31 20:47:49 +01:00
}
2009-10-18 10:29:33 +02:00
if ( is_nhext ) free ( is_nhext ) ;
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2010-05-01 16:41:54 +02:00
# ifdef USE_SHMEM
shmdt ( shm_dg_data ) ;
# endif
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2004-03-06 21:34:27 +01:00
/*
* Check email address , returns 1 if valid , 0 otherwise .
* Doesn ' t recognize addresses with parts in double - quotes .
* Addresses with a colon in them are always rejected .
*/
int
check_email ( char * s )
{
char * atomchars = " !#$%&'*+-/=?^_`{|}~ " " 0123456789 "
" abcdefghijklmnopqrstuvwxyz " " ABCDEFGHIJKLMNOPQRSTUVWXYZ " ;
int f ;
if ( * s = = ' @ ' )
return 0 ;
while ( * s ! = ' \0 ' & & * s ! = ' @ ' )
{
if ( strchr ( atomchars , * s ) = = NULL )
return 0 ;
s + + ;
if ( * s = = ' . ' )
s + + ;
}
if ( * s = = ' \0 ' )
return 0 ;
s + + ;
f = 0 ;
while ( * s ! = ' \0 ' )
{
if ( strchr ( atomchars , * s ) = = NULL )
return 0 ;
s + + ;
if ( * s = = ' . ' )
s + + , f = 1 ;
}
return f ;
}
2004-02-05 20:38:17 +01:00
void
change_email ( )
{
char buf [ 81 ] ;
clear ( ) ;
2004-02-05 20:50:58 +01:00
for ( ; ; )
2004-02-05 20:38:17 +01:00
{
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2004-02-05 20:38:17 +01:00
mvprintw ( 3 , 1 , " Your current email is: %s " , me - > email ) ;
mvaddstr ( 4 , 1 , " Please enter a new one (max 80 chars; blank line aborts) " ) ;
mvaddstr ( 6 , 1 , " => " ) ;
2008-01-12 23:29:13 +01:00
if ( mygetnstr ( buf , 80 , 1 ) ! = OK )
return ;
2004-02-05 20:38:17 +01:00
2007-12-30 10:00:16 +01:00
if ( * buf = = ' \0 ' )
2004-02-05 20:38:17 +01:00
return ;
else if ( ! strcmp ( me - > email , buf ) )
{
clear ( ) ;
mvaddstr ( 8 , 1 , " That's the same one as before. Try again? " ) ;
move ( 1 , 1 ) ;
}
2004-03-06 21:34:27 +01:00
else if ( check_email ( buf ) )
2004-02-05 20:38:17 +01:00
{
mvprintw ( 8 , 1 , " Changing email address to '%s'. Confirm (y/n): " , buf ) ;
2010-03-02 19:32:57 +01:00
if ( dgl_getch ( ) = = ' y ' )
2004-02-05 20:38:17 +01:00
{
free ( me - > email ) ;
me - > email = strdup ( buf ) ;
writefile ( 0 ) ;
return ;
}
else
{
mvaddstr ( 9 , 1 , " No changes made. Press any key to continue... " ) ;
2010-03-02 19:32:57 +01:00
dgl_getch ( ) ;
2004-02-05 20:38:17 +01:00
return ;
}
}
else
{
clear ( ) ;
mvaddstr ( 8 , 1 , " That doesn't look like an email address to me. " ) ;
move ( 1 , 1 ) ;
}
}
}
2004-01-04 13:16:05 +01:00
int
2004-02-13 23:30:59 +01:00
changepw ( int dowrite )
2003-12-30 22:30:32 +01:00
{
2009-11-28 18:53:00 +01:00
char buf [ DGL_PASSWDLEN + 1 ] ;
2003-12-31 20:47:49 +01:00
int error = 2 ;
2004-01-03 04:51:29 +01:00
/* A precondition is that struct `me' exists because we can be not-yet-logged-in. */
2009-10-17 22:26:56 +02:00
if ( ! me ) {
debug_write ( " no 'me' in changepw " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 122 ) ; /* Die. */
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
while ( error )
{
2009-11-28 18:53:00 +01:00
char repeatbuf [ DGL_PASSWDLEN + 1 ] ;
2003-12-31 20:47:49 +01:00
clear ( ) ;
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2003-12-31 20:47:49 +01:00
mvprintw ( 5 , 1 ,
" Please enter a%s password. Remember that this is sent over the net " ,
loggedin ? " new " : " " ) ;
mvaddstr ( 6 , 1 ,
" in plaintext, so make it something new and expect it to be relatively " ) ;
mvaddstr ( 7 , 1 , " insecure. " ) ;
2009-11-28 18:53:00 +01:00
mvprintw ( 8 , 1 ,
" %i character max. No ':' characters. Blank line to abort. " , DGL_PASSWDLEN ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 10 , 1 , " => " ) ;
if ( error = = 1 )
{
mvaddstr ( 15 , 1 , " Sorry, the passwords don't match. Try again. " ) ;
move ( 10 , 4 ) ;
}
refresh ( ) ;
2009-11-28 18:53:00 +01:00
if ( mygetnstr ( buf , DGL_PASSWDLEN , 0 ) ! = OK )
2008-01-12 23:29:13 +01:00
return 0 ;
2003-12-31 20:47:49 +01:00
2007-12-30 10:00:16 +01:00
if ( * buf = = ' \0 ' )
2004-01-04 13:16:05 +01:00
return 0 ;
2003-12-31 20:47:49 +01:00
2009-10-17 22:26:56 +02:00
if ( strchr ( buf , ' : ' ) ! = NULL ) {
debug_write ( " cannot have ':' in passwd " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 112 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
mvaddstr ( 12 , 1 , " And again: " ) ;
mvaddstr ( 13 , 1 , " => " ) ;
2009-11-28 18:53:00 +01:00
if ( mygetnstr ( repeatbuf , DGL_PASSWDLEN , 0 ) ! = OK )
2008-01-12 23:29:13 +01:00
return 0 ;
2003-12-31 20:47:49 +01:00
if ( ! strcmp ( buf , repeatbuf ) )
error = 0 ;
else
error = 1 ;
}
2004-02-05 20:38:17 +01:00
free ( me - > password ) ;
2003-12-31 20:47:49 +01:00
me - > password = strdup ( crypt ( buf , buf ) ) ;
2004-02-13 23:30:59 +01:00
2004-02-13 23:36:17 +01:00
if ( dowrite )
2004-02-13 23:30:59 +01:00
writefile ( 0 ) ;
2004-01-04 13:16:05 +01:00
return 1 ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2008-04-06 10:27:44 +02:00
void
wall_email ( char * from , char * msg )
{
int len , i ;
2009-10-18 10:39:19 +02:00
struct dg_game * * games = NULL ;
2008-04-06 10:27:44 +02:00
char spool_fn [ 1024 + 1 ] ;
FILE * user_spool = NULL ;
struct flock fl = { 0 } ;
fl . l_type = F_WRLCK ;
fl . l_whence = SEEK_SET ;
fl . l_start = 0 ;
fl . l_len = 0 ;
if ( ! from | | ! msg ) return ;
if ( strlen ( from ) < 1 ) {
fprintf ( stderr , " Error: wall: 'from' username is too short! \n " ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " wall: 'from' username too short " ) ;
2008-04-06 10:27:44 +02:00
graceful_exit ( 121 ) ;
}
2010-02-25 18:02:32 +01:00
if ( strlen ( msg ) > = DGL_MAILMSGLEN ) {
2008-04-06 10:27:44 +02:00
fprintf ( stderr , " Error: wall: message too long! \n " ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " wall: message too long " ) ;
2008-04-06 10:27:44 +02:00
graceful_exit ( 120 ) ;
}
2009-10-17 19:34:36 +02:00
games = populate_games ( - 1 , & len , me ) ;
2008-04-06 10:27:44 +02:00
if ( len = = 0 ) {
fprintf ( stderr , " Error: wall: no one's logged in! \n " ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " wall: no people playing " ) ;
2008-04-06 10:27:44 +02:00
graceful_exit ( 118 ) ;
}
for ( i = 0 ; i < len ; i + + ) {
int game = games [ i ] - > gamenum ;
int fnamelen ;
if ( strlen ( myconfig [ game ] - > spool ) < 1 ) continue ;
snprintf ( spool_fn , 1024 , " %s/%s " , myconfig [ game ] - > spool , games [ i ] - > name ) ;
if ( ( user_spool = fopen ( spool_fn , " a " ) ) = = NULL ) continue ;
while ( fcntl ( fileno ( user_spool ) , F_SETLK , & fl ) = = - 1 ) {
if ( errno ! = EAGAIN ) continue ;
sleep ( 1 ) ;
}
fprintf ( user_spool , " %s:%s \n " , from , msg ) ;
fclose ( user_spool ) ;
}
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2008-04-06 10:27:44 +02:00
}
2003-12-30 22:30:32 +01:00
void
domailuser ( char * username )
{
2003-12-31 20:47:49 +01:00
unsigned int len , i ;
2010-02-25 18:02:32 +01:00
char * spool_fn , message [ DGL_MAILMSGLEN + 1 ] ;
2003-12-31 20:47:49 +01:00
FILE * user_spool = NULL ;
time_t now ;
int mail_empty = 1 ;
2007-03-29 22:14:55 +02:00
int game ;
2004-01-30 18:32:12 +01:00
struct flock fl = { 0 } ;
fl . l_type = F_WRLCK ;
fl . l_whence = SEEK_SET ;
fl . l_start = 0 ;
fl . l_len = 0 ;
2003-12-31 20:47:49 +01:00
assert ( loggedin ) ;
2007-03-29 22:14:55 +02:00
game = 0 ; /*TODO: find_curr_player_game(username) */
if ( strlen ( myconfig [ game ] - > spool ) < 1 ) return ;
len = strlen ( myconfig [ game ] - > spool ) + strlen ( username ) + 1 ;
2003-12-31 20:47:49 +01:00
spool_fn = malloc ( len + 1 ) ;
time ( & now ) ;
2007-03-29 22:14:55 +02:00
snprintf ( spool_fn , len + 1 , " %s/%s " , myconfig [ game ] - > spool , username ) ;
2003-12-31 20:47:49 +01:00
/* print the enter your message line */
clear ( ) ;
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2010-02-25 18:02:32 +01:00
mvprintw ( 5 , 1 ,
" Enter your message here. It is to be one line only and %i characters or less. " ,
DGL_MAILMSGLEN ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 7 , 1 , " => " ) ;
2010-02-25 18:02:32 +01:00
if ( mygetnstr ( message , DGL_MAILMSGLEN , 1 ) ! = OK )
2008-01-12 23:29:13 +01:00
return ;
2003-12-31 20:47:49 +01:00
for ( i = 0 ; i < strlen ( message ) ; i + + )
{
if ( message [ i ] ! = ' ' & & message [ i ] ! = ' \n ' & & message [ i ] ! = ' \t ' )
mail_empty = 0 ;
}
if ( mail_empty )
{
2008-01-12 23:51:12 +01:00
mvaddstr ( 9 , 1 , " This scroll appears to be blank. " ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 10 , 1 , " (Aborting your message.) " ) ;
2008-01-12 23:51:12 +01:00
mvaddstr ( 12 , 1 , " --More-- " ) ;
2010-03-02 19:32:57 +01:00
dgl_getch ( ) ;
2003-12-31 20:47:49 +01:00
return ;
}
if ( ( user_spool = fopen ( spool_fn , " a " ) ) = = NULL )
{
mvaddstr ( 9 , 1 ,
2008-01-12 23:51:12 +01:00
" You fall into the water! You sink like a rock. " ) ;
2003-12-31 20:47:49 +01:00
mvprintw ( 10 , 1 ,
2008-01-12 23:51:12 +01:00
" (Couldn't open %s'%c spool file. Aborting.) " ,
2003-12-31 20:47:49 +01:00
username , ( username [ strlen ( username ) - 1 ] ! = ' s ' ) ? ' s ' : 0 ) ;
2008-01-12 23:51:12 +01:00
mvaddstr ( 12 , 1 , " --More-- " ) ;
2010-03-02 19:32:57 +01:00
dgl_getch ( ) ;
2003-12-31 20:47:49 +01:00
return ;
}
2008-01-12 23:51:12 +01:00
mvaddstr ( 9 , 1 , " Sending your scroll... " ) ;
2003-12-31 20:47:49 +01:00
refresh ( ) ;
2008-01-12 23:51:12 +01:00
/* Getting a lock on the mailspool... */
2004-01-04 01:21:39 +01:00
while ( fcntl ( fileno ( user_spool ) , F_SETLK , & fl ) = = - 1 )
{
2004-01-04 03:19:12 +01:00
if ( errno ! = EAGAIN )
{
mvaddstr ( 10 , 1 ,
2008-01-12 23:51:12 +01:00
" (Received a weird error from fcntl. Aborting.) " ) ;
mvaddstr ( 12 , 1 , " --More-- " ) ;
2010-03-02 19:32:57 +01:00
dgl_getch ( ) ;
2004-01-04 03:19:12 +01:00
return ;
}
sleep ( 1 ) ;
2004-01-04 01:21:39 +01:00
}
2003-12-31 20:47:49 +01:00
fprintf ( user_spool , " %s:%s \n " , me - > username , message ) ;
2004-01-06 14:35:38 +01:00
/*
* Don ' t unlock the file ourselves , this way it will be done automatically
* after all data has been written . ( Using file locking with stdio is icky . )
*/
2003-12-31 20:47:49 +01:00
fclose ( user_spool ) ;
2008-01-12 23:51:12 +01:00
mvaddstr ( 9 , 1 , " Scroll delivered! " ) ;
move ( 9 , 19 ) ; /* Pedantry! */
2004-01-06 14:35:38 +01:00
refresh ( ) ;
sleep ( 2 ) ;
2003-12-31 20:47:49 +01:00
return ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
void
freefile ( )
{
2007-12-27 20:52:48 +01:00
# ifndef USE_SQLITE3
2003-12-31 20:47:49 +01:00
int i ;
/* free existing mem, clear existing entries */
for ( i = 0 ; i < f_num ; i + + )
{
2004-01-26 09:29:04 +01:00
if ( users [ i ] ! = me )
{
free ( users [ i ] - > password ) ;
free ( users [ i ] - > username ) ;
free ( users [ i ] - > email ) ;
free ( users [ i ] - > env ) ;
free ( users [ i ] ) ;
}
2003-12-31 20:47:49 +01:00
}
if ( users )
free ( users ) ;
users = NULL ;
f_num = 0 ;
2007-12-27 20:52:48 +01:00
# endif
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
void
2004-01-26 09:29:04 +01:00
initcurses ( )
2003-12-30 22:30:32 +01:00
{
2003-12-31 20:47:49 +01:00
initscr ( ) ;
cbreak ( ) ;
2004-01-19 12:58:31 +01:00
noecho ( ) ;
2003-12-31 20:47:49 +01:00
nonl ( ) ;
intrflush ( stdscr , FALSE ) ;
keypad ( stdscr , TRUE ) ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2004-06-12 02:11:18 +02:00
void
autologin ( char * user , char * pass )
{
2007-12-27 20:52:48 +01:00
struct dg_user * tmp ;
tmp = userexist ( user , 0 ) ;
if ( tmp ) {
me = cpy_me ( tmp ) ;
if ( passwordgood ( pass ) ) {
loggedin = 1 ;
setproctitle ( " %s " , me - > username ) ;
2008-01-01 18:03:05 +01:00
dgl_exec_cmdqueue ( globalconfig . cmdqueue [ DGLTIME_LOGIN ] , 0 , me ) ;
2007-12-27 20:52:48 +01:00
}
}
2004-06-12 02:11:18 +02:00
}
2003-12-30 22:30:32 +01:00
void
2004-01-31 04:04:58 +01:00
loginprompt ( int from_ttyplay )
2003-12-30 22:30:32 +01:00
{
2009-11-28 18:53:00 +01:00
char user_buf [ DGL_PLAYERNAMELEN + 1 ] , pw_buf [ DGL_PASSWDLEN + 2 ] ;
2007-12-30 09:29:28 +01:00
int error = 2 ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
loggedin = 0 ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
while ( error )
{
clear ( ) ;
2003-12-30 22:30:32 +01:00
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2003-12-30 22:30:32 +01:00
2004-01-31 04:04:58 +01:00
if ( from_ttyplay = = 1 )
mvaddstr ( 4 , 1 , " This operation requires you to be logged in. " ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 5 , 1 ,
2004-01-31 04:04:58 +01:00
" Please enter your username. (blank entry aborts) " ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 7 , 1 , " => " ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
if ( error = = 1 )
{
mvaddstr ( 9 , 1 , " There was a problem with your last entry. " ) ;
move ( 7 , 4 ) ;
}
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
refresh ( ) ;
2003-12-30 22:30:32 +01:00
2009-11-27 19:41:35 +01:00
if ( mygetnstr ( user_buf , DGL_PLAYERNAMELEN , 1 ) ! = OK )
2008-01-12 23:29:13 +01:00
return ;
2003-12-30 22:30:32 +01:00
2007-12-30 10:00:16 +01:00
if ( * user_buf = = ' \0 ' )
2003-12-31 20:47:49 +01:00
return ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
error = 1 ;
2003-12-30 22:30:32 +01:00
2007-12-27 20:52:48 +01:00
{
struct dg_user * tmpme ;
if ( ( tmpme = userexist ( user_buf , 0 ) ) ) {
me = cpy_me ( tmpme ) ;
error = 0 ;
}
}
2003-12-31 20:47:49 +01:00
}
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
clear ( ) ;
2003-12-30 22:30:32 +01:00
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
mvaddstr ( 5 , 1 , " Please enter your password. " ) ;
mvaddstr ( 7 , 1 , " => " ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
refresh ( ) ;
2003-12-30 22:30:32 +01:00
2009-11-28 18:53:00 +01:00
if ( mygetnstr ( pw_buf , DGL_PASSWDLEN , 0 ) ! = OK )
2008-01-12 23:29:13 +01:00
return ;
2003-12-30 22:30:32 +01:00
2004-01-02 22:00:54 +01:00
if ( passwordgood ( pw_buf ) )
2003-12-31 20:47:49 +01:00
{
loggedin = 1 ;
2008-01-13 00:15:30 +01:00
if ( from_ttyplay )
setproctitle ( " %s [watching %s] " , me - > username , chosen_name ) ;
else
setproctitle ( " %s " , me - > username ) ;
2008-01-01 18:03:05 +01:00
dgl_exec_cmdqueue ( globalconfig . cmdqueue [ DGLTIME_LOGIN ] , 0 , me ) ;
2003-12-31 20:47:49 +01:00
}
2004-04-22 17:04:15 +02:00
else
2004-01-31 04:10:03 +01:00
{
2004-04-22 17:04:15 +02:00
me = NULL ;
if ( from_ttyplay = = 1 )
{
mvaddstr ( 9 , 1 , " Login failed. Returning to game. " ) ;
refresh ( ) ;
sleep ( 2 ) ;
}
}
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
void
newuser ( )
{
2004-02-03 00:28:17 +01:00
char buf [ 1024 ] , dirname [ 100 ] ;
2003-12-31 20:47:49 +01:00
int error = 2 ;
unsigned int i ;
loggedin = 0 ;
2003-12-30 22:30:32 +01:00
2007-12-27 20:52:48 +01:00
# ifndef USE_SQLITE3
2007-03-29 22:14:55 +02:00
if ( f_num > = globalconfig . max )
2004-01-21 17:31:40 +01:00
{
clear ( ) ;
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2004-01-21 17:31:40 +01:00
mvaddstr ( 5 , 1 , " Sorry, too many users have registered now. " ) ;
mvaddstr ( 6 , 1 , " You might email the server administrator. " ) ;
mvaddstr ( 7 , 1 , " Press return to return to the menu. " ) ;
2010-03-02 19:32:57 +01:00
dgl_getch ( ) ;
2004-01-21 17:31:40 +01:00
return ;
}
2007-12-27 20:52:48 +01:00
# endif
2004-01-21 17:31:40 +01:00
2003-12-31 20:47:49 +01:00
if ( me )
free ( me ) ;
2003-12-30 22:30:32 +01:00
2004-02-17 02:00:22 +01:00
me = calloc ( 1 , sizeof ( struct dg_user ) ) ;
2003-12-31 02:58:56 +01:00
2003-12-31 20:47:49 +01:00
while ( error )
{
clear ( ) ;
2003-12-30 23:41:47 +01:00
2007-03-31 13:10:07 +02:00
sprintf ( buf , " %i character max. " , globalconfig . max_newnick_len ) ;
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
mvaddstr ( 5 , 1 , " Welcome new user. Please enter a username. " ) ;
mvaddstr ( 6 , 1 ,
" Only characters and numbers are allowed, with no spaces. " ) ;
2007-03-31 13:10:07 +02:00
mvaddstr ( 7 , 1 , buf ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 9 , 1 , " => " ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
if ( error = = 1 )
{
mvaddstr ( 11 , 1 , " There was a problem with your last entry. " ) ;
move ( 9 , 4 ) ;
}
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
refresh ( ) ;
2003-12-30 22:30:32 +01:00
2008-01-12 23:29:13 +01:00
if ( mygetnstr ( buf , globalconfig . max_newnick_len , 1 ) ! = OK )
buf [ 0 ] = 0 ;
2007-12-27 20:52:48 +01:00
2007-12-30 10:00:16 +01:00
if ( * buf = = ' \0 ' ) {
2007-12-27 20:52:48 +01:00
free ( me ) ;
me = NULL ;
return ;
}
if ( ! userexist ( buf , 1 ) ) {
error = 0 ;
} else
error = 1 ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
for ( i = 0 ; i < strlen ( buf ) ; i + + )
{
2004-01-16 03:00:47 +01:00
if ( ! isalnum ( ( int ) buf [ i ] ) )
2003-12-31 20:47:49 +01:00
error = 1 ;
}
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
if ( strlen ( buf ) < 2 )
error = 1 ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
if ( strlen ( buf ) = = 0 )
2004-01-05 02:25:38 +01:00
{
free ( me ) ;
2004-02-17 01:58:21 +01:00
me = NULL ;
2003-12-31 20:47:49 +01:00
return ;
2004-01-05 02:25:38 +01:00
}
2003-12-31 20:47:49 +01:00
}
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
me - > username = strdup ( buf ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
/* password step */
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
clear ( ) ;
2003-12-30 22:30:32 +01:00
2004-02-13 23:30:59 +01:00
if ( ! changepw ( 0 ) ) /* Calling changepw instead to prompt twice. */
2004-01-04 13:16:05 +01:00
{
2004-01-05 02:25:38 +01:00
free ( me - > username ) ;
2004-01-04 13:16:05 +01:00
free ( me ) ;
me = NULL ;
return ;
}
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
/* email step */
2003-12-30 22:30:32 +01:00
2004-03-06 21:34:27 +01:00
error = 2 ;
while ( error ! = 0 )
{
clear ( ) ;
2003-12-30 22:30:32 +01:00
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2003-12-30 22:30:32 +01:00
2004-03-06 21:34:27 +01:00
mvaddstr ( 5 , 1 , " Please enter your email address. " ) ;
mvaddstr ( 6 , 1 , " This is sent _nowhere_ but will be used if you ask "
" the sysadmin for lost " ) ;
mvaddstr ( 7 , 1 , " password help. Please use a correct one. It only "
" benefits you. " ) ;
mvaddstr ( 8 , 1 , " 80 character max. No ':' characters. Blank line "
" aborts. " ) ;
mvaddstr ( 10 , 1 , " => " ) ;
2003-12-30 22:30:32 +01:00
2004-03-06 21:34:27 +01:00
if ( error = = 1 )
{
mvaddstr ( 12 , 1 , " There was a problem with your last entry. " ) ;
move ( 10 , 4 ) ;
}
2003-12-30 22:30:32 +01:00
2004-03-06 21:34:27 +01:00
refresh ( ) ;
2008-01-12 23:29:13 +01:00
if ( mygetnstr ( buf , 80 , 1 ) ! = OK )
buf [ 0 ] = 0 ;
2004-03-06 21:34:27 +01:00
if ( check_email ( buf ) )
error = 0 ;
else
error = 1 ;
2007-12-30 10:00:16 +01:00
if ( * buf = = ' \0 ' )
2004-03-06 21:34:27 +01:00
{
free ( me - > username ) ;
free ( me - > password ) ;
free ( me ) ;
me = NULL ;
return ;
}
}
2004-01-05 02:25:38 +01:00
2003-12-31 20:47:49 +01:00
me - > email = strdup ( buf ) ;
me - > env = calloc ( 1 , 1 ) ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
loggedin = 1 ;
2003-12-30 22:30:32 +01:00
2004-06-28 21:41:06 +02:00
setproctitle ( " %s " , me - > username ) ;
2004-02-17 19:33:13 +01:00
2008-01-01 18:03:05 +01:00
dgl_exec_cmdqueue ( globalconfig . cmdqueue [ DGLTIME_REGISTER ] , 0 , me ) ;
2003-12-31 20:47:49 +01:00
writefile ( 1 ) ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
int
2004-01-02 22:00:54 +01:00
passwordgood ( char * cpw )
2003-12-30 22:30:32 +01:00
{
2004-06-14 20:06:25 +02:00
assert ( me ! = NULL ) ;
2004-01-02 22:00:54 +01:00
2009-11-28 18:53:00 +01:00
if ( ! strncmp ( crypt ( cpw , cpw ) , me - > password , DGL_PASSWDLEN ) )
2003-12-31 20:47:49 +01:00
return 1 ;
2009-11-28 18:53:00 +01:00
if ( ! strncmp ( cpw , me - > password , DGL_PASSWDLEN ) )
2003-12-31 20:47:49 +01:00
return 1 ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
return 0 ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
int
readfile ( int nolock )
{
2007-12-27 20:52:48 +01:00
# ifndef USE_SQLITE3
2003-12-31 20:47:49 +01:00
FILE * fp = NULL , * fpl = NULL ;
char buf [ 1200 ] ;
2004-01-30 18:32:12 +01:00
struct flock fl = { 0 } ;
2004-01-04 01:59:48 +01:00
2004-01-30 18:32:12 +01:00
fl . l_type = F_RDLCK ;
fl . l_whence = SEEK_SET ;
fl . l_start = 0 ;
fl . l_len = 0 ;
memset ( buf , 1024 , 0 ) ;
2003-12-31 20:47:49 +01:00
/* read new stuff */
if ( ! nolock )
{
2007-03-31 23:29:45 +02:00
fpl = fopen ( globalconfig . lockfile , " r " ) ;
2009-10-17 22:26:56 +02:00
if ( ! fpl ) {
debug_write ( " cannot fopen lockfile " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 106 ) ;
2009-10-17 22:26:56 +02:00
}
if ( fcntl ( fileno ( fpl ) , F_SETLKW , & fl ) = = - 1 ) {
debug_write ( " cannot fcntl lockfile " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 114 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
}
2007-03-31 23:18:32 +02:00
fp = fopen ( globalconfig . passwd , " r " ) ;
2009-10-17 22:26:56 +02:00
if ( ! fp ) {
debug_write ( " cannot fopen passwd file " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 106 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
/* once per name in the file */
while ( fgets ( buf , 1200 , fp ) )
{
char * b = buf , * n = buf ;
users = realloc ( users , sizeof ( struct dg_user * ) * ( f_num + 1 ) ) ;
users [ f_num ] = malloc ( sizeof ( struct dg_user ) ) ;
2009-11-28 18:53:00 +01:00
users [ f_num ] - > username = ( char * ) calloc ( DGL_PLAYERNAMELEN + 2 , sizeof ( char ) ) ;
2003-12-31 20:47:49 +01:00
users [ f_num ] - > email = ( char * ) calloc ( 82 , sizeof ( char ) ) ;
2009-11-28 18:53:00 +01:00
users [ f_num ] - > password = ( char * ) calloc ( DGL_PASSWDLEN + 2 , sizeof ( char ) ) ;
2003-12-31 20:47:49 +01:00
users [ f_num ] - > env = ( char * ) calloc ( 1026 , sizeof ( char ) ) ;
/* name field, must be valid */
while ( * b ! = ' : ' )
{
2004-01-16 03:00:47 +01:00
if ( ! isalnum ( ( int ) * b ) )
2003-12-31 20:47:49 +01:00
return 1 ;
users [ f_num ] - > username [ ( b - n ) ] = * b ;
b + + ;
2009-11-28 18:53:00 +01:00
if ( ( b - n ) > = DGL_PLAYERNAMELEN ) {
2009-10-17 22:26:56 +02:00
debug_write ( " name field too long " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 100 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
}
/* advance to next field */
n = b + 1 ;
b = n ;
/* email field */
while ( * b ! = ' : ' )
{
users [ f_num ] - > email [ ( b - n ) ] = * b ;
b + + ;
2009-10-17 22:26:56 +02:00
if ( ( b - n ) > 80 ) {
debug_write ( " email field too long " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 101 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
}
/* advance to next field */
n = b + 1 ;
b = n ;
/* pw field */
while ( * b ! = ' : ' )
{
users [ f_num ] - > password [ ( b - n ) ] = * b ;
b + + ;
2009-11-28 18:53:00 +01:00
if ( ( b - n ) > = DGL_PASSWDLEN ) {
2009-10-17 22:26:56 +02:00
debug_write ( " passwd field too long " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 102 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
}
/* advance to next field */
n = b + 1 ;
b = n ;
/* env field */
while ( ( * b ! = ' \n ' ) & & ( * b ! = 0 ) & & ( * b ! = EOF ) )
{
users [ f_num ] - > env [ ( b - n ) ] = * b ;
b + + ;
2009-10-17 22:26:56 +02:00
if ( ( b - n ) > = 1024 ) {
debug_write ( " env field too long " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 102 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
}
f_num + + ;
/* prevent a buffer overrun here */
2007-03-29 22:14:55 +02:00
if ( f_num > globalconfig . max )
2004-02-01 09:20:28 +01:00
{
fprintf ( stderr , " ERROR: number of users in database exceeds maximum. Exiting. \n " ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " too many users in database " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 109 ) ;
2004-02-01 09:20:28 +01:00
}
2003-12-31 20:47:49 +01:00
}
if ( ! nolock )
fclose ( fpl ) ;
fclose ( fp ) ;
2007-12-27 20:52:48 +01:00
# endif
2003-12-31 20:47:49 +01:00
return 0 ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2007-12-27 20:52:48 +01:00
# ifndef USE_SQLITE3
2007-12-30 09:29:28 +01:00
struct dg_user * userexist_tmp_me = NULL ;
struct dg_user *
2007-03-31 13:10:07 +02:00
userexist ( char * cname , int isnew )
2003-12-30 22:30:32 +01:00
{
2003-12-31 20:47:49 +01:00
int i ;
2003-12-30 22:30:32 +01:00
2007-12-30 09:29:28 +01:00
if ( userexist_tmp_me ) {
free ( userexist_tmp_me - > username ) ;
free ( userexist_tmp_me - > email ) ;
free ( userexist_tmp_me - > env ) ;
free ( userexist_tmp_me - > password ) ;
free ( userexist_tmp_me ) ;
userexist_tmp_me = NULL ;
}
2003-12-31 20:47:49 +01:00
for ( i = 0 ; i < f_num ; i + + )
{
2009-11-27 19:41:35 +01:00
if ( ! strncasecmp ( cname , users [ i ] - > username , ( isnew ? globalconfig . max_newnick_len : DGL_PLAYERNAMELEN ) ) ) {
2007-12-30 09:29:28 +01:00
userexist_tmp_me = cpy_me ( users [ i ] ) ;
return userexist_tmp_me ;
}
2003-12-31 20:47:49 +01:00
}
2003-12-30 22:30:32 +01:00
2007-12-30 09:29:28 +01:00
return NULL ;
2003-12-30 22:30:32 +01:00
}
2007-12-27 20:52:48 +01:00
# else
struct dg_user * userexist_tmp_me = NULL ;
static int
userexist_callback ( void * NotUsed , int argc , char * * argv , char * * colname )
{
int i ;
NotUsed = NULL ;
userexist_tmp_me = malloc ( sizeof ( struct dg_user ) ) ;
for ( i = 0 ; i < argc ; i + + ) {
if ( ! strcmp ( colname [ i ] , " username " ) )
userexist_tmp_me - > username = strdup ( argv [ i ] ) ;
else if ( ! strcmp ( colname [ i ] , " email " ) )
userexist_tmp_me - > email = strdup ( argv [ i ] ) ;
else if ( ! strcmp ( colname [ i ] , " env " ) )
userexist_tmp_me - > env = strdup ( argv [ i ] ) ;
else if ( ! strcmp ( colname [ i ] , " password " ) )
userexist_tmp_me - > password = strdup ( argv [ i ] ) ;
else if ( ! strcmp ( colname [ i ] , " flags " ) )
userexist_tmp_me - > flags = atoi ( argv [ i ] ) ;
else if ( ! strcmp ( colname [ i ] , " id " ) )
userexist_tmp_me - > id = atoi ( argv [ i ] ) ;
}
return 0 ;
}
struct dg_user *
userexist ( char * cname , int isnew )
{
sqlite3 * db ;
char * errmsg = NULL ;
2007-12-28 00:44:09 +01:00
int ret , retry = 10 ;
2007-12-27 20:52:48 +01:00
char * qbuf ;
2009-11-27 19:41:35 +01:00
char tmpbuf [ DGL_PLAYERNAMELEN + 2 ] ;
strncpy ( tmpbuf , cname , ( isnew ? globalconfig . max_newnick_len : DGL_PLAYERNAMELEN ) ) ;
2007-12-27 20:52:48 +01:00
2007-12-28 11:01:35 +01:00
/* Check that the nick doesn't interfere with already registered nicks */
if ( isnew & & ( strlen ( cname ) > = globalconfig . max_newnick_len ) )
strcat ( tmpbuf , " % " ) ;
qbuf = sqlite3_mprintf ( " select * from dglusers where username like '%q' limit 1 " , tmpbuf ) ;
2007-12-27 20:52:48 +01:00
2007-12-30 09:44:02 +01:00
ret = sqlite3_open ( USE_SQLITE_DB , & db ) ; /* FIXME: use globalconfig->passwd? */
2007-12-27 20:52:48 +01:00
if ( ret ) {
sqlite3_close ( db ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " sqlite3_open failed " ) ;
2007-12-27 20:52:48 +01:00
graceful_exit ( 109 ) ;
}
if ( userexist_tmp_me ) {
free ( userexist_tmp_me - > username ) ;
free ( userexist_tmp_me - > email ) ;
free ( userexist_tmp_me - > env ) ;
free ( userexist_tmp_me - > password ) ;
free ( userexist_tmp_me ) ;
userexist_tmp_me = NULL ;
}
2008-08-23 11:47:04 +02:00
sqlite3_busy_timeout ( db , 10000 ) ;
ret = sqlite3_exec ( db , qbuf , userexist_callback , 0 , & errmsg ) ;
sqlite3_free ( qbuf ) ;
2007-12-27 20:52:48 +01:00
if ( ret ! = SQLITE_OK ) {
sqlite3_close ( db ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " sqlite3_exec failed " ) ;
2007-12-27 20:52:48 +01:00
graceful_exit ( 108 ) ;
}
sqlite3_close ( db ) ;
return userexist_tmp_me ;
}
# endif
2003-12-30 22:30:32 +01:00
/* ************************************************************* */
void
2007-03-29 22:14:55 +02:00
write_canned_rcfile ( int game , char * target )
2003-12-30 22:30:32 +01:00
{
2003-12-31 20:47:49 +01:00
FILE * canned , * newfile ;
2004-01-05 02:55:08 +01:00
char buf [ 1024 ] , * rfn ;
size_t bytes , len ;
2007-03-29 22:14:55 +02:00
len = strlen ( myconfig [ game ] - > rcfile ) + 2 ;
2004-01-05 02:55:08 +01:00
rfn = malloc ( len ) ;
2007-03-29 22:14:55 +02:00
snprintf ( rfn , len , " /%s " , myconfig [ game ] - > rcfile ) ;
2003-12-31 20:47:49 +01:00
if ( ! ( newfile = fopen ( target , " w " ) ) )
{
bail :
mvaddstr ( 13 , 1 ,
2004-02-01 09:10:00 +01:00
" You don't know how to write that! You write \" %s was here \" and the scroll disappears. " ) ;
2003-12-31 20:47:49 +01:00
mvaddstr ( 14 , 1 ,
2007-03-29 22:14:55 +02:00
" (Sorry, but I couldn't open one of the config files. This is a bug.) " ) ;
2003-12-31 20:47:49 +01:00
return ;
}
2004-01-05 02:55:08 +01:00
if ( ! ( canned = fopen ( rfn , " r " ) ) )
2003-12-31 20:47:49 +01:00
goto bail ;
2004-01-05 02:55:08 +01:00
free ( rfn ) ;
2003-12-31 20:47:49 +01:00
while ( ( bytes = fread ( buf , 1 , 1024 , canned ) ) > 0 )
{
if ( fwrite ( buf , 1 , bytes , newfile ) ! = bytes )
{
if ( ferror ( newfile ) )
{
mvaddstr ( 13 , 1 , " Your hand slips while engraving. " ) ;
mvaddstr ( 14 , 1 ,
" (Encountered a problem writing the new file. This is a bug.) " ) ;
fclose ( canned ) ;
fclose ( newfile ) ;
return ;
}
}
}
fclose ( canned ) ;
fclose ( newfile ) ;
2008-03-23 19:01:56 +01:00
chmod ( target , default_fmode ) ;
2003-12-30 22:30:32 +01:00
}
2003-12-31 02:58:56 +01:00
2003-12-30 22:30:32 +01:00
void
2007-03-29 22:14:55 +02:00
editoptions ( int game )
2003-12-30 22:30:32 +01:00
{
2003-12-31 20:47:49 +01:00
FILE * rcfile ;
char * myargv [ 3 ] ;
2004-01-23 19:14:48 +01:00
pid_t editor ;
2003-12-30 22:30:32 +01:00
2009-10-17 22:26:56 +02:00
rcfile = fopen ( dgl_format_str ( game , me , myconfig [ game ] - > rc_fmt , NULL ) , " r " ) ;
2007-03-29 22:14:55 +02:00
if ( ! rcfile )
2009-10-17 22:26:56 +02:00
write_canned_rcfile ( game , dgl_format_str ( game , me , myconfig [ game ] - > rc_fmt , NULL ) ) ;
2003-12-31 02:58:56 +01:00
2004-01-31 04:04:58 +01:00
/* use whatever editor_main to edit */
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
myargv [ 0 ] = " " ;
2009-10-17 22:26:56 +02:00
myargv [ 1 ] = dgl_format_str ( game , me , myconfig [ game ] - > rc_fmt , NULL ) ;
2003-12-31 20:47:49 +01:00
myargv [ 2 ] = 0 ;
2003-12-30 22:30:32 +01:00
2003-12-31 20:47:49 +01:00
endwin ( ) ;
2004-01-23 19:14:48 +01:00
editor = fork ( ) ;
if ( editor = = - 1 )
{
perror ( " fork " ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " edit fork failed " ) ;
2004-01-23 19:14:48 +01:00
graceful_exit ( 114 ) ;
}
else if ( editor = = 0 )
{
2004-01-25 23:44:34 +01:00
editor_main ( 2 , myargv ) ;
2004-01-23 19:14:48 +01:00
exit ( 0 ) ;
}
else
waitpid ( editor , NULL , 0 ) ;
2008-01-01 21:57:50 +01:00
2003-12-31 20:47:49 +01:00
refresh ( ) ;
2008-03-23 13:51:21 +01:00
check_retard ( 1 ) ;
2003-12-30 22:30:32 +01:00
}
/* ************************************************************* */
2007-12-27 20:52:48 +01:00
# ifndef USE_SQLITE3
2003-12-30 22:30:32 +01:00
void
writefile ( int requirenew )
{
2003-12-31 20:47:49 +01:00
FILE * fp , * fpl ;
int i = 0 ;
int my_done = 0 ;
2004-01-30 18:32:12 +01:00
struct flock fl = { 0 } ;
2004-02-17 01:53:28 +01:00
sigset_t oldmask , toblock ;
2004-01-30 18:32:12 +01:00
fl . l_type = F_WRLCK ;
fl . l_whence = SEEK_SET ;
fl . l_start = 0 ;
fl . l_len = 0 ;
2003-12-31 20:47:49 +01:00
2004-02-17 01:53:28 +01:00
sigemptyset ( & toblock ) ;
sigaddset ( & toblock , SIGHUP ) ;
sigaddset ( & toblock , SIGINT ) ;
sigaddset ( & toblock , SIGQUIT ) ;
sigaddset ( & toblock , SIGTERM ) ;
sigprocmask ( SIG_BLOCK , & toblock , & oldmask ) ;
2007-03-31 23:29:45 +02:00
fpl = fopen ( globalconfig . lockfile , " r+ " ) ;
2003-12-31 20:47:49 +01:00
if ( ! fpl )
2004-02-17 01:53:28 +01:00
{
sigprocmask ( SIG_SETMASK , & oldmask , NULL ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " writefile locking failed " ) ;
2004-02-17 01:53:28 +01:00
graceful_exit ( 115 ) ;
}
2004-01-12 18:32:47 +01:00
if ( fcntl ( fileno ( fpl ) , F_SETLK , & fl ) )
2004-02-17 01:53:28 +01:00
{
sigprocmask ( SIG_SETMASK , & oldmask , NULL ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " writefile fcntl failed " ) ;
2004-02-17 01:53:28 +01:00
graceful_exit ( 107 ) ;
}
2003-12-31 20:47:49 +01:00
2004-01-12 18:32:47 +01:00
fl . l_type = F_UNLCK ;
2008-01-01 21:57:50 +01:00
2003-12-31 20:47:49 +01:00
freefile ( ) ;
readfile ( 1 ) ;
2007-03-31 23:18:32 +02:00
fp = fopen ( globalconfig . passwd , " w " ) ;
2003-12-31 20:47:49 +01:00
if ( ! fp )
2004-02-17 01:53:28 +01:00
{
sigprocmask ( SIG_SETMASK , & oldmask , NULL ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " passwd file fopen failed " ) ;
2004-02-17 01:53:28 +01:00
graceful_exit ( 104 ) ;
}
2003-12-31 20:47:49 +01:00
for ( i = 0 ; i < f_num ; i + + )
{
2009-11-27 19:41:35 +01:00
if ( loggedin & & ! strncmp ( me - > username , users [ i ] - > username , DGL_PLAYERNAMELEN ) )
2003-12-31 20:47:49 +01:00
{
if ( requirenew )
{
/* this is if someone managed to register at the same time
* as someone else . just die . */
2004-02-17 01:53:28 +01:00
fclose ( fp ) ;
fclose ( fpl ) ;
sigprocmask ( SIG_SETMASK , & oldmask , NULL ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " two users registering at the same time " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 111 ) ;
2003-12-31 20:47:49 +01:00
}
fprintf ( fp , " %s:%s:%s:%s \n " , me - > username , me - > email , me - > password ,
me - > env ) ;
my_done = 1 ;
}
else
{
fprintf ( fp , " %s:%s:%s:%s \n " , users [ i ] - > username , users [ i ] - > email ,
users [ i ] - > password , users [ i ] - > env ) ;
}
}
if ( loggedin & & ! my_done )
{ /* new entry */
2007-03-29 22:14:55 +02:00
if ( f_num < globalconfig . max )
2004-01-21 17:31:40 +01:00
fprintf ( fp , " %s:%s:%s:%s \n " , me - > username , me - > email , me - > password ,
me - > env ) ;
else /* Oops, someone else registered the last available slot first */
2004-02-17 01:53:28 +01:00
{
fclose ( fp ) ;
fclose ( fpl ) ;
sigprocmask ( SIG_SETMASK , & oldmask , NULL ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " too many users in passwd db already " ) ;
2004-02-17 01:53:28 +01:00
graceful_exit ( 116 ) ;
}
2003-12-31 20:47:49 +01:00
}
fclose ( fp ) ;
fclose ( fpl ) ;
2004-02-17 01:53:28 +01:00
sigprocmask ( SIG_SETMASK , & oldmask , NULL ) ;
2003-12-30 22:30:32 +01:00
}
2007-12-27 20:52:48 +01:00
# else
void
writefile ( int requirenew )
{
sqlite3 * db ;
char * errmsg = NULL ;
2007-12-28 00:44:09 +01:00
int ret , retry = 10 ;
2007-12-27 20:52:48 +01:00
char * qbuf ;
if ( requirenew ) {
qbuf = sqlite3_mprintf ( " insert into dglusers (username, email, env, password, flags) values ('%q', '%q', '%q', '%q', %li) " , me - > username , me - > email , me - > env , me - > password , me - > flags ) ;
} else {
qbuf = sqlite3_mprintf ( " update dglusers set username='%q', email='%q', env='%q', password='%q', flags=%li where id=%i " , me - > username , me - > email , me - > env , me - > password , me - > flags , me - > id ) ;
}
2007-12-30 09:44:02 +01:00
ret = sqlite3_open ( USE_SQLITE_DB , & db ) ; /* FIXME: use globalconfig->passwd? */
2007-12-27 20:52:48 +01:00
if ( ret ) {
sqlite3_close ( db ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " writefile sqlite3_open failed " ) ;
2007-12-27 20:52:48 +01:00
graceful_exit ( 107 ) ;
}
2008-08-23 11:47:04 +02:00
sqlite3_busy_timeout ( db , 10000 ) ;
ret = sqlite3_exec ( db , qbuf , NULL , NULL , & errmsg ) ;
2007-12-27 20:52:48 +01:00
sqlite3_free ( qbuf ) ;
if ( ret ! = SQLITE_OK ) {
sqlite3_close ( db ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " writefile sqlite3_exec failed " ) ;
2007-12-27 20:52:48 +01:00
graceful_exit ( 106 ) ;
}
sqlite3_close ( db ) ;
}
# endif
2003-12-30 22:30:32 +01:00
2004-01-04 02:45:21 +01:00
/* ************************************************************* */
/* ************************************************************* */
2003-12-30 22:30:32 +01:00
/* ************************************************************* */
/* ************************************************************* */
/* ************************************************************* */
2007-03-29 22:14:55 +02:00
2004-01-28 17:31:37 +01:00
int
2007-03-29 22:14:55 +02:00
purge_stale_locks ( int game )
2004-01-04 03:03:26 +01:00
{
2004-01-04 03:19:12 +01:00
DIR * pdir ;
2004-01-04 03:03:26 +01:00
struct dirent * dent ;
2004-01-05 02:55:08 +01:00
char * dir ;
size_t len ;
2004-01-28 17:31:37 +01:00
short firsttime = 1 ;
2004-01-05 02:55:08 +01:00
2009-10-17 22:26:56 +02:00
dir = strdup ( dgl_format_str ( game , me , myconfig [ game ] - > inprogressdir , NULL ) ) ;
2007-03-29 22:14:55 +02:00
2009-10-17 22:26:56 +02:00
if ( ! ( pdir = opendir ( dir ) ) ) {
debug_write ( " purge_stale_locks dir open failed " ) ;
2004-01-04 03:19:12 +01:00
graceful_exit ( 200 ) ;
2009-10-17 22:26:56 +02:00
}
2004-01-04 03:19:12 +01:00
2004-01-05 02:55:08 +01:00
free ( dir ) ;
2004-01-04 03:19:12 +01:00
while ( ( dent = readdir ( pdir ) ) ! = NULL )
{
FILE * ipfile ;
2004-01-04 03:35:40 +01:00
char * colon , * fn ;
2004-01-04 03:19:12 +01:00
char buf [ 16 ] ;
pid_t pid ;
2004-01-04 03:35:40 +01:00
size_t len ;
int seconds = 0 ;
2007-03-29 22:14:55 +02:00
2004-01-04 23:49:29 +01:00
if ( ! strcmp ( dent - > d_name , " . " ) | | ! strcmp ( dent - > d_name , " .. " ) )
continue ;
2004-01-04 03:28:57 +01:00
2004-01-04 03:19:12 +01:00
colon = strchr ( dent - > d_name , ' : ' ) ;
/* should never happen */
2009-10-17 22:26:56 +02:00
if ( ! colon ) {
debug_write ( " purge_stale_locks !colon " ) ;
2004-01-04 03:19:12 +01:00
graceful_exit ( 201 ) ;
2009-10-17 22:26:56 +02:00
}
2004-02-16 00:19:39 +01:00
if ( colon - dent - > d_name ! = strlen ( me - > username ) )
continue ;
2004-01-04 03:19:12 +01:00
if ( strncmp ( dent - > d_name , me - > username , colon - dent - > d_name ) )
continue ;
2004-01-04 03:03:26 +01:00
2009-10-17 22:26:56 +02:00
len = strlen ( dent - > d_name ) + strlen ( dgl_format_str ( game , me , myconfig [ game ] - > inprogressdir , NULL ) ) + 1 ;
2004-01-04 03:35:40 +01:00
fn = malloc ( len ) ;
2009-10-17 22:26:56 +02:00
snprintf ( fn , len , " %s%s " , dgl_format_str ( game , me , myconfig [ game ] - > inprogressdir , NULL ) , dent - > d_name ) ;
2004-01-04 23:49:29 +01:00
2009-10-17 22:26:56 +02:00
if ( ! ( ipfile = fopen ( fn , " r " ) ) ) {
debug_write ( " purge_stale_locks fopen inprogressdir fail " ) ;
2004-01-04 03:19:12 +01:00
graceful_exit ( 202 ) ;
2009-10-17 22:26:56 +02:00
}
2004-01-04 03:03:26 +01:00
2009-10-17 22:26:56 +02:00
if ( fgets ( buf , 16 , ipfile ) = = NULL ) {
debug_write ( " purge_stale_locks fgets ipfile fail " ) ;
2004-01-04 03:19:12 +01:00
graceful_exit ( 203 ) ;
2009-10-17 22:26:56 +02:00
}
2004-01-04 03:03:26 +01:00
2004-01-04 03:19:12 +01:00
fclose ( ipfile ) ;
2004-01-04 03:35:40 +01:00
2004-01-28 17:31:37 +01:00
if ( firsttime )
{
clear ( ) ;
2008-04-05 15:29:19 +02:00
drawbanner ( & banner , 1 , 1 ) ;
2004-01-28 17:31:37 +01:00
2004-02-01 09:10:00 +01:00
# define HUP_WAIT 10 /* seconds before HUPPING */
mvprintw ( 3 , 1 ,
2004-04-03 21:27:42 +02:00
" There are some stale %s processes, will recover in %d seconds. " ,
2007-03-29 22:14:55 +02:00
myconfig [ game ] - > game_name , HUP_WAIT ) ;
2004-01-28 17:31:37 +01:00
mvaddstr ( 4 , 1 ,
" Press a key NOW if you don't want this to happen! " ) ;
2007-03-29 22:14:55 +02:00
move ( 3 , 51 + strlen ( myconfig [ game ] - > game_name ) ) ; /* pedantry */
2004-01-28 17:31:37 +01:00
halfdelay ( 10 ) ;
2007-03-29 22:14:55 +02:00
2004-02-01 09:10:00 +01:00
for ( seconds = HUP_WAIT - 1 ; seconds > = 0 ; seconds - - )
2004-01-28 17:31:37 +01:00
{
2010-03-02 19:32:57 +01:00
if ( dgl_getch ( ) ! = ERR )
2004-01-28 17:31:37 +01:00
{
nocbreak ( ) ; /* leave half-delay */
cbreak ( ) ;
return 0 ;
}
2007-03-29 22:14:55 +02:00
mvprintw ( 3 , 50 + strlen ( myconfig [ game ] - > game_name ) , " %d%s " , seconds , ( seconds > 9 ) ? " " : " " ) ;
2004-01-28 17:31:37 +01:00
}
nocbreak ( ) ;
cbreak ( ) ;
2007-03-29 22:14:55 +02:00
2004-01-28 17:31:37 +01:00
firsttime = 0 ;
}
2004-01-30 01:56:46 +01:00
clear ( ) ;
2004-01-04 03:56:09 +01:00
refresh ( ) ;
2004-01-04 03:03:26 +01:00
2004-01-04 03:19:12 +01:00
pid = atoi ( buf ) ;
2004-01-04 03:03:26 +01:00
2004-01-04 03:19:12 +01:00
kill ( pid , SIGHUP ) ;
2004-01-04 03:03:26 +01:00
2004-01-04 03:19:12 +01:00
errno = 0 ;
2004-01-04 03:03:26 +01:00
2004-01-04 03:19:12 +01:00
/* Wait for it to stop running */
2004-01-04 03:31:00 +01:00
seconds = 0 ;
2004-01-04 03:19:12 +01:00
while ( kill ( pid , 0 ) = = 0 )
{
seconds + + ;
sleep ( 1 ) ;
if ( seconds = = 10 )
{
2004-04-03 21:27:42 +02:00
mvprintw ( 3 , 1 ,
2007-03-29 22:14:55 +02:00
" Couldn't terminate one of your stale %s processes gracefully. " , myconfig [ game ] - > game_name ) ;
2004-01-04 03:19:12 +01:00
mvaddstr ( 4 , 1 , " Force its termination? [yn] " ) ;
2010-03-02 19:32:57 +01:00
if ( tolower ( dgl_getch ( ) ) = = ' y ' )
2004-01-04 03:19:12 +01:00
{
kill ( pid , SIGTERM ) ;
break ;
}
2004-01-04 23:49:29 +01:00
else
{
endwin ( ) ;
2004-04-03 21:27:42 +02:00
fprintf ( stderr , " Sorry, no %s for you now, please "
2007-03-29 22:14:55 +02:00
" contact the admin. \n " , myconfig [ game ] - > game_name ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " could not terminate stale processes " ) ;
2004-01-04 23:49:29 +01:00
graceful_exit ( 1 ) ;
}
2004-01-04 03:19:12 +01:00
}
}
2004-01-04 03:56:09 +01:00
/* Don't remove the lock file until the process is dead. */
unlink ( fn ) ;
free ( fn ) ;
2004-01-04 03:19:12 +01:00
}
closedir ( pdir ) ;
2004-01-28 17:31:37 +01:00
return 1 ;
}
2004-01-04 03:03:26 +01:00
2008-08-23 14:39:01 +02:00
int
2008-04-05 15:29:19 +02:00
runmenuloop ( struct dg_menu * menu )
2007-03-29 22:14:55 +02:00
{
2008-04-05 15:29:19 +02:00
struct dg_banner ban ;
struct dg_menuoption * tmpopt ;
int userchoice = 0 ;
2009-10-19 17:17:28 +02:00
int doclear = 1 ;
2008-04-05 15:29:19 +02:00
2008-08-23 14:39:01 +02:00
if ( ! menu ) return 1 ;
2008-04-05 15:29:19 +02:00
ban . lines = NULL ;
ban . len = 0 ;
2010-03-02 19:32:57 +01:00
idle_alarm_set_enabled ( 1 ) ;
2008-04-05 15:29:19 +02:00
loadbanner ( menu - > banner_fn , & ban ) ;
while ( 1 ) {
2009-10-19 17:17:28 +02:00
if ( doclear ) {
doclear = 0 ;
clear ( ) ;
}
2008-04-05 15:29:19 +02:00
drawbanner ( & ban , 1 , 0 ) ;
2009-12-01 22:55:48 +01:00
if ( menu - > cursor_x > = 0 & & menu - > cursor_y > = 0 )
mvprintw ( menu - > cursor_y , menu - > cursor_x , " " ) ;
2008-04-05 15:29:19 +02:00
refresh ( ) ;
2010-03-02 19:32:57 +01:00
userchoice = dgl_getch ( ) ;
2010-05-03 19:54:13 +02:00
if ( userchoice = = ERR ) {
freebanner ( & ban ) ;
return 1 ;
}
2008-04-05 15:29:19 +02:00
tmpopt = menu - > options ;
while ( tmpopt ) {
if ( strchr ( tmpopt - > keys , userchoice ) ) {
dgl_exec_cmdqueue ( tmpopt - > cmdqueue , selected_game , me ) ;
2009-10-19 17:17:28 +02:00
doclear = 1 ;
2008-04-05 15:29:19 +02:00
break ;
} else {
tmpopt = tmpopt - > next ;
}
}
2007-03-29 22:14:55 +02:00
2008-04-05 15:29:19 +02:00
if ( return_from_submenu ) {
2010-05-03 19:54:13 +02:00
freebanner ( & ban ) ;
2008-04-05 15:29:19 +02:00
return_from_submenu = 0 ;
2008-08-23 14:39:01 +02:00
return 0 ;
2008-04-05 15:29:19 +02:00
}
2008-04-05 17:07:26 +02:00
if ( check_retard ( 0 ) ) {
2010-05-03 19:54:13 +02:00
freebanner ( & ban ) ;
2009-10-17 22:26:56 +02:00
debug_write ( " retard " ) ;
2008-04-05 17:07:26 +02:00
graceful_exit ( 119 ) ;
}
2007-03-29 22:14:55 +02:00
}
}
2004-04-21 18:22:55 +02:00
int
authenticate ( )
{
int i , len , me_index ;
2009-11-28 18:53:00 +01:00
char user_buf [ DGL_PLAYERNAMELEN + 1 ] , pw_buf [ DGL_PASSWDLEN + 1 ] ;
2009-10-18 10:39:19 +02:00
struct dg_game * * games = NULL ;
2004-04-21 18:22:55 +02:00
/* We use simple password authentication, rather than challenge/response. */
printf ( " \n " ) ;
fflush ( stdout ) ;
fgets ( user_buf , sizeof ( user_buf ) , stdin ) ;
len = strlen ( user_buf ) ;
if ( user_buf [ len - 1 ] = = ' \n ' )
user_buf [ - - len ] = ' \0 ' ;
else
{
2009-11-27 19:41:35 +01:00
fprintf ( stderr , " Username too long (max %i chars). \n " , DGL_PLAYERNAMELEN ) ;
2004-04-21 18:22:55 +02:00
return 1 ;
}
fgets ( pw_buf , sizeof ( pw_buf ) , stdin ) ;
len = strlen ( pw_buf ) ;
if ( pw_buf [ len - 1 ] = = ' \n ' )
pw_buf [ - - len ] = ' \0 ' ;
else
{
2009-11-28 18:53:00 +01:00
fprintf ( stderr , " Password too long (max %i chars). \n " , DGL_PASSWDLEN ) ;
2004-04-21 18:22:55 +02:00
return 1 ;
}
2007-12-27 20:52:48 +01:00
{
struct dg_user * tmpme ;
if ( ( tmpme = userexist ( user_buf , 0 ) ) ) {
me = cpy_me ( tmpme ) ;
if ( passwordgood ( pw_buf ) )
{
2009-10-17 19:34:36 +02:00
games = populate_games ( - 1 , & len , me ) ;
2007-12-27 20:52:48 +01:00
for ( i = 0 ; i < len ; i + + )
if ( ! strcmp ( games [ i ] - > name , user_buf ) )
{
fprintf ( stderr , " Game already in progress. \n " ) ;
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2007-12-27 20:52:48 +01:00
return 1 ;
}
win . ws_row = win . ws_col = 0 ;
gen_inprogress_lock ( 0 , getppid ( ) , gen_nhext_filename ( ) ) ;
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2007-12-27 20:52:48 +01:00
return 0 ;
}
}
}
2004-04-21 18:22:55 +02:00
sleep ( 2 ) ;
fprintf ( stderr , " Login failed. \n " ) ;
2009-10-18 10:39:19 +02:00
free_populated_games ( games , len ) ;
2004-04-21 18:22:55 +02:00
return 1 ;
}
2003-12-30 22:30:32 +01:00
int
2004-01-05 02:57:25 +01:00
main ( int argc , char * * argv )
2003-12-30 22:30:32 +01:00
{
2003-12-31 20:47:49 +01:00
/* for chroot and program execution */
2008-04-05 15:29:19 +02:00
char atrcfilename [ 81 ] , * p , * auth = NULL ;
2003-12-31 20:47:49 +01:00
unsigned int len ;
2007-03-31 18:21:58 +02:00
int c , i ;
2004-04-21 18:22:55 +02:00
int nhext = 0 , nhauth = 0 ;
2007-03-29 22:14:55 +02:00
int userchoice ;
2007-04-01 14:09:42 +02:00
char * tmp ;
2008-04-06 10:27:44 +02:00
char * wall_email_str = NULL ;
2010-02-25 17:40:55 +01:00
# ifdef USE_RLIMIT
struct rlimit lim ;
# endif
2003-12-31 20:47:49 +01:00
2004-07-03 21:19:28 +02:00
# ifndef HAVE_SETPROCTITLE
/* save argc, argv */
char * * saved_argv ;
2007-03-31 18:21:58 +02:00
int saved_argc ;
2004-07-03 21:19:28 +02:00
saved_argc = argc ;
saved_argv = malloc ( sizeof ( char * * ) * ( argc + 1 ) ) ;
for ( i = 0 ; i < argc ; i + + )
saved_argv [ i ] = strdup ( argv [ i ] ) ;
saved_argv [ i ] = ' \0 ' ;
compat_init_setproctitle ( argc , argv ) ;
argv = saved_argv ;
# endif
2004-09-12 10:58:32 +02:00
p = getenv ( " USER " ) ;
2009-09-26 21:13:05 +02:00
/* Linux telnetd allows importing the USER envvar via telnet,
* while FreeBSD does not . FreeBSD , on the other hand , does allow
* the LOGNAME envvar . Check USER first , then LOGNAME .
*/
if ( p = = NULL ) {
p = getenv ( " LOGNAME " ) ;
}
2004-09-12 10:58:32 +02:00
if ( p & & * p ! = ' \0 ' )
auth = strdup ( p ) ;
/* else auth is still NULL */
2004-07-03 21:19:28 +02:00
__progname = basename ( strdup ( argv [ 0 ] ) ) ;
2010-05-01 16:41:54 +02:00
while ( ( c = getopt ( argc , argv , " qh:pf:aeW:S " ) ) ! = - 1 )
2004-01-31 07:23:02 +01:00
{
2004-02-01 21:53:08 +01:00
switch ( c )
2004-02-01 21:46:08 +01:00
{
2004-02-01 21:53:08 +01:00
case ' q ' :
silent = 1 ; break ;
2004-04-21 18:22:55 +02:00
case ' a ' :
nhauth = 1 ; break ;
case ' e ' :
nhext = 1 ; break ;
2004-02-02 23:57:54 +01:00
case ' f ' :
if ( config )
{
if ( ! silent )
fprintf ( stderr , " warning: using %s \n " , argv [ optind ] ) ;
free ( config ) ;
}
2008-01-01 21:57:50 +01:00
2004-02-02 23:57:54 +01:00
config = strdup ( optarg ) ;
break ;
2008-01-01 21:57:50 +01:00
2008-04-06 10:27:44 +02:00
case ' W ' :
wall_email_str = strdup ( optarg ) ;
break ;
2010-05-01 16:41:54 +02:00
case ' S ' : /* Free the shared memory block */
{
# ifdef USE_SHMEM
key_t shm , sem ;
int shm_id ;
int shm_size = sizeof ( struct dg_shm ) + shm_n_games * sizeof ( struct dg_shm_game ) ;
shm_mk_keys ( & shm , & sem ) ;
if ( ( shm_id = shmget ( shm , shm_size , 0644 ) ) ! = - 1 ) {
shmctl ( shm_id , IPC_RMID , NULL ) ;
if ( ! silent ) fprintf ( stderr , " shmem block freed. \n " ) ;
} else {
if ( ! silent ) fprintf ( stderr , " nonexistent shmem block. \n " ) ;
}
# else
if ( ! silent ) fprintf ( stderr , " warning: dgamelaunch was compiled without shmem. \n " ) ;
# endif
graceful_exit ( 0 ) ;
}
break ;
2004-02-01 21:53:08 +01:00
default :
break ; /*ignore */
2004-02-01 21:46:08 +01:00
}
2004-02-01 21:53:08 +01:00
}
2008-01-01 21:57:50 +01:00
2004-06-22 18:36:09 +02:00
while ( optind < argc )
{
size_t len = strlen ( argv [ optind ] ) ;
memset ( argv [ optind + + ] , 0 , len ) ;
}
2008-01-13 00:15:30 +01:00
setproctitle ( " <Anonymous> " ) ;
2004-06-22 18:36:09 +02:00
2009-10-18 15:10:45 +02:00
srand ( time ( 0 ) ) ;
2004-01-05 02:55:08 +01:00
create_config ( ) ;
2003-12-31 20:47:49 +01:00
/* signal handlers */
signal ( SIGHUP , catch_sighup ) ;
2009-10-18 02:17:50 +02:00
signal ( SIGWINCH , sigwinch_func ) ;
2003-12-31 20:47:49 +01:00
2004-02-20 18:57:29 +01:00
( void ) tcgetattr ( 0 , & tt ) ;
2004-03-04 14:30:12 +01:00
if ( - 1 = = ioctl ( 0 , TIOCGWINSZ , ( char * ) & win ) | | win . ws_row < 4 | |
win . ws_col < 4 ) /* Rudimentary validity check */
{
win . ws_row = 24 ;
win . ws_col = 80 ;
win . ws_xpixel = win . ws_col * 8 ;
win . ws_ypixel = win . ws_row * 8 ;
}
2003-12-31 20:47:49 +01:00
2004-02-20 18:57:29 +01:00
/* get master tty just before chroot (lives in /dev) */
2004-04-21 18:22:55 +02:00
if ( ! nhext & & ! nhauth )
ttyrec_getpty ( ) ;
2003-12-31 20:47:49 +01:00
2010-02-25 17:40:55 +01:00
# ifdef USE_RLIMIT
# ifdef USE_RLIMIT_CORE
/* enable and set core dump size */
if ( ! getrlimit ( RLIMIT_CORE , & lim ) ) {
lim . rlim_cur = USE_RLIMIT_CORE ;
setrlimit ( RLIMIT_CORE , & lim ) ;
}
# endif
# ifdef USE_RLIMIT_AS
/* set maximum memory usage */
if ( ! getrlimit ( RLIMIT_AS , & lim ) ) {
lim . rlim_cur = USE_RLIMIT_AS ;
setrlimit ( RLIMIT_AS , & lim ) ;
}
# endif
# endif
2007-03-29 22:14:55 +02:00
if ( geteuid ( ) ! = globalconfig . shed_uid )
2003-12-31 20:47:49 +01:00
{
2004-04-21 18:22:55 +02:00
/* chroot */
2007-03-29 22:14:55 +02:00
if ( chroot ( globalconfig . chroot ) )
2004-04-21 18:22:55 +02:00
{
perror ( " cannot change root directory " ) ;
graceful_exit ( 1 ) ;
}
2003-12-31 20:47:49 +01:00
2004-04-21 18:22:55 +02:00
if ( chdir ( " / " ) )
{
perror ( " cannot chdir to root directory " ) ;
graceful_exit ( 1 ) ;
}
2003-12-31 20:47:49 +01:00
2004-04-21 18:22:55 +02:00
/* shed privs. this is done immediately after chroot. */
2007-03-29 22:14:55 +02:00
if ( setgroups ( 1 , & globalconfig . shed_gid ) = = - 1 )
2004-04-21 18:22:55 +02:00
{
perror ( " setgroups " ) ;
graceful_exit ( 1 ) ;
}
2004-01-02 21:39:02 +01:00
2007-03-29 22:14:55 +02:00
if ( setgid ( globalconfig . shed_gid ) = = - 1 )
2004-04-21 18:22:55 +02:00
{
perror ( " setgid " ) ;
graceful_exit ( 1 ) ;
}
2007-03-29 22:14:55 +02:00
if ( setuid ( globalconfig . shed_uid ) = = - 1 )
2004-04-21 18:22:55 +02:00
{
perror ( " setuid " ) ;
graceful_exit ( 1 ) ;
}
2004-01-03 04:51:29 +01:00
}
2004-01-02 21:39:02 +01:00
2008-04-06 10:27:44 +02:00
if ( wall_email_str ) {
char * emailfrom = wall_email_str ;
char * emailmsg = strchr ( wall_email_str , ' : ' ) ;
2009-10-17 22:26:56 +02:00
if ( ! emailmsg ) {
debug_write ( " wall: no mail msg " ) ;
2008-04-06 10:27:44 +02:00
graceful_exit ( 117 ) ;
2009-10-17 22:26:56 +02:00
}
2008-04-06 10:27:44 +02:00
* emailmsg = ' \0 ' ;
emailmsg + + ;
if ( emailmsg )
wall_email ( emailfrom , emailmsg ) ;
graceful_exit ( 0 ) ;
}
2010-05-03 19:54:13 +02:00
banner . len = 0 ;
banner . lines = NULL ;
2008-04-05 15:29:19 +02:00
loadbanner ( globalconfig . banner , & banner ) ;
2008-01-01 18:03:05 +01:00
dgl_exec_cmdqueue ( globalconfig . cmdqueue [ DGLTIME_DGLSTART ] , 0 , NULL ) ;
2004-04-21 18:22:55 +02:00
if ( nhext )
2004-01-03 04:51:29 +01:00
{
2004-04-21 18:22:55 +02:00
char * myargv [ 3 ] ;
2007-03-29 22:14:55 +02:00
myargv [ 0 ] = myconfig [ 0 ] - > game_path ;
2004-04-21 18:22:55 +02:00
myargv [ 1 ] = " --proxy " ;
myargv [ 2 ] = 0 ;
2007-03-29 22:14:55 +02:00
execvp ( myconfig [ 0 ] - > game_path , myargv ) ;
perror ( myconfig [ 0 ] - > game_path ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 1 ) ;
2004-01-03 04:51:29 +01:00
}
2003-12-31 20:47:49 +01:00
/* simple login routine, uses ncurses */
2009-10-17 22:26:56 +02:00
if ( readfile ( 0 ) ) {
debug_write ( " log in fail " ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 110 ) ;
2009-10-17 22:26:56 +02:00
}
2003-12-31 20:47:49 +01:00
2009-10-17 22:26:56 +02:00
if ( nhauth ) {
debug_write ( " nhauth " ) ;
2004-04-21 18:22:55 +02:00
graceful_exit ( authenticate ( ) ) ;
2009-10-17 22:26:56 +02:00
}
2004-04-21 18:22:55 +02:00
2004-06-12 02:11:18 +02:00
if ( auth )
{
char * user , * pass , * p ;
p = strchr ( auth , ' : ' ) ;
if ( p )
{
pass = p + 1 ;
2004-06-13 05:05:47 +02:00
if ( * pass ! = ' \0 ' )
2004-06-12 02:11:18 +02:00
{
* p = ' \0 ' ;
user = auth ;
autologin ( user , pass ) ;
}
}
}
2007-03-29 22:14:55 +02:00
2008-04-05 15:29:19 +02:00
initcurses ( ) ;
2009-10-18 02:17:50 +02:00
term_resize_check ( ) ;
2004-06-28 21:41:06 +02:00
2008-04-05 15:29:19 +02:00
while ( 1 ) {
2008-08-23 14:39:01 +02:00
if ( runmenuloop ( dgl_find_menu ( loggedin ? " mainmenu_user " : " mainmenu_anon " ) ) )
break ;
2007-03-29 22:14:55 +02:00
}
2003-12-31 20:47:49 +01:00
/* NOW we can safely kill this */
freefile ( ) ;
if ( me )
free ( me ) ;
2010-05-03 19:54:13 +02:00
freebanner ( & banner ) ;
2004-01-04 02:45:21 +01:00
graceful_exit ( 1 ) ;
2007-03-29 22:14:55 +02:00
2003-12-31 20:47:49 +01:00
return 1 ;
2003-12-30 22:30:32 +01:00
}