[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Proposal for new Ssystem call in MiNT



Attached to this mail are two files, containing the C code for the new
system call Ssystem(long mode, void *ptr).

Those who are interrested in MiNT should have a look on it. Tell me about bugs
in the code, maybe someone has some suggestions.

  jerry
        jerry@merlin.abacus.de          jerry@zedat.fu-berlin.de

/* @(#)ssystem.c mint/freemint
 * $Id$
 * by jerry g geiger
 *  - jerry@zedat.fu-berlin.de  or jerry@merlin.abacus.de
 * 
 * 
 * 
 Ssystem(('GC'<< 16)|addr, char *pvalue)
 	GC, GS, GL
 	returns value of Sysvar addr in pvalue: char, short, long
	To read the memory at returned pointers you will need
	access to that memory region !!

 Ssystem(('SS'<< 16)|addr, short *pvalue)
	SS, SL
	set sysvar at addr to value at pvalue: short, long
	only by superuser (ruid == 0)!!

 Ssystem(GETCOOKIE, COOKIE *cookiep)
 
 Ssystem(SETCOOKIE, COOKIE *cookiep)
 	needs euid root; if exists change cookie
 
 Ssystem(SETCLOCK, struct timeval *tvp); 
 	also SETICLOCK,SETMCLOCK,SETTCLOCK
	needs euid root, if ptr == NULL use current time

 Ssystem(GETCLOCKT, clock_t *pvalue);
 	if pvalue return clock_t in there

uname:
 Ssystem(OSNAME, long *pvalue);
	returns 'MiNT'
 Ssystem(OSVERSION, long *pvalue);
	returns MiNT version MAJ<<24|MIN<<16|PatchLev<<8|ident
		ident: 'f' for Freemint, b for beta, ...
 Ssystem(OSDATE, long *pvalue);
 	returns MiNT compile or release Date 
	time(seconds) since epoch or string ???
 Ssystem(MACHINE, long *pvalue);
 	'A'<<24|XX<<16|FP<<8|SOUND
	A: Atari  XX: 680XX   FP: bits: 1: yes | 2: hardware  
	SOUND: 1 Yamaha chip, 2 DSP
 Ssystem(GETHOSTNAME, char *pvalue);
 	string, pvalue has to be an 128 bytes array, only valid after SETHOSTNAME!!
 Ssystem(SETHOSTNAME, char *pvalue);
 	pvalue string of max 127 bytes + '\0', only superuser
 */

#include "ssystem.h"
#include "time.h"
#include "version.h"
#include "cookie.h"
#include "mint.h"

extern long set_clock(int which, struct timeval *tvp);	/* see time.c	*/

static long get_cookie(COOKIE *cookiep);
static long set_cookie(COOKIE *cookiep);

static long MiNT_version = (long)MAJ_VERSION<<24|(long)MIN_VERSION<<16|PAT_LEVEL<<8|VERS_IDENT;
static char hostname[128];

long ARGS_ON_STACK s_system  (long mode , void *ptr)
{
	int smode, isroot = 0;	/* check euid -> 1, ruid --> 2	*/

	if(curproc->euid == 0)
		isroot = 1;
	if(curproc->ruid == 0)
		isroot = 2;

	if(!mode)	/* yes this call exists	*/
		return(0L);	

	if(!ptr)
		return(-1);
	
	switch(mode) {
		case OSNAME:
			*(unsigned long *)ptr = 0x4d694e54L /* 'MiNT' */ ;break;
		case OSVERSION:
			*(unsigned long *)ptr = MiNT_version; break;
		case GETHOSTNAME:
			strcpy((char *)ptr, hostname); break;
		case GETCLOCKT:
			*(unsigned long *)ptr = *((unsigned long *)0x004ba); break;
		case SETHOSTNAME:
			if(!isroot)
				return(EACCDN);
			strncpy(hostname,(char *)ptr, 127); break;
		case SETCLOCK:
		case SETICLOCK:
		case SETMCLOCK:
		case SETTCLOCK:
			if(!isroot)
				return(EACCDN);
			return(set_clock(mode&SETCLOCKMASK, (struct timeval *)ptr));
			break;
		case GETCOOKIE:
			return(get_cookie((COOKIE *)ptr));
			break;
		case SETCOOKIE:
			if(!isroot)
				return(EACCDN);
			return(set_cookie((COOKIE *)ptr));
		default:
			smode = (mode & 0xffff0000)>>16;
			if(smode && !ptr)
				return(-1);
			switch(smode) {
				/* get variables	*/
				case 'GC':
					*(char *)ptr = *((char *)(mode&0xffff)); break;
				case 'GS':
					*(short *)ptr = *((short *)(mode&0xfffe)); break;
				case 'GL':
					*(long *)ptr = *((long *)(mode&0xfffe)); break;
				case 'SS':
					if(isroot != 2) return(EACCDN);
					*((short *)(mode&0xfffe)) = *(short *)ptr; break;
				case 'SL':
					if(isroot != 2) return(EACCDN);
					*((long *)(mode&0xfffe)) = *(long *)ptr; break;
				default:
					return(EINVFN);
			}
	}
	return(0);
}



/* 
 * find cookie cookiep->tag and return it's value in 
 * cookiep->value, return 0
 * return -1 if not found
 */

static long get_cookie(COOKIE *cookiep)
{
	COOKIE * cjar;
	cjar = *CJAR;	/* for compatibility. 	*/
	while(cjar->tag) {
		if(cjar->tag == cookiep->tag) {
			cookiep->value = cjar->value;
			return(0);
		}
		cjar++;
	}
	return(-1);
}


/* 
 * add cookie cookiep->tag to cookie list or change it's value
 * if already existing
 * 
 */

static long set_cookie(COOKIE *cookiep)
{
	COOKIE * cjar; int n = 0;
	cjar = *CJAR;	/* for compatibility. 	*/
	while(cjar->tag) {
		n++;
		if(cjar->tag == cookiep->tag) {
			cjar->value = cookiep->value;
			return(0);
		}
		cjar++;
	}
	n++;
	if(n <  cjar->value) {
		n =  cjar->value;
		cjar->tag = cookiep->tag;
		cjar->value = cookiep->value;
		cjar++;
		cjar->tag = 0L;
		cjar->value = n;
		return(0);
	}
	return(ENSMEM);	/* LIST exhausted :-)	*/
}

/* eof ssystem.c	*/
/* @(#)ssystem.h mint/freemint
 * $Id$
 * by jerry g geiger
 *  - jerry@zedat.fu-berlin.de  or jerry@merlin.abacus.de
 * 
 * list of mode/function numbers for
 * long s_system ARGS_ON_STACK  (long mode , void *ptr)
 */
#define HAS_SSYSTEM	0

#define	OSNAME		1
#define	OSVERSION	2
#define	OSDATE		3
#define	MACHINE		4
#define	GETHOSTNAME	5
#define	GETCLOCKT	6
#define	GETCOOKIE	7
#define	SETCOOKIE	8
#define	SETHOSTNAME	9

#define	GETCLOCK	16
	#define	GETICLOCK	17
	#define	GETMCLOCK	18
	#define	GETTCLOCK	19
	#define	GETCLOCKMASK	3
#define	SETCLOCK	20
	#define	SETICLOCK	21
	#define	SETMCLOCK	22
	#define	SETTCLOCK	23
	#define	SETCLOCKMASK	3
/* read/write sys variables:	*/
#define	GETVARCHAR	'GC'
#define	GETVARSHORT	'GS'
#define	GETVARLONG	'GL'
#define	SETVARSHORT	'SS'
#define	SETVARLONG	'SL'
/* mode is any of the five above << 16 | adr
   So any values with
	mode & 0xffff0000 == 'GC'<<16 or 'GS'<<16, 'GL'<<16, 'SS'<<16, 'SL'<<16
   	are reserved !!	
 */

/* eof ssystem.h	*/