dslinux/user/pixil/libs/pixlib .configured Makefile file_access.c linux.c linux_if.c linux_ppp.c linux_wireless.c local_route.h pix_comm_api.c pix_sys_api.c platform.c platform_proto.c sound_api.c sound_dsp.c sysinfo.c timelib.c

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:25:30 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/libs/pixlib
In directory antilope:/tmp/cvs-serv11916/libs/pixlib

Added Files:
	.configured Makefile file_access.c linux.c linux_if.c 
	linux_ppp.c linux_wireless.c local_route.h pix_comm_api.c 
	pix_sys_api.c platform.c platform_proto.c sound_api.c 
	sound_dsp.c sysinfo.c timelib.c 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: timelib.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


/*
**
** Imported "Include" Files
**
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include <pixlib/timelib.h>



/*
**
** Local Variable Declarations
**
*/
static char *full_month_list[] = {
    NULL,
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
};
static char *short_month_list[] = {
    NULL, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
    "Oct", "Nov", "Dec"
};
static char *full_day_list[] = {
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday"
};
static char *short_day_list[] = {
    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"
};
static short reg_days_in_month[] =
    { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static short leap_days_in_month[] =
    { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };



/*
**
** The following function will determine if the specified year is a leap
** year. If it is, a non-zero value is returned. If it is not, zero is
** returned.
**
*/
static int
isLeapYear(unsigned short year)
{
    unsigned short result;

    result = year / 4;
    if ((result * 4) == year)
	return (1);
    else
	return (0);
}



/*
**
** This function will convert the time/date information found in the
** specified 'tm' structure into an pix_sys_date_t strcuture.
**
** The "tstruct" parameter is a pointer to the 'tm' structure. The
** "result" parameter is a pointer to an pix_sys_date_t structure that
** will contain the result.
**
** If successful, '0' is returned. If the time/date specified by the
** 'tm' structure is outside the bounds of an pix_sys_date_t structure, a
** non-zero value is returned.
**
*/
int
pix_sysConvertTMStruct(struct tm *tstruct, pix_sys_date_t * result)
{
    /* convert the structure */
    result->year = tstruct->tm_year + 1900;
    result->month = tstruct->tm_mon + 1;
    result->day = tstruct->tm_mday;
    result->hour = tstruct->tm_hour;
    result->minute = tstruct->tm_min;
    result->second = tstruct->tm_sec;

    /* exit with no errors */
    return (0);
}



/*
**
** This function will initialize an pix_sys_date_t structure with
** the current time and date.
**
** The "result" parameter points to the pix_sys_date_t structure
** that will contain the result.
**
*/
void
pix_sysGetCurrentTime(pix_sys_date_t * result)
{
    time_t tick;
    struct tm *tdata;

    tick = time(NULL);
    tdata = localtime(&tick);
    result->year = tdata->tm_year + 1900;
    result->month = tdata->tm_mon + 1;
    result->day = tdata->tm_mday;
    result->hour = tdata->tm_hour;
    result->minute = tdata->tm_min;
    result->second = tdata->tm_sec;
}



/*
**
** This function will compare the dates found in two pix_sys_date_t
** structures.
**
** The "stamp1" and "stamp2" parameters are pointers to initialized
** pix_sys_date_t structures.
**
** If the first date is earlier than the second, a negative
** value is returned. If the first date is later than the second,
** a positive value is returned. If the two dates are the same,
** '0' is returned.
**
*/
int
pix_sysCompareDates(pix_sys_date_t * stamp1, pix_sys_date_t * stamp2)
{
    /* compare years */
    if (stamp1->year < stamp2->year)
	return (-1);
    if (stamp1->year > stamp2->year)
	return (1);

    /* years are the same - compare months */
    if (stamp1->month < stamp2->month)
	return (-1);
    if (stamp1->month > stamp2->month)
	return (1);

    /* months are the same - compare days */
    if (stamp1->day < stamp2->day)
	return (-1);
    if (stamp1->day > stamp2->day)
	return (1);

    /* dates are the same */
    return (0);
}



/*
**
** The following function will compare the dates and times found
** in two pix_sys_date_t structures.
**
** The "stamp1" and "stamp2" parameters are pointers to initialized
** pix_sys_date_t structures.
**
** If the first timestamp is earlier than the second, a negative
** value is returned. If the first timestamp is later than the
** second, a positive value is returned. If the two timestamps
** are the same, '0' is returned.
**
*/
int
pix_sysCompareTimeStamps(pix_sys_date_t * stamp1, pix_sys_date_t * stamp2)
{
    /* compare years */
    if (stamp1->year < stamp2->year)
	return (-1);
    if (stamp1->year > stamp2->year)
	return (1);

    /* years are the same - compare months */
    if (stamp1->month < stamp2->month)
	return (-1);
    if (stamp1->month > stamp2->month)
	return (1);

    /* months are the same - compare days */
    if (stamp1->day < stamp2->day)
	return (-1);
    if (stamp1->day > stamp2->day)
	return (1);

    /* days are the same - compare hours */
    if (stamp1->hour < stamp2->hour)
	return (-1);
    if (stamp1->hour > stamp2->hour)
	return (1);

    /* hours are the same - compare minutes */
    if (stamp1->minute < stamp2->minute)
	return (-1);
    if (stamp1->minute > stamp2->minute)
	return (1);

    /* minutes are the same - compare seconds */
    if (stamp1->second < stamp2->second)
	return (-1);
    if (stamp1->second > stamp2->second)
	return (1);

    /* timestamps are equal */
    return (0);
}



/*
**
** This function will check to see if the subject timestamp falls
** within the bounds specified by the first and last timestamps.
**
** The "first" and "last" parameters are pointers to initialized
** pix_sys_date_t structures that define the bounds. The "subject"
** parameter is a pointer to an initialized pix_sys_date_t structure
** that specifies the time to be tested.
**
** If the subject timestamp is greater than or equal to the first
** timestamp and is less than or equal to the last timestamp, '0'
** is returned. Otherwise, the subject timestamp is outside of the
** bounds specified and a non-zero value is returned.
**
*/
int
pix_sysCompareBounds(pix_sys_date_t * first, pix_sys_date_t * last,
		     pix_sys_date_t * subject)
{
    if (pix_sysCompareTimeStamps(subject, first) == -1)
	return (-1);
    if (pix_sysCompareTimeStamps(subject, last) == 1)
	return (1);
    return (0);
}



/*
**
** This function will add one day to the date found in a
** pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysIncrementDate(pix_sys_date_t * stamp)
{
    unsigned short lastday;

    /* recover last date for this month */
    if (isLeapYear(stamp->year))
	lastday = leap_days_in_month[stamp->month];
    else
	lastday = reg_days_in_month[stamp->month];

    /* bump the date */
    if (stamp->day + 1 <= lastday) {
	stamp->day += 1;
	return;
    }

    /* date has overflowed - adjust */
    stamp->day = 1;
    stamp->month += 1;

    /* see if month is within bounds */
    if (stamp->month <= 12)
	return;

    /* month has overflowed - adjust */
    stamp->month = 1;
    stamp->year += 1;
}



/*
**
** This function will subtract one day from the date found in a
** pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysDecrementDate(pix_sys_date_t * stamp)
{
    /* bump the date */
    stamp->day -= 1;

    /* see if date is within bounds */
    if (stamp->day > 0)
	return;

    /* date has underflowed - handle special case at beginning of year */
    if (stamp->month == 1) {
	stamp->year -= 1;
	stamp->month = 12;
	stamp->day = 31;
	return;
    }

    /* date has underflowed - adjust */
    stamp->month -= 1;
    if (isLeapYear(stamp->year))
	stamp->day = leap_days_in_month[stamp->month];
    else
	stamp->day = reg_days_in_month[stamp->month];
}



/*
**
** This funtion will add one hour to the date found in an pix_sys_date_t
** structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysIncrementHour(pix_sys_date_t * stamp)
{
    /* bump the hour */
    stamp->hour += 1;

    /* see if hour is within bounds */
    if (stamp->hour < 24)
	return;

    /* hour has overflowed - adjust */
    stamp->hour = 0;
    pix_sysIncrementDate(stamp);
}



/*
**
** This funtion will subtract one hour from the date found in an
** pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysDecrementHour(pix_sys_date_t * stamp)
{
    /* bump the hour */
    stamp->hour -= 1;

    /* see if hour is within bounds */
    if (stamp->hour < 24)
	return;

    /* hour has overflowed - adjust */
    stamp->hour = 23;
    pix_sysDecrementDate(stamp);
}



/*
**
** This funtion will add one minute to the date found in an pix_sys_date_t
** structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysIncrementMinute(pix_sys_date_t * stamp)
{
    /* bump the minute */
    stamp->minute += 1;

    /* see if minute is within bounds */
    if (stamp->minute < 60)
	return;

    /* minute has overflowed - adjust */
    stamp->minute = 0;
    pix_sysIncrementHour(stamp);
}



/*
**
** This funtion will subtract one minute from the date found in an
** pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysDecrementMinute(pix_sys_date_t * stamp)
{
    /* bump the minute */
    stamp->minute -= 1;

    /* see if minute is within bounds */
    if (stamp->minute < 60)
	return;

    /* minute has overflowed - adjust */
    stamp->minute = 59;
    pix_sysDecrementHour(stamp);
}



/*
**
** This funtion will add one second to the date found in an pix_sys_date_t
** structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysIncrementSecond(pix_sys_date_t * stamp)
{
    /* bump the second */
    stamp->second += 1;

    /* see if second is within bounds */
    if (stamp->second < 60)
	return;

    /* second has overflowed - adjust */
    stamp->second = 0;
    pix_sysIncrementMinute(stamp);
}



/*
**
** This funtion will subtract one second from the date found in an
** pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
*/
void
pix_sysDecrementSecond(pix_sys_date_t * stamp)
{
    /* bump the second */
    stamp->second -= 1;

    /* see if second is within bounds */
    if (stamp->second < 60)
	return;

    /* second has overflowed - adjust */
    stamp->second = 59;
    pix_sysDecrementMinute(stamp);
}



/*
**
** This function will calculate what day of the week corresponds
** to the specified pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
** A pointer to the text string that specifies the day of the week
** is returned.
**
*/
char *
pix_sysGetFullDayOfWeek(pix_sys_date_t * stamp)
{
    short d, i, m, y;

    d = stamp->day;
    m = stamp->month;
    y = stamp->year;
    if ((m == 1) || (m == 2)) {
	m += 12;
	--y;
    }
    i = (d + (2 * m) + ((3 * (m + 1)) / 5) + y + (y / 4) - (y / 100) +
	 (y / 400)) % 7;
    return (full_day_list[i]);
}



/*
**
** This function will calculate what day of the week corresponds
** to the specified pix_sys_date_t structure.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
** A pointer to the text string that specifies the day of the week
** is returned.
**
*/
char *
pix_sysGetShortDayOfWeek(pix_sys_date_t * stamp)
{
    short d, i, m, y;

    d = stamp->day;
    m = stamp->month;
    y = stamp->year;
    if ((m == 1) || (m == 2)) {
	m += 12;
	--y;
    }
    i = (d + (2 * m) + ((3 * (m + 1)) / 5) + y + (y / 4) - (y / 100) +
	 (y / 400)) % 7;
    return (short_day_list[i]);
}



/*
**
** This function will recover a pointer to a text string that describes
** the specified month with a three letter abbreviation.
**
** The "month" parameter specifies the month's numeric value.
**
** If successful, a pointer to the text string for the specified month
** is returned. If an error occures during function execution, a pointer
** to an empty string is returned.
**
*/
char *
pix_sysGetShortMonth(unsigned char month)
{
    if ((month < 1) || (month > 12))
	return (NULL);
    else
	return (short_month_list[month]);
}



/*
**
** This function will recover a pointer to a text string that describes
** the specified month.
**
** The "month" parameter specifies the month's numeric value.
**
** If successful, a pointer to the text string for the specified month
** is returned. If an error occures during function execution, a pointer
** to an empty string is returned.
**
*/
char *
pix_sysGetFullMonth(unsigned char month)
{
    if ((month < 1) || (month > 12))
	return (NULL);
    else
	return (full_month_list[month]);
}



/*
**
** This function will recover the number of days in the month specified
** in the associated pix_sys_date_t. Leap year calculations are included.
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure.
**
** If successful, the number of days in the specified month are returned.
** If an error occures during function execution, '0' is returned.
**
*/
int
pix_sysGetDaysInMonth(pix_sys_date_t * stamp)
{
    if ((stamp->month == 0) || (stamp->month > 12))
	return (0);
    if (isLeapYear(stamp->year))
	return (leap_days_in_month[stamp->month]);
    else
	return (reg_days_in_month[stamp->month]);
}



/*
**
** This function will create an ASCIIZ string that represents the date
** and time found in the specified pix_sys_date_t. The resulting string will
** be in one of the following formats:
**
** format=0:   June 27, 2001
** format=1:   June 27, 2001, 10:58 AM
** format=2:   June 27, 2001, 10:58:30 AM
** format=3:   Wednesday, June 27, 2001
** format=4:   Wednesday, June 27, 2001, 10:58 AM
** format=5:   Wednesday, June 27, 2001, 10:58:30 AM
** format=6:   06/27/01
** format=7:   06/27/01 10:58a
** format=8:   06/27/01 10:58:30a
** format=9:   Wed 06/27/01
** format=10:  Wed 06/27/01 10:58a
** format=11:  Wed 06/27/01 10:58:30a
** format=12:  27 Jun 2001
** format=13:  27 Jun 2001 10:58 AM
** format=14:  27 Jun 2001 10:58:00 AM
** format=15:  Wed 27 Jun 2001
** format=16:  Wed 27 Jun 2001 10:58 AM
** format=17:  Wed 27 Jun 2001 10:58:30 AM
** format=18:  10:58 AM
** format=19:  10:58:30 AM
**
** The "stamp" parameter is a pointer to an initialized pix_sys_date_t
** structure. The "format" parameter specifies the string's format.
** The "result" parameter is a pointer to the buffer where the 
** resulting ASCIIZ string will be stored.
**
*/
void
pix_sysGetTimeDateString(pix_sys_date_t * stamp, short format, char *result)
{
    char AP, ap;
    unsigned short hour, year;

    /* do AM/PM conversion */
    hour = stamp->hour;
    if (hour == 0) {
	hour = 12;
	AP = 'A';
	ap = 'a';
    } else if ((hour > 0) && (hour < 12)) {
	AP = 'A';
	ap = 'a';
    } else if (hour == 12) {
	AP = 'P';
	ap = 'p';
    } else {
	hour -= 12;
	AP = 'P';
	ap = 'p';
    }

    /* abbreviate year */
    year = stamp->year % 100;

    /* generate date string */
    switch (format) {
	/* June 27, 2001 */
    case 0:
	sprintf(result,
		"%s %d, %d",
		full_month_list[stamp->month], stamp->day, stamp->year);
	break;

	/* June 27, 2001, 10:58 AM */
    case 1:
	sprintf(result,
		"%s %d, %d, %d:%02d %cM",
		full_month_list[stamp->month],
		stamp->day, stamp->year, hour, stamp->minute, AP);
	break;

	/* June 27, 2001, 10:58:30 AM */
    case 2:
	sprintf(result,
		"%s %d, %d, %d:%02d:%02d %cM",
		full_month_list[stamp->month],
		stamp->day,
		stamp->year, hour, stamp->minute, stamp->second, AP);
	break;

	/* Wednesday, June 27, 2001 */
    case 3:
	sprintf(result,
		"%s, %s %d, %d",
		pix_sysGetFullDayOfWeek(stamp),
		full_month_list[stamp->month], stamp->day, stamp->year);
	break;

	/* Wednesday, June 27, 2001, 10:58 AM */
    case 4:
	sprintf(result,
		"%s, %s %d, %d, %d:%02d %cM",
		pix_sysGetFullDayOfWeek(stamp),
		full_month_list[stamp->month],
		stamp->day, stamp->year, hour, stamp->minute, AP);
	break;

	/* Wednesday, June 27, 2001, 10:58:30 AM */
    case 5:
	sprintf(result,
		"%s, %s %d, %d, %d:%02d:%02d %cM",
		pix_sysGetFullDayOfWeek(stamp),
		full_month_list[stamp->month],
		stamp->day,
		stamp->year, hour, stamp->minute, stamp->second, AP);
	break;

	/* 06/27/01 */
    case 6:
	sprintf(result, "%02d/%02d/%02d", stamp->month, stamp->day, year);
	break;

	/* 06/27/01 10:58a */
    case 7:
	sprintf(result,
		"%02d/%02d/%02d %d:%02d%c",
		stamp->month, stamp->day, year, hour, stamp->minute, ap);
	break;

	/* 06/27/01 10:58:30a */
    case 8:
	sprintf(result,
		"%02d/%02d/%02d %d:%02d:%02d%c",
		stamp->month,
		stamp->day, year, hour, stamp->minute, stamp->second, ap);
	break;

	/*  Wed 06/27/01 */
    case 9:
	sprintf(result,
		"%s %02d/%02d/%02d",
		pix_sysGetShortDayOfWeek(stamp),
		stamp->month, stamp->day, year);
	break;

	/* Wed 06/27/01 10:58a */
    case 10:
	sprintf(result,
		"%s %02d/%02d/%02d %d:%02d%c",
		pix_sysGetShortDayOfWeek(stamp),
		stamp->month, stamp->day, year, hour, stamp->minute, ap);
	break;

	/* Wed 06/27/01 10:58:30a */
    case 11:
	sprintf(result,
		"%s %02d/%02d/%02d %d:%02d:%02d%c",
		pix_sysGetShortDayOfWeek(stamp),
		stamp->month,
		stamp->day, year, hour, stamp->minute, stamp->second, ap);
	break;

	/* 27 Jun 2001 */
    case 12:
	sprintf(result,
		"%d %s %d",
		stamp->day, short_month_list[stamp->month], stamp->year);
	break;

	/* 27 Jun 2001 10:58 AM */
    case 13:
	sprintf(result,
		"%d %s %d %d:%02d %cM",
		stamp->day,
		short_month_list[stamp->month],
		stamp->year, hour, stamp->minute, AP);
	break;

	/* 27 Jun 2001 10:58:00 AM */
    case 14:
	sprintf(result,
		"%d %s %d %d:%02d:%02d %cM",
		stamp->day,
		short_month_list[stamp->month],
		stamp->year, hour, stamp->minute, stamp->second, ap);
	break;

	/* Wed 27 Jun 2001 */
    case 15:
	sprintf(result,
		"%s %d %s %d",
		pix_sysGetShortDayOfWeek(stamp),
		stamp->day, short_month_list[stamp->month], stamp->year);
	break;

	/* Wed 27 Jun 2001 10:58 AM */
    case 16:
	sprintf(result,
		"%s %d %s %d %d:%02d %cM",
		pix_sysGetShortDayOfWeek(stamp),
		stamp->day,
		short_month_list[stamp->month],
		stamp->year, hour, stamp->minute, AP);
	break;

	/* Wed 27 Jun 2001 10:58:30 AM */
    case 17:
	sprintf(result,
		"%s %d %s %d %d:%02d:%02d %cM",
		pix_sysGetShortDayOfWeek(stamp),
		stamp->day,
		short_month_list[stamp->month],
		stamp->year, hour, stamp->minute, stamp->second, AP);
	break;

	/* 10:58 AM */
    case 18:
	sprintf(result, "%d:%02d %cM", hour, stamp->minute, AP);
	break;

	/* 10:58:30 AM */
    case 19:
	sprintf(result,
		"%d:%02d:%02d %cM", hour, stamp->minute, stamp->second, AP);
	break;
    }
}

--- NEW FILE: sound_api.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */



#include <pixlib/pixlib.h>
#include <pixlib/pixio_proto.h>

extern pix_io_functions_t pix_io_functions;

int
pix_io_play_soundfile(int type, char *filename)
{
    switch (type) {
    case PIXIO_WAV_FILE:
	if (pix_io_functions.sysdep_play_wav_file)
	    return (pix_io_functions.sysdep_play_wav_file(filename));
	else
	    return (PIXIO_NOT_IMPLEMENTED);
	break;

    default:
	return (PIXIO_NOT_IMPLEMENTED);
    }
}

int
pix_io_save_sound_file(int type, char *filename, pix_io_audio_t * settings,
		       unsigned char *buffer)
{
    switch (type) {
    case PIXIO_WAV_FILE:
	if (pix_io_functions.sysdep_save_wav_file)
	    return (pix_io_functions.
		    sysdep_save_wav_file(filename, settings, buffer));
	else
	    return (PIXIO_NOT_IMPLEMENTED);
	break;

    default:
	return (PIXIO_NOT_IMPLEMENTED);
    }
}

int
pix_io_load_sound_file(int type, char *filename, pix_io_audio_t * settings,
		       unsigned char *buffer, int size)
{
    switch (type) {
    case PIXIO_WAV_FILE:
	if (pix_io_functions.sysdep_load_wav_file)
	    return (pix_io_functions.
		    sysdep_load_wav_file(filename, settings, buffer, size));
	else
	    return (PIXIO_NOT_IMPLEMENTED);
	break;

    default:
	return (PIXIO_NOT_IMPLEMENTED);
    }
}

int
pix_io_open_stream(int direction, pix_io_audio_t * settings)
{
    if (pix_io_functions.sysdep_open_stream)
	return (pix_io_functions.sysdep_open_stream(direction, settings));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

int
pix_io_stream_record(int fd, unsigned char *buffer, int size)
{
    if (pix_io_functions.sysdep_stream_record)
	return (pix_io_functions.sysdep_stream_record(fd, buffer, size));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

int
pix_io_stream_play(int fd, unsigned char *buffer, int size)
{
    if (pix_io_functions.sysdep_stream_play)
	return (pix_io_functions.sysdep_stream_play(fd, buffer, size));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

int
pix_io_get_wav_stats(char *filename, pix_io_audio_t * settings)
{
    if (pix_io_functions.sysdep_get_wav_stats)
	return (pix_io_functions.sysdep_get_wav_stats(filename, settings));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

int
pix_io_get_mixer_devices(unsigned long *bitmask)
{
    if (pix_io_functions.sysdep_get_mixer_devices)
	return (pix_io_functions.sysdep_get_mixer_devices(bitmask));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

int
pix_io_set_mixer_level(int device, pix_io_level_t * level)
{
    if (pix_io_functions.sysdep_set_mixer_level)
	return (pix_io_functions.sysdep_set_mixer_level(device, level));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

int
pix_io_get_mixer_level(int device, pix_io_level_t * level)
{
    if (pix_io_functions.sysdep_get_mixer_level)
	return (pix_io_functions.sysdep_get_mixer_level(device, level));
    else
	return (PIXIO_NOT_IMPLEMENTED);
}

--- NEW FILE: sound_dsp.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/soundcard.h>

#include <pixlib/pixlib.h>
#include <sound_dsp.h>

#define AUDIO_FILE "/dev/dsp"

/* This array ties the PIXIO_MIXER defines to the */
/* LINUX defines */

static int pix_io2linux_values[PIXIO_MIXER_COUNT] = {
    SOUND_MIXER_VOLUME,
    SOUND_MIXER_BASS,
    SOUND_MIXER_TREBLE,
    SOUND_MIXER_MIC,
    SOUND_MIXER_LINE1,
    SOUND_MIXER_LINE2
};

static int
OpenAudioDevice(int direction)
{
    int omode;
    int fd;

    if (direction == PIXIO_PLAY)
	omode = O_WRONLY;
    else
	omode = O_RDONLY | O_NONBLOCK;

    fd = open(AUDIO_FILE, omode, 0);

    if (fd == -1)
	perror("OPEN_AUDIO");

    return (fd);
}

void
ParseWAVHeader(dspWaveHeader * hdr, pix_io_audio_t * playback)
{
    playback->stereo = (hdr->modus == WAVE_STEREO) ? 1 : 0;
    playback->sample = hdr->bits_per_sample;
    playback->speed = hdr->spd;
    playback->size = hdr->datalen;
}

int
dspStreamRecord(int fd, unsigned char *buffer, int size)
{
    int len = read(fd, buffer, size);

    if (len < 0) {
	if (errno == EAGAIN)
	    return (PIXIO_AGAIN);

	perror("dspStreamRecord");
	return (PIXIO_ERROR);
    }

    return (len);
}

int
dspStreamPlay(int fd, unsigned char *buffer, int size)
{
    int len = write(fd, buffer, size);

    if (len < 0) {
	if (errno == EAGAIN)
	    return (PIXIO_AGAIN);

	perror("PLAY_STREAM");
	return (PIXIO_ERROR);
    }

    return (len);
}

int
dspGetWAVFileStats(char *filename, pix_io_audio_t * settings)
{
    dspWaveHeader wavheader;
    int infd;

    if ((infd = open(filename, O_RDONLY, 0)) == -1) {
	perror("OPEN_WAV");
	return (PIXIO_ERROR);
    }

    /* Read and parse the header */
    if (read(infd, (char *) &wavheader, sizeof(dspWaveHeader))
	< sizeof(dspWaveHeader)) {
	perror("READ_WAV");
	close(infd);
	return (PIXIO_ERROR);
    }

    ParseWAVHeader(&wavheader, settings);
    close(infd);
    return (PIXIO_OK);
}

#define RIFF            0x46464952
#define WAVE            0x45564157
#define FMT             0x20746D66
#define DATA            0x61746164
#define PCM_CODE        1

int
dspWriteWAVFile(char *filename, pix_io_audio_t * settings,
		unsigned char *buffer)
{
    int fd;
    dspWaveHeader hdr;

    hdr.main_chunk = RIFF;
    hdr.length = settings->size + sizeof(dspWaveHeader) - 8;
    hdr.chunk_type = WAVE;
    hdr.sub_chunk = FMT;
    hdr.sc_len = 16;
    hdr.format = PCM_CODE;
    hdr.modus = settings->stereo ? 2 : 1;
    hdr.spd = settings->speed;
    hdr.bytes_per_sample =
	((settings->sample == 8) ? 1 : 2) * (settings->stereo ? 2 : 1);
    hdr.bytes_per_sec = settings->speed * hdr.modus * hdr.bytes_per_sample;
    hdr.bits_per_sample = settings->sample;
    hdr.data_chunk = DATA;
    hdr.datalen = settings->size;

    if ((fd = open(filename, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE)) == -1) {
	perror("OPEN WAV");
	return (PIXIO_ERROR);
    }

    write(fd, &hdr, sizeof(dspWaveHeader));
    write(fd, buffer, settings->size);
    close(fd);
    return (PIXIO_OK);
}

int
dspReadWAVFile(char *filename, pix_io_audio_t * settings,
	       unsigned char *buffer, int maxsize)
{
    int infd, len;
    dspWaveHeader wavheader;

    if ((infd = open(filename, O_RDONLY, 0)) == -1) {
	perror("OPEN WAV");
	return (PIXIO_ERROR);
    }

    /* Read and parse the header */
    if (read(infd, (char *) &wavheader, sizeof(dspWaveHeader))
	< sizeof(dspWaveHeader)) {
	perror("READ WAV");
	close(infd);
	return (PIXIO_ERROR);
    }

    ParseWAVHeader(&wavheader, settings);

    if (settings->size > maxsize) {
	close(infd);
	return (PIXIO_FILE_TOO_BIG);
    }

    len = read(infd, buffer, settings->size);

    if (len == -1 || len != settings->size) {
	if (len == -1)
	    perror("READ WAV");

	close(infd);
	return (PIXIO_ERROR);
    } else {
	close(infd);
	return (len);
    }
}

int
dspPlayWAVFile(char *filename)
{
    int err = PIXIO_ERROR;
    char *audiobuffer;

    dspWaveHeader wavheader;

    int dev = 0;
    int infd = 0;

    pix_io_audio_t playback;

    /* Read the WAV file */

    if ((infd = open(filename, O_RDONLY, 0)) == -1) {
	perror("OPEN WAV");
	return (PIXIO_ERROR);
    }

    /* Read and parse the header */
    if (read(infd, (char *) &wavheader, sizeof(dspWaveHeader))
	< sizeof(dspWaveHeader)) {
	perror("READ WAV");
	close(infd);
	return (PIXIO_ERROR);
    }

    ParseWAVHeader(&wavheader, &playback);

    /* Now open up the stream */
    dev = dspOpenStream(PIXIO_PLAY, &playback);

    if (dev == PIXIO_ERROR) {
	close(infd);
	return (PIXIO_ERROR);
    }

    audiobuffer = (char *) malloc(playback.blocksize);

    while (1) {
	int inlen;

	/* Read a block in from the file */
	inlen = read(infd, (char *) audiobuffer, playback.blocksize);

	if (inlen == -1) {
	    perror("READ_WAV");
	    break;
	}

	if (inlen == 0) {
	    err = PIXIO_OK;	/* No error */
	    break;
	}

	if (write(dev, (char *) audiobuffer, inlen) != inlen) {
	    perror("WRITE_AUDIO");
	    break;
	}

	if (inlen < playback.blocksize) {
	    err = PIXIO_OK;	/* No error */
	    break;
	}
    }

    close(dev);
    close(infd);
    return (err);

    return (err);
}

static int
open_mixer()
{
    int fd;

    fd = open("/dev/mixer", O_RDWR);

    if (fd == -1)
	perror("OPEN_MIXER");

    return (fd);
}

static unsigned long
read_mixer(int device)
{
    int mixer = 0;
    int level = -1;

    if ((mixer = open_mixer()) == -1)
	return (-1);

    if (ioctl(mixer, MIXER_READ(device), &level) == -1) {
	perror("MIXER_READ (IOCTL)");
	level = -1;
    }

    close(mixer);
    return (level);
}

#ifdef NOTUSED

static int
write_mixer(int device, unsigned long level)
{
    int err = -1;
    int mixer = 0;

    if ((mixer = open_mixer()) == -1)
	return (-1);

    if (ioctl(mixer, MIXER_WRITE(device), &level) == -1) {
	perror("MIXER_WRITE (IOCTL)");
	err = -1;
    } else
	err = 0;

    close(mixer);
    return (err);
}
#endif

int
mixer_get_devices(unsigned long *bitmask)
{
    int i, j;
    unsigned long readin;

    if ((readin = read_mixer(SOUND_MIXER_DEVMASK)) == -1)
	return (PIXIO_ERROR);

    *bitmask = 0;

    for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
	if (readin & (1 << i)) {
	    for (j = 0; j < PIXIO_MIXER_COUNT; j++) {
		if (pix_io2linux_values[j] == i)
		    *bitmask |= (1 << j);
	    }
	}
    }

    return (PIXIO_OK);
}

--- NEW FILE: pix_comm_api.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <pixlib/pixlib.h>
#include <pixlib/pix_comm_proto.h>
#include <linux_if.h>
#include <linux_wireless.h>

/* This is a structure (defined elsewhere for each 
 * individual platform), that give us a gateway to the
 * actualy system dependent functions for each API 
 * call 
 */

extern pix_comm_func_t pix_comm_functions;

/*
 * pix_comm_set_ip_address()
 * This function sets the IP settings for the specified interface 
 */

int
pix_comm_set_ip_address(char *ifr, pix_comm_ipaddr_t * ip_addr)
{
    if (pix_comm_functions.sysdep_do_ip_address)
	return (pix_comm_functions.
		sysdep_do_ip_address(PIX_COMM_SET, ifr, ip_addr));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_get_ip_address(char *ifr, pix_comm_ipaddr_t * ip_addr)
{
    if (pix_comm_functions.sysdep_do_ip_address)
	return (pix_comm_functions.
		sysdep_do_ip_address(PIX_COMM_GET, ifr, ip_addr));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

/*
 * pix_comm_set_nameserver()
 * This function sets the nameserver address and domain
 */

int
pix_comm_set_nameserver(char *domain, char *search, unsigned long *addr,
			int acount)
{
    if (pix_comm_functions.sysdep_set_nameserver)
	return (pix_comm_functions.
		sysdep_set_nameserver(domain, search, addr, acount));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

/*
 * pix_comm_add_default_gateway()
 * This function adds a IP default gateway to the system
 */

int
pix_comm_add_default_gateway(unsigned long addr, char *interface)
{
    if (pix_comm_functions.sysdep_do_default_gateway)
	return (pix_comm_functions.
		sysdep_do_default_gateway(PIX_COMM_ADD, &addr, interface));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_remove_default_gateway()
{
    if (pix_comm_functions.sysdep_do_default_gateway)
	return (pix_comm_functions.
		sysdep_do_default_gateway(PIX_COMM_DEL, 0, 0));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_get_default_gateway(unsigned long *addr)
{
    if (pix_comm_functions.sysdep_do_default_gateway)
	return (pix_comm_functions.
		sysdep_do_default_gateway(PIX_COMM_GET, addr, 0));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}


int
pix_comm_ppp_connect(int ctype, pix_comm_ppp_options_t * opts, char **cmds,
		     int cmdcount, int dhcp, char *config)
{
    if (pix_comm_functions.sysdep_ppp_connect)
	return (pix_comm_functions.
		sysdep_ppp_connect(ctype, opts, cmds, cmdcount, dhcp,
				   config));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_ppp_disconnect(char *ifname)
{
    if (pix_comm_functions.sysdep_ppp_disconnect)
	return (pix_comm_functions.sysdep_ppp_disconnect(ifname));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_get_if_list(int filter, pix_comm_interface_t * iflist, int *ifcount)
{
    if (pix_comm_functions.sysdep_get_if_list)
	return (pix_comm_functions.
		sysdep_get_if_list(filter, iflist, ifcount));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_if_active(char *ifname)
{
    if (pix_comm_functions.sysdep_if_active)
	return (pix_comm_functions.sysdep_if_active(ifname));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_if_up(char *ifname, int dhcp)
{
    if (0 == dhcp) {
	if (pix_comm_functions.sysdep_set_if_status)
	    return (pix_comm_functions.
		    sysdep_set_if_status(PIX_COMM_ACTIVE, ifname));
	else
	    return (PIX_COMM_NOT_IMPLEMENTED);
    } else {
	return (linux_if_dhcp(ifname));
	//      if (pix_comm_functions.sysdep_if_dhcp)
	//      return(linux_if_dhcp(ifname));
	//      else
	//      return(PIX_COMM_NOT_IMPLEMENTED);
    }
}

int
pix_comm_if_down(char *ifname)
{
    if (pix_comm_functions.sysdep_set_if_status)
	return (pix_comm_functions.
		sysdep_set_if_status(PIX_COMM_INACTIVE, ifname));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_ppp_get_stats(char *ifname, pix_comm_ppp_stats_t * pppstats)
{
    if (pix_comm_functions.sysdep_ppp_get_stats)
	return (pix_comm_functions.sysdep_ppp_get_stats(ifname, pppstats));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_ppp_write_info(char *filename, pix_comm_ppp_info_t * pppinfo)
{
    if (pix_comm_functions.sysdep_ppp_write_info)
	return (pix_comm_functions.sysdep_ppp_write_info(filename, pppinfo));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_ppp_read_info(char *filename, pix_comm_ppp_info_t * pppinfo)
{
    if (pix_comm_functions.sysdep_ppp_read_info)
	return (pix_comm_functions.sysdep_ppp_read_info(filename, pppinfo));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_ppp_get_ip_info(char *ifname, pix_comm_ppp_options_t * pppoptions)
{
    if (pix_comm_functions.sysdep_ppp_get_ip_info)
	return (pix_comm_functions.
		sysdep_ppp_get_ip_info(ifname, pppoptions));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

/* Wireless Active? */
int
pix_comm_wireless_get_name(char *interface, char *name)
{
    return (wireless_name(interface, name));
    /*
       if (pix_comm_functions.sysdep_wireless_name) {
       //    return(pix_comm_functions.sysdep_wireless_name(interface, name));
       return(wireless_name(interface, name));
       } else {
       return(PIX_COMM_NOT_IMPLEMENTED);
       }
       ******* */

}

/* WEP */
int
pix_comm_wireless_set_encode(char *interface, char *name)
{
    return (wireless_encode(PIX_COMM_SET, interface, name));
    /*
       if (pix_comm_functions.sysdep_wireless_encode)
       return(wireless_encode(PIX_COMM_SET, interface, name));
       else
       return(PIX_COMM_NOT_IMPLEMENTED);
     */
}

int
pix_comm_wireless_get_encode(char *interface, char *name)
{
    return (wireless_encode(PIX_COMM_GET, interface, name));
    /*
       if (pix_comm_functions.sysdep_wireless_encode)
       return(wireless_encode(PIX_COMM_GET, interface, name));
       else
       return(PIX_COMM_NOT_IMPLEMENTED);
     */
}

int
pix_comm_wireless_set_essid(char *interface, char *name)
{
    printf("2: pix_com_wireless_set_essid ... %s\n", name);
    return (wireless_essid(PIX_COMM_SET, interface, name));
    /*
       if (pix_comm_functions.sysdep_wireless_essid)
       return(wireless_essid(PIX_COMM_SET, interface, name));
       else
       return(PIX_COMM_NOT_IMPLEMENTED);
     */
}

int
pix_comm_wireless_get_essid(char *interface, char *name)
{
    return (wireless_essid(PIX_COMM_GET, interface, name));

    /*
       if (pix_comm_functions.sysdep_wireless_essid)
       return(wireless_essid(PIX_COMM_GET, interface, name));
       else
       return(PIX_COMM_NOT_IMPLEMENTED);
     */
}

int
pix_comm_wireless_get_stats(char *interface, pix_comm_wirestats_t * stats)
{
    if (pix_comm_functions.sysdep_wireless_get_stats)
	return (pix_comm_functions.
		sysdep_wireless_get_stats(interface, stats));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_wireless_get_if_list(pix_comm_interface_t * iflist, int *ifcount)
{
    if (pix_comm_functions.sysdep_wireless_get_if_list)
	return (pix_comm_functions.
		sysdep_wireless_get_if_list(iflist, ifcount));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_get_net_value(char *key, char *ret)
{
    if (pix_comm_functions.sysdep_get_net_value)
	return (pix_comm_functions.sysdep_get_net_value(key, ret));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_write_net_values(pix_comm_ipaddr_str_t ip_info,
			  pix_comm_dns_t dns_info)
{
    if (pix_comm_functions.sysdep_write_net_values)
	return (pix_comm_functions.
		sysdep_write_net_values(ip_info, dns_info));
    else
	return (PIX_COMM_NOT_IMPLEMENTED);
}

int
pix_comm_set_netscript_values(char *file, const char *keys[],
			      const char *vals[], int size)
{
    if (0 == linux_set_netscript_values(file, keys, vals, size))
	return (PIX_COMM_OK);
    else
	return (PIX_COMM_ERROR);
}

int
pix_comm_get_netscript_values(char *file, char *keys[], char *vals[],
			      int size)
{
    if (0 == linux_get_netscript_values(file, keys, vals, size))
	return (PIX_COMM_OK);
    else
	return (PIX_COMM_ERROR);
}

--- NEW FILE: platform.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <string.h>

#include <pixlib/pixlib.h>
#include <linux_if.h>

int
pix_set_nameserver(char *domain, char *search, unsigned long *addr,
		   int acount)
{
    /* On the ipaq, we can only write to the /usr/local domain */
    /* so we have a symbolic link from /etc/resolv.conf to     */
    /* /usr/local/etc/resolv.conf, so thats the file we update here */

    return (linux_set_nameserver(RESOLV_FILE, domain, search, addr, acount));
}

int
pix_write_net_values(pix_sys_ipaddr_str_t ip_info, pix_sys_dns_t dns_info)
{
    FILE *net_file;
    unsigned long dns_addr[2];
    int dns_count = 0;
    int ret = 0;

    net_file = fopen(ETH0_FILE, "w");
    if (NULL == net_file) {
	fprintf(stderr, "Unbale to open file %s\n", ETH0_FILE);
	return (PIX_SYS_ERROR);
    }
    fputs("DEVICE=\"eth0\"\n", net_file);
    fputs("NETMASK=\"", net_file);
    fputs(ip_info.netmask, net_file);
    fputs("\"\n", net_file);
    fputs("ONBOOT=\"yes\"\n", net_file);
    if (1 == ip_info.dhcp) {
	fputs("IPADDR=\"\"\n", net_file);
	fputs("BOOTPROTO=\"dhcp\"\n", net_file);
    } else {
	fputs("IPADDR=\"", net_file);
	fputs(ip_info.addr, net_file);
	fputs("\"\n", net_file);
	fputs("BOOTPROTO=\"static\"\n", net_file);
    }
    fclose(net_file);

    if (0 != strcmp("...", dns_info.str_dns_1)) {
	if (0 != strcmp("", dns_info.str_dns_1)) {
	    dns_addr[dns_count] = dns_info.long_dns_1;
	    dns_count++;
	}
    }
    if (0 != strcmp("...", dns_info.str_dns_2)) {
	if (0 != strcmp("", dns_info.str_dns_2)) {
	    dns_addr[dns_count] = dns_info.long_dns_2;
	    dns_count++;
	}
    }
    if (0 != strcmp("...", dns_info.str_dns_3)) {
	if (0 != strcmp("", dns_info.str_dns_3)) {
	    dns_addr[dns_count] = dns_info.long_dns_3;
	    dns_count++;
	}
    }
    ret =
	pix_set_nameserver((char *) dns_info.domain, (char *) dns_info.search,
			   dns_addr, dns_count);

    net_file = fopen(GATEWAY_FILE, "w+");
    if (NULL == net_file) {
	fprintf(stderr, "Unbale to open file %s\n", GATEWAY_FILE);
	return (PIX_SYS_ERROR);
    }
    if (0 == strcmp("...", ip_info.gateway)) {
	fputs("", net_file);
    } else {
	fputs(ip_info.gateway, net_file);
    }
    fclose(net_file);
    return (PIX_SYS_OK);
}

int
pix_get_net_value(char *key, char *ret)
{
    FILE *net_file;
    char buf[255];
    char *str_p;
    char ret_buf[255];
    int len = 0;
    int idx = 0;
    int nameserver = 0;
    int target = 0;

    if (0 == strcasecmp(key, "DHCP")) {
	key = "BOOTPROTO";
	net_file = fopen(ETH0_FILE, "r");
	if (NULL == net_file) {
	    fprintf(stderr, "Unbale to open file %s\n", ETH0_FILE);
	    ret = "";
	    return (PIX_SYS_ERROR);
	}
	goto equal;
    } else {
	net_file = fopen(RESOLV_FILE, "r");
	if (NULL == net_file) {
	    fprintf(stderr, "Unbale to open file %s\n", ETH0_FILE);
	    ret = "";
	    return (PIX_SYS_ERROR);
	}
	goto space;
    }
    ret = "";

  equal:			//has an = for delim
    while (NULL != fgets(buf, sizeof(buf) - 1, net_file)) {
	if ((str_p = strstr(buf, key)) && ('#' != buf[0])) {
	    ret_buf[0] = '\0';
	    str_p = strstr(buf, "=");
	    if (NULL != str_p) {
		str_p++;
		if ('\"' == *str_p) {
		    str_p++;
		    if ('\"' == *str_p || '\n' == *str_p) {
			fclose(net_file);
			ret = "";
			return (PIX_SYS_OK);
		    }
		}
		len = strlen(str_p);
		for (idx = 0; idx < len; idx++) {
		    if (('\"' != *str_p) && ('\n' != *str_p)
			&& (NULL != str_p)) {
			ret_buf[idx] = *str_p;
			str_p++;
		    } else {
			ret_buf[idx] = '\0';
			break;
		    }
		}
	    }
	    fclose(net_file);
	    strncpy(ret, ret_buf, strlen(ret_buf) + 1);
	    if (0 == strcasecmp(key, "BOOTPROTO")) {
		if (0 == strcasecmp(ret, "DHCP")) {
		    strncpy(ret, "Y", strlen(ret_buf) + 1);
		}
	    }
	    break;
	}
    }

  space:			// has a " " space for a delim
    while (NULL != fgets(buf, sizeof(buf) - 1, net_file)) {
	if (0 == strcmp(key, "DNS_1")) {
	    target = 1;
	    key = "nameserver";
	}
	if (0 == strcmp(key, "DNS_2")) {
	    target = 2;
	    key = "nameserver";
	}
	if (0 == strcmp(key, "DNS_3")) {
	    target = 3;
	    key = "nameserver";
	}
	if (0 == strncasecmp(key, buf, strlen(key))) {
	    if (0 == strcmp(key, "nameserver")) {
		nameserver++;
		if (nameserver != target) {
		    continue;
		}
	    }
	    idx = 1;
	    str_p = strstr(buf, " ");
	    if (NULL != str_p) {
		str_p++;
		len = strlen(str_p);
		for (idx = 0; idx < len; idx++) {
		    ret_buf[idx] = *str_p;
		    str_p++;
		}
	    }
	    ret_buf[idx - 1] = '\0';
	    fclose(net_file);
	    strncpy(ret, ret_buf, strlen(ret_buf) + 1);
	    return (PIX_SYS_OK);
	}
    }
    return (PIX_SYS_OK);
}

--- NEW FILE: local_route.h ---
/* Copyright (C) 1997 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The GNU C Library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* Based on the 4.4BSD and Linux version of this file.  */

#ifndef _NET_ROUTE_H
#define _NET_ROUTE_H	1

#include <features.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>


/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
struct rtentry
{
    unsigned long int rt_pad1;
    struct sockaddr rt_dst;	/* Target address.  */
    struct sockaddr rt_gateway;	/* Gateway addr (RTF_GATEWAY).  */
    struct sockaddr rt_genmask;	/* Target network mask (IP).  */
    unsigned short int rt_flags;
    short int rt_pad2;
    unsigned long int rt_pad3;
    unsigned char rt_tos;
    unsigned char rt_class;
    short int rt_pad4;
    short int rt_metric;	/* +1 for binary compatibility!  */
    char *rt_dev;		/* Forcing the device at add.  */
    unsigned long int rt_mtu;	/* Per route MTU/Window.  */
    unsigned long int rt_window;	/* Window clamping.  */
    unsigned short int rt_irtt;	/* Initial RTT.  */
};
/* Compatibility hack.  */
#define rt_mss	rt_mtu


struct in6_rtmsg
{
    struct in6_addr rtmsg_dst;
    struct in6_addr rtmsg_src;
    struct in6_addr rtmsg_gateway;
    u_int32_t rtmsg_type;
    u_int16_t rtmsg_dst_len;
    u_int16_t rtmsg_src_len;
    u_int32_t rtmsg_metric;
    unsigned long int rtmsg_info;
    u_int32_t rtmsg_flags;
    int rtmsg_ifindex;
};


#define	RTF_UP		0x0001	/* Route usable.  */
#define	RTF_GATEWAY	0x0002	/* Destination is a gateway.  */

#define	RTF_HOST	0x0004	/* Host entry (net otherwise).  */
#define RTF_REINSTATE	0x0008	/* Reinstate route after timeout.  */
#define	RTF_DYNAMIC	0x0010	/* Created dyn. (by redirect).  */
#define	RTF_MODIFIED	0x0020	/* Modified dyn. (by redirect).  */
#define RTF_MTU		0x0040	/* Specific MTU for this route.  */
#define RTF_MSS		RTF_MTU	/* Compatibility.  */
#define RTF_WINDOW	0x0080	/* Per route window clamping.  */
#define RTF_IRTT	0x0100	/* Initial round trip time.  */
#define RTF_REJECT	0x0200	/* Reject route.  */
#define	RTF_STATIC	0x0400	/* Manually injected route.  */
#define	RTF_XRESOLVE	0x0800	/* External resolver.  */
#define RTF_NOFORWARD   0x1000	/* Forwarding inhibited.  */
#define RTF_THROW	0x2000	/* Go to next class.  */
#define RTF_NOPMTUDISC  0x4000	/* Do not send packets with DF.  */

/* for IPv6 */
#define RTF_DEFAULT	0x00010000	/* default - learned via ND     */
#define RTF_ALLONLINK	0x00020000	/* fallback, no routers on link */
#define RTF_ADDRCONF	0x00040000	/* addrconf route - RA          */

#define RTF_LINKRT	0x00100000	/* link specific - device match */
#define RTF_NONEXTHOP	0x00200000	/* route with no nexthop        */

#define RTF_CACHE	0x01000000	/* cache entry                  */
#define RTF_FLOW	0x02000000	/* flow significant route       */
#define RTF_POLICY	0x04000000	/* policy route                 */

#define RTCF_VALVE	0x00200000
#define RTCF_MASQ	0x00400000
#define RTCF_NAT	0x00800000
#define RTCF_DOREDIRECT 0x01000000
#define RTCF_LOG	0x02000000
#define RTCF_DIRECTSRC	0x04000000

#define RTF_LOCAL	0x80000000
#define RTF_INTERFACE	0x40000000
#define RTF_MULTICAST	0x20000000
#define RTF_BROADCAST	0x10000000
#define RTF_NAT		0x08000000

#define RTF_ADDRCLASSMASK	0xF8000000
#define RT_ADDRCLASS(flags)	((__u_int32_t) flags >> 23)

#define RT_TOS(tos)		((tos) & IPTOS_TOS_MASK)

#define RT_LOCALADDR(flags)	((flags & RTF_ADDRCLASSMASK) \
				 == (RTF_LOCAL|RTF_INTERFACE))

#define RT_CLASS_UNSPEC		0
#define RT_CLASS_DEFAULT	253

#define RT_CLASS_MAIN		254
#define RT_CLASS_LOCAL		255
#define RT_CLASS_MAX		255


#define RTMSG_ACK		NLMSG_ACK
#define RTMSG_OVERRUN		NLMSG_OVERRUN

#define RTMSG_NEWDEVICE		0x11
#define RTMSG_DELDEVICE		0x12
#define RTMSG_NEWROUTE		0x21
#define RTMSG_DELROUTE		0x22
#define RTMSG_NEWRULE		0x31
#define RTMSG_DELRULE		0x32
#define RTMSG_CONTROL		0x40

#define RTMSG_AR_FAILED		0x51	/* Address Resolution failed.  */

#endif /* net/route.h */

--- NEW FILE: Makefile ---
# libs/pim/Makefile

platform-y=

platform-$(CONFIG_PLATFORM_X86DEMO)=platform/x86
platform-$(CONFIG_PLATFORM_IPAQ)=platform/ipaq
platform-$(CONFIG_PLATFORM_ZAURUS)=platform/zaurus
platform-$(CONFIG_PLATFORM_TUXSCREEN)=platform/tuxscreen

LIB_STATIC=libpixil.a
LIB_SHARED=libpixil.so

INCLUDES+=-I./include

SRC=${shell ls *.c} ${shell ls $(platform-y)/*.c}
OBJS=${SRC:.c=.o}

include $(BASE_DIR)/Rules.make




--- NEW FILE: sysinfo.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */



/* Feature test switches */


/* System header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Local header files */
#include <pixlib/pixlib.h>


/* Typedef, macro, enum/struct/union definitions */


/* Global scope variables */


/* Static scope variables */


/* Static function prototypes */

/*******************************************************************************\
**
**	Static function definitions
**
\*******************************************************************************/

/*******************************************************************************\
**
**	External Function definitions
**
\*******************************************************************************/

/*******************************************************************************\
**
**	Function:	int pix_sys_meminfo()
**	Desc:		Gets the system memory information from the /proc/meminfo file
**	Accepts:	struct pixMemInfo_t *pmi = Ptr to memory information
**	Returns:	int; 0 on success, -1 on error
**
\*******************************************************************************/
int
pix_sys_meminfo(pixMemInfo_t * pmi)
{
    char membuf[512];		/* Memory Buffer */
    int rc = -1;		/* Return code */
    unsigned long a, b, c, d, e, f;
    FILE *fp;			/* File pointer */

    if (pmi == NULL)
	return (rc);

    memset(pmi, 0, sizeof(pixMemInfo_t));

    if ((fp = fopen("/proc/meminfo", "r")) == NULL)
	return (rc);


    /* Parse the data */
    fgets(membuf, sizeof(membuf), fp);
    if (fscanf(fp, "%*s %ld %ld %ld %ld %ld %ld", &a, &b, &c, &d, &e, &f) > 0) {
	pmi->mtotal = a;
	pmi->mused = b;
	pmi->mfree = c;
	pmi->mshare = d;
	pmi->mbuffer = e;
	pmi->mcache = f;
	if (fscanf(fp, "%*s %ld %ld %ld", &a, &b, &c) > 0) {
	    pmi->stotal = a;
	    pmi->sused = b;
	    pmi->sfree = c;
	    rc = 0;
	}			/* end of if */
    }
    /* end of if */
    fclose(fp);

    return (rc);
}				/* end of pix_sys_meminfo() */

/*******************************************************************************\
**
**	Function:	int pix_sys_osinfo()
**	Desc:		Returns OS information
**	Accepts:	struct utsname *punm = Ptr to the structure to fill in
**	Returns:	int; 0 on success, -1 on error
**
\*******************************************************************************/
int
pix_sys_osinfo(struct utsname *punm)
{
    if (punm == NULL)
	return (-1);

    return (uname(punm));
}				/* end of pix_osinfo() */

/*******************************************************************************\
**
**	Function:	int pix_sys_pcmciainfo()
**	Desc:		Returns information from the card manager (cardmgr) concerning the
**				status of the PCMIA sockets
**	Accepts:	pixPCMCIAInfo_t *ppi = Ptr to the PCMCIA info struct
**	Returns:	int; 0 on success, -1 on error
**
\*******************************************************************************/
int
pix_sys_pcmciainfo(pixPCMCIAInfo_t * ppi)
{
    char cardbuf[256],		/* read buffer */
     *cardpath = NULL,		/* Ptr to the card path */
     *cardopts[2] = { "/var/run/stab",
	"/var/lib/pcmcia/stab"
    };
    int rc = -1;		/* Default return code */
    FILE *fp = 0;		/* File pointer */

    /* Determine the validity of the arguments */
    if (ppi == NULL)
	return (rc);

    /* Determine the path of the file */
    if ((cardpath = getenv("CARD_STAB")) == NULL
	|| (fp = fopen(cardpath, "r")) == NULL) {
	int idx;

	for (idx = 0; idx < 2; idx++) {
	    cardpath = cardopts[idx];
	    if ((fp = fopen(cardpath, "r")) != NULL)
		break;
	}			/* end of for */
    }
    /* end of if */
    if (fp == NULL)
	return (rc);

    /* Now parse the data */
    while (fgets(cardbuf, sizeof(cardbuf), fp) != NULL) {
	int len = strlen(cardbuf);

	if (cardbuf[len - 1] == '\n')
	    cardbuf[--len] = '\0';

	if (!memcmp(cardbuf, "Socket 0:", 9)) {
	    strcpy(ppi->socket0, cardbuf);
	    rc++;
	} /* end if of */
	else if (!memcmp(cardbuf, "Socket 1:", 9)) {
	    strcpy(ppi->socket1, cardbuf);
	    rc++;
	}			/* end of else if */
    }				/* end of while */

    fclose(fp);

    /* Normalize the return value */
    if (rc > -1)
	rc = 0;

    return (rc);
}				/* end of pix_sys_pcmciainfo() */

--- NEW FILE: linux.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

#include <sys/time.h>
#include <sys/types.h>

#include <pixlib/pixlib.h>
#include <linux.h>

/*
 * linux_set_date(date_struct)
 * Set the system date based on the passed structure
 */

int
linux_set_date(pix_sys_date_t * date_struct)
{
    struct tm newtm;
    time_t newtime;
    struct timeval tv;

    if (!date_struct)
	return (PIX_SYS_ERROR);

    newtm.tm_sec = date_struct->second;
    newtm.tm_min = date_struct->minute;
    newtm.tm_hour = date_struct->hour;

    newtm.tm_mday = date_struct->day;
    newtm.tm_mon = date_struct->month - 1;
    newtm.tm_year = date_struct->year - 1900;

    newtime = mktime(&newtm);

    if (newtime == -1)
	return (PIX_SYS_ERROR);

    tv.tv_sec = newtime;

    if (settimeofday(&tv, NULL) == -1) {
	if (errno == EPERM)
	    return (PIX_SYS_NOT_SUPERUSER);
	else
	    return (PIX_SYS_ERROR);
    }

    return (PIX_SYS_OK);
}

/*
 * linux_get_date(date_struct) 
 * Return the current system date / time 
 */

int
linux_get_date(pix_sys_date_t * date_struct)
{
    pix_sysGetCurrentTime(date_struct);
    return (PIX_SYS_OK);
}

/*
 * linux_get_cpu_load(cpu_struct)
 * Get the current cpu loads (in jiffies) 
 */

int
linux_get_cpu_load(pix_sys_cpu_t * cpu_struct)
{
    int fd;
    char str[BUFSIZ];
    char *c;

    /* Open up the file */
    fd = open("/proc/stat", O_RDONLY);

    if (fd == -1) {
	perror("linux_get_cpu_load");
	return (PIX_SYS_FILE_ERROR);
    }

    read((int) fd, str, BUFSIZ - 1);

    /* Now skip over "cpu" */
    for (c = str; *c != ' '; c++)
	continue;

    c++;

    /* Get the new values */

    cpu_struct->user = strtoul(c, &c, 0);
    cpu_struct->nice = strtoul(c, &c, 0);
    cpu_struct->system = strtoul(c, &c, 0);
    cpu_struct->idle = strtoul(c, &c, 0);

    close(fd);
    return (PIX_SYS_OK);
}

/*
 * linux_get_memory_usage(mem_struct)
 * Get the current memory usage  
 */

int
linux_get_memory_usage(pix_sys_memory_t * mem_struct)
{
    int fd;
    char str[BUFSIZ];
    char *c;

    /* Open up the file */
    fd = open("/proc/meminfo", O_RDONLY);

    if (fd == -1) {
	perror("linux_get_memory_usage");
	return (PIX_SYS_FILE_ERROR);
    }

    read((int) fd, str, BUFSIZ - 1);

    /* Completely skip the first line */
    for (c = str; *c != '\n'; c++);

    /* Now, parse the line to get all of the good stuff */
    for (c++; *c != ' '; c++);

    /* Now skip over any whitespace to get to the first number */
    for (; *c == ' '; c++);

    /* Now read each number, and put it directly into the passed */
    /* memory struct */

    mem_struct->total = strtoul(c, &c, 0);
    mem_struct->used = strtoul(c, &c, 0);
    mem_struct->free = strtoul(c, &c, 0);
    mem_struct->shared = strtoul(c, &c, 0);
    mem_struct->buffers = strtoul(c, &c, 0);
    mem_struct->cached = strtoul(c, &c, 0);

    /* Skip to the next line */
    for (; *c != '\n'; c++);
    for (c++; *c != ' '; c++);
    for (; *c == ' '; c++);

    mem_struct->stotal = strtoul(c, &c, 0);
    mem_struct->sused = strtoul(c, &c, 0);

    close(fd);

    return (PIX_SYS_OK);
}

--- NEW FILE: .configured ---

--- NEW FILE: file_access.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <pixlib/pixlib.h>

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>


// If you want more type names to associate with directories add them here.
nxFSlist FStypes[] = { {"Memory Card", "cf"}
,
{"Local", "local"}
,
{"CD-ROM", "cdrom"}
,
{"", ""}
};

// This returns the offset into FStypes[] of the present type -1 on error
int
get_devtype(const char *input)
{
    int i, o;
    char path[10];
    memset(path, '\0', 10);
    o = 0;
    for (i = 0; i < 20; i++) {
	if (input[i] == '/') {
	    o++;
	    if (o == 3) {
		path[i] = '\0';
		break;
	    }
	}
	if (o == 2)
	    path[i] = input[i];
    }
    if (o < 3)
	return -1;
    for (i = 0; FStypes[i].name[0]; i++) {
	if (!strcmp(path, FStypes[i].path))
	    return i;
    }
    return -1;
}

char *
nxFSgettwd(void)
{
    static char dirbuff[128];
    char gpbuff[128];
    char dnbuff[5];
    char *bptr;
    int i;
    int devtype;
    int devnum;
    memset(dnbuff, '\0', 5);
    if ((devtype = get_devtype(getcwd(gpbuff, 128))) == -1)
	return "path_error";
    bptr = strchr(strchr(strchr(gpbuff, '/') + 1, '/') + 1, '/') + 1;
    for (i = 0; i < 5; i++) {
	dnbuff[i] = bptr[i];
	if (dnbuff[i] == '/')
	    dnbuff[i] = '\0';
    }
    devnum = atoi(dnbuff);
    sprintf(dirbuff, "%s %i %s", &FStypes[devtype].name[0], devnum,
	    &bptr[i - 1]);
    return dirbuff;

}


// this does damage the string by adding a NULL
char *
get_mtabpath(char *str)
{
    int i;
    char *ret;
    ret = strchr(strchr(str, ' '), '/');
    i = 0;
    while (ret[i] != ' ') {
	i++;
    }
    ret[i] = '\0';
    return ret;
}

// this function takes list as a null pointer.  Free it later
int
xnFSgetfslist(nxFSlist ** list)
{
    FILE *mtabf;
    nxFSlist *tmplist;
    nxFSlist *retlist;
    char mtab_line[80];
    char *resbuf;
    char *ptrbuf;
    char dnbuff[5];
    int entries;
    int i, o;
    memset(dnbuff, '\0', 5);
    if ((mtabf = fopen("/etc/mtab", "r")) == NULL)
	return -1;
    tmplist = malloc(sizeof(nxFSlist) * 20);
    for (entries = 0;;) {
	if ((resbuf = fgets(mtab_line, 80, mtabf)) == NULL)
	    break;
	ptrbuf = get_mtabpath(resbuf);
	if ((i = get_devtype(ptrbuf)) > -1) {
	    resbuf =
		strchr(strchr(strchr(ptrbuf, '/') + 1, '/') + 1, '/') + 1;
	    for (o = 0; o < 5; o++) {
		dnbuff[o] = resbuf[o];
		if (dnbuff[o] == '/')
		    dnbuff[o] = '\0';
	    }
	    o = atoi(dnbuff);
	    sprintf(tmplist[entries].name, "%s %i", FStypes[i].name, o);
	    sprintf(tmplist[entries].path, "%s", ptrbuf);
	    entries++;
	}
    }
    retlist = malloc(sizeof(nxFSlist) * entries);
    for (i = 0; i < entries; i++) {
	strcpy(retlist[i].name, tmplist[i].name);
	strcpy(retlist[i].path, tmplist[i].path);
    }
    *list = retlist;
    fclose(mtabf);
    free(tmplist);
    return entries;
}

--- NEW FILE: linux_if.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>

#include "local_route.h"
#include <pixlib/pixlib.h>

/****** UTILITY FUNCTIONS *******/

int
linux_open_socket(void)
{
    int fd;

    /* Open up a socket so we can communicate */
    fd = socket(AF_INET, SOCK_DGRAM, 0);

    if (fd < 0)
	perror("OPEN_SOCKET (SOCKET)");

    return (fd);
}

static int
resolve(char *name, struct sockaddr_in *sin)
{
    sin->sin_family = AF_INET;
    sin->sin_port = 0;
    if (!strcmp("default", name)) {
	sin->sin_addr.s_addr = INADDR_ANY;
	return (1);
    }
    if (inet_aton(name, &sin->sin_addr)) {
	return 0;
    }
    return 0;
}

void
linux_set_sockaddr(struct sockaddr *insock,
		   unsigned long addr, unsigned short port)
{
    struct sockaddr_in *sock = (struct sockaddr_in *) insock;

    sock->sin_family = AF_INET;
    sock->sin_addr.s_addr = addr;
    sock->sin_port = port;
}

int
get_if_flags(char *ifname, unsigned long *flags)
{
    int err = 0;
    int fd;
    struct ifreq ifr;

    /* Open up a socket so we can communicate */
    if ((fd = linux_open_socket()) < 0)
	return (-1);

    memset(&ifr, 0, sizeof(ifr));

    /* Copy the interface name over */
    strcpy(ifr.ifr_name, ifname);

    if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
	perror("GET_IF_FLAGS (IOCTL)");
	*flags = 0;
	err = -1;
    } else {
	*flags = ifr.ifr_flags;
    }

    close(fd);
    return (err);
}

static int
set_if_flags(char *ifname, unsigned long flags)
{
    int err = 0;
    int fd;
    struct ifreq ifr;

    /* Open up a socket so we can communicate */

    if ((fd = linux_open_socket()) < 0)
	return (-1);

    memset(&ifr, 0, sizeof(ifr));

    /* Copy the interface name over */
    strcpy(ifr.ifr_name, ifname);
    ifr.ifr_flags = flags;

    if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
	perror("SET_IF_FLAGS (IOCTL)");
	err = -1;
    }

    close(fd);
    return (err);
}

int
linux_do_ip_address(int command, char *ifname, pix_comm_ipaddr_t * ipaddr)
{
    int err = PIX_COMM_IPADDR_ERROR;
    int fd;
    struct ifreq ifr;
    struct sockaddr_in *sin = (void *) &ifr.ifr_addr;

    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, ifname);

    /* Open up a socket so we can communicate */
    if ((fd = linux_open_socket()) < 0)
	return (PIX_COMM_ERROR);

    switch (command) {
    case PIX_COMM_SET:
	linux_set_sockaddr((struct sockaddr *) sin, htonl(ipaddr->addr), 0);
	if (ioctl(fd, SIOCSIFADDR, &ifr) < 0) {
	    perror("SET_IP_ADDR (IOCTL)");
	    break;
	}

	linux_set_sockaddr((struct sockaddr *) sin, htonl(ipaddr->netmask),
			   0);
	if (ioctl(fd, SIOCSIFNETMASK, &ifr) < 0) {
	    perror("SET_IP_ADDR (IOCTL)");
	    break;
	}

	linux_set_sockaddr((struct sockaddr *) sin, htonl(ipaddr->broadcast),
			   0);
	if (ioctl(fd, SIOCSIFBRDADDR, &ifr) < 0) {
	    perror("SET_IP_ADDR (IOCTL)");
	    break;
	}

	err = PIX_COMM_OK;
	break;

    case PIX_COMM_GET:
	if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
	    perror("GET_IP_ADDR (IOCTL)");
	    break;
	}

	ipaddr->addr = ntohl(sin->sin_addr.s_addr);

	if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) {
	    perror("GET_IP_ADDR (IOCTL)");
	    break;
	}

	ipaddr->netmask = ntohl(sin->sin_addr.s_addr);

	if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0) {
	    perror("GET_IP_ADDR (IOCTL)");
	    break;
	}

	ipaddr->broadcast = ntohl(sin->sin_addr.s_addr);

	err = PIX_COMM_OK;
	break;

    default:
	err = PIX_COMM_INVALID;
	break;
    }

    close(fd);
    return (err);
}

/* Local flags not used by the outside world */

#define DEFAULT_GATEWAY 0x01

static int
linux_add_route(unsigned long addr, unsigned long netmask,
		unsigned long gateway, char *interface)
{
    int err = PIX_COMM_OK;

    int fd;
    struct rtentry rm;
    char name[15];


    memset((char *) &rm, 0, sizeof(struct rtentry));

    rm.rt_flags = (RTF_UP | RTF_HOST);
    if (addr) {
	rm.rt_flags = RTF_HOST;
	linux_set_sockaddr(&(rm.rt_dst), addr, 0);
	linux_set_sockaddr(&(rm.rt_genmask), netmask, 0);
    } else {
	struct sockaddr mask;
	sprintf(name, "default");
	resolve(name, (struct sockaddr_in *) (&rm.rt_dst));
	sprintf(name, "%d.%d.%d.%d",
		(unsigned char) (gateway >> 24) & 0xFF,
		(unsigned char) (gateway >> 16) & 0xFF,
		(unsigned char) (gateway >> 8) & 0xFF,
		(unsigned char) gateway & 0xFF);
	resolve(name, (struct sockaddr_in *) (&rm.rt_gateway));
	resolve("0.0.0.0", (struct sockaddr_in *) (&mask));
	rm.rt_genmask = mask;
	rm.rt_flags &= ~RTF_HOST;
    }

    //linux_set_sockaddr(&(rm.rt_gateway), gateway, 0);

    if (gateway)
	rm.rt_flags |= RTF_GATEWAY;

    if (interface) {
	if (NULL == rm.rt_dev) {
	    rm.rt_dev = (char *) calloc(strlen(interface), sizeof(char));
	}
	strcpy(rm.rt_dev, interface);
    } else
	rm.rt_dev = "lo";

    /* Open up a socket so we can communicate */
    if ((fd = linux_open_socket()) < 0)
	return (PIX_COMM_ERROR);

    if (ioctl(fd, SIOCADDRT, &rm) < 0) {
	perror("ADD_ROUTE (IOCTL)");
	err = PIX_COMM_ERROR;
    }

    close(fd);
    if (NULL != rm.rt_dev) {
	free(rm.rt_dev);
    }
    return (err);
}

static int
linux_delete_route(unsigned long addr)
{
    int err = PIX_COMM_OK;
    int fd;
    struct rtentry rm;

    memset(&rm, 0, sizeof(rm));
    linux_set_sockaddr((struct sockaddr *) &rm.rt_dst, addr, 0);

    /* Open up a socket so we can communicate */
    if ((fd = linux_open_socket()) < 0)
	return (PIX_COMM_ERROR);

    if (ioctl(fd, SIOCDELRT, &rm) < 0) {
	perror("DEL_ROUTE (IOCTL)");
	err = PIX_COMM_ERROR;
    }

    close(fd);
    return (err);
}

#define ROUTE_PROC_FILE "/proc/net/route"

/* Here, gw is the returned value for addr */

static int
linux_get_route(unsigned long *gw, unsigned long addr)
{
    char buffer[BUFSIZ];

    FILE *wfile = fopen(ROUTE_PROC_FILE, "r");

    if (!wfile) {
	perror("GET_ROUTE (OPEN)");
	return (PIX_COMM_ERROR);
    }

    /* Skip the first line */
    fgets(buffer, BUFSIZ, wfile);

    /* Now, go through all the routes until we find the one that matches the flags */

    while (1) {
	char iface[15];
	unsigned long daddr, gaddr;
	int inflags;

	if (feof(wfile))
	    break;

	fgets(buffer, BUFSIZ, wfile);

	/* sscanf(buffer, "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t08lX\t%d\t%u\t%d\n",
	   iface, &daddr, &addr); */

	sscanf(buffer, "%s\t%08lX\t%08lX\%8X",
	       iface, &daddr, &gaddr, &inflags);

	if (daddr == addr && (inflags & RTF_UP)) {
	    *gw = ntohl(gaddr);

	    fclose(wfile);
	    return (PIX_COMM_OK);
	}
    }

    fclose(wfile);
    return (PIX_COMM_ERROR);
}

int
linux_do_default_gateway(int command, unsigned long *addr, char *interface)
{
    unsigned long inaddr;

    switch (command) {
    case PIX_COMM_ADD:
	return (linux_add_route(0, 0, *addr, interface));

    case PIX_COMM_DEL:
	if (linux_get_route(&inaddr, 0) == PIX_COMM_ERROR)
	    return (PIX_COMM_ERROR);

	return (linux_delete_route(inaddr));
	break;

    case PIX_COMM_GET:
	return (linux_get_route(addr, 0));

    default:
	return (PIX_COMM_INVALID);
    }
}

int
linux_set_nameserver(char *filen, char *domain, char *search,
		     unsigned long *addr, int addrcount)
{
    int i;

    char outbuf[256];

    /* Open up the specified file */
    int fd = open(filen, O_RDWR | O_TRUNC);

    if (fd == -1)
	return (PIX_COMM_ERROR);

    if (0 != strcmp("", domain)) {
	sprintf(outbuf, "domain %s\n", domain);
	write(fd, outbuf, strlen(outbuf));
    }
    if (0 != strcmp("", search)) {
	sprintf(outbuf, "search %s\n", search);
	write(fd, outbuf, strlen(outbuf));
    }

    /* Now start writing all of the nameserver information out */

    for (i = 0; i < addrcount; i++) {
	sprintf(outbuf, "nameserver %d.%d.%d.%d\n",
		(unsigned char) (addr[i] >> 24) & 0xFF,
		(unsigned char) (addr[i] >> 16) & 0xFF,
		(unsigned char) (addr[i] >> 8) & 0xFF,
		(unsigned char) addr[i] & 0xFF);

	write(fd, outbuf, strlen(outbuf));
    }

    close(fd);
    return (PIX_COMM_OK);
}

int
linux_if_active(char *ifname)
{
    unsigned long flags;

    if (get_if_flags(ifname, &flags) == -1)
	return (PIX_COMM_INACTIVE);

    if (!(flags & IFF_UP))
	return (PIX_COMM_INACTIVE);
    else
	return (PIX_COMM_ACTIVE);
}

int
linux_if_dhcp(char *ifname)
{
    pid_t childpid;
    int err = 0;
    int child_status;
    int idx;

    if ((childpid = fork()) == -1) {
	perror("IF_DHCP (FORK)");
	return (PIX_COMM_ERROR);
    } else if (childpid == 0)	// in child
    {
	for (idx = 3; idx < 20; idx++)
	    close(idx);
	//      err = execl("/sbin/pump", "/sbin/pump", "-i", ifname, NULL);

	//      err = execl("/bin/sh", "/bin/sh" "/etc/sysconfig/network-scripts/ifup", ifname, NULL);

	err =
	    execl("/bin/sh", "sh", "/etc/sysconfig/network-scripts/ifup",
		  ifname, NULL);

	//      err = execl("/bin/sh", "sh");

	if (0 > err)
	    perror("IF_DHCP (EXECL)");
	exit(1);
    } else			//in parent
    {
	wait(&child_status);
	if (PIX_COMM_INACTIVE == linux_if_active(ifname))
	    return (PIX_COMM_ERROR);
	else
	    return (PIX_COMM_OK);
    }
}

int
linux_set_if_status(int status, char *ifname)
{
    unsigned long flags;
    pid_t childpid;
    int err = 0;
    int child_status;
    int idx;

    if (get_if_flags(ifname, &flags) == -1)
	return (PIX_COMM_ERROR);

    if (status == PIX_COMM_ACTIVE)
	flags |= IFF_UP;
    else
	flags &= ~IFF_UP;

    if ((childpid = fork()) == -1) {
	perror("IF_DHCP (FORK)");
	return (PIX_COMM_ERROR);
    } else if (childpid == 0)	// in child
    {
	for (idx = 3; idx < 20; idx++)
	    close(idx);
	//      err = execl("/sbin/pump", "/sbin/pump", "-i", ifname, NULL);

	//      err = execl("/bin/sh", "/bin/sh" "/etc/sysconfig/network-scripts/ifup", ifname, NULL);
	printf("ifdown *******\n");
	err =
	    execl("/bin/sh", "sh", "/etc/sysconfig/network-scripts/ifdown",
		  ifname, NULL);

	//      err = execl("/bin/sh", "sh");

	if (0 > err)
	    perror("IF_DHCP (EXECL)");
	exit(1);
    } else			//in parent
    {
	wait(&child_status);
	return (set_if_flags(ifname, flags));
    }
}

int
linux_get_if_list(int type, pix_comm_interface_t * iflist, int *ifcount)
{
    int retcount = -1;
    int err = PIX_COMM_ERROR;
    int fd, n;
    struct ifconf ifc;
    struct ifreq *ifr;

    int maxreq = *ifcount;	/* Maximum number of interfaces to return */

    /* We want to return a list of interfaces and some stats */
    fd = socket(PF_INET, SOCK_DGRAM, 0);

    if (fd == -1) {
	perror("GET_IF_LIST (SOCKET)");
	return (PIX_COMM_ERROR);
    }

    ifc.ifc_len = sizeof(struct ifreq) * maxreq;
    ifc.ifc_buf = (char *) malloc(ifc.ifc_len);

    if (!ifc.ifc_buf)
	return (PIX_COMM_ERROR);

    if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
	perror("GET_IF_LIST (IOCTL)");
	err = PIX_COMM_ERROR;
	goto out;
    }

    /* Now, go through and get the interface flags */

    ifr = ifc.ifc_req;

    for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq), ifr++) {
	unsigned long flags;

	/* Get the flags */
	if (get_if_flags(ifr->ifr_name, &flags) == 0) {
	    if (flags & IFF_LOOPBACK)
		continue;

	    if (type == PIX_COMM_TYPE_PPP && !(flags & IFF_POINTOPOINT))
		continue;

	    if (type == PIX_COMM_TYPE_ETHERNET && (flags & IFF_POINTOPOINT))
		continue;

	    retcount++;
	    strcpy(iflist[retcount].name, ifr->ifr_name);

	    if (flags & IFF_POINTOPOINT)
		iflist[retcount].type = PIX_COMM_TYPE_PPP;
	    else
		iflist[retcount].type = PIX_COMM_TYPE_ETHERNET;

	    if (flags & IFF_UP)
		iflist[retcount].active = 1;
	    else
		iflist[retcount].active = 0;
	}
    }

    if (retcount != -1) {
	err = PIX_COMM_OK;
	*ifcount = retcount;
    } else
	err = PIX_COMM_NO_INTERFACES;

  out:
    free(ifc.ifc_buf);
    return err;
}

int
linux_set_netscript_values(char *file, const char *keys[], const char *vals[],
			   int size)
{

    FILE *net_file;
    int i = 0;

    net_file = fopen(file, "w");
    if (NULL == net_file) {
	fprintf(stderr, "Unable to open file %s\n", file);
	return (PIX_COMM_ERROR);
    }

    while (i < size) {
	fputs(keys[i], net_file);
	fputs("=", net_file);
	fputs(vals[i], net_file);
	fputs("\n", net_file);
	i++;
    }

    fclose(net_file);
    return (PIX_COMM_OK);
}

int
linux_get_netscript_values(char *file, char *keys[], char *vals[], int size)
{

    FILE *net_file;
    char buf[255];
    char key_buf[255];
    char val_buf[255];
    int i = 0, j = 0, k = 0;
    int len = 0;
    char *str_p = NULL, *eq_p = NULL;

    net_file = fopen(file, "r");
    if (NULL == net_file) {
	fprintf(stderr, "Unable to open file %s\n", file);
	return (PIX_COMM_ERROR);
    }

    while (NULL != fgets(buf, sizeof(buf) - 1, net_file) && (i < size)) {

	/* Verify line as a "=" */
	eq_p = strstr(buf, "=");
	if (NULL == eq_p) {
	    fprintf(stderr, "Invalid key=value pairs.\n");
	    continue;
	}

	if ('#' != buf[0]) {

	    j = 0;
	    key_buf[j] = '\0';
	    val_buf[j] = '\0';

	    /* Get keys */
	    str_p = buf;
	    while (('=' != *str_p) && (NULL != str_p)) {
		key_buf[j] = *str_p;
		str_p++;
		j++;
	    }
	    key_buf[j] = '\0';
	    strcpy(keys[i], key_buf);

	    /* Increment past the "=" */
	    str_p = strstr(buf, "=");
	    str_p++;

	    /* Get values */
	    len = strlen(str_p);
	    for (k = 0; k < len; k++) {
		if (('\n' != *str_p) && (NULL != str_p)) {
		    val_buf[k] = *str_p;
		    str_p++;
		} else {
		    val_buf[k] = '\0';
		}
	    }
	    strcpy(vals[i], val_buf);
	}

	i++;			/* increment to next line in file */
    }

    fclose(net_file);
    return (PIX_COMM_OK);

}

--- NEW FILE: platform_proto.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


/* PIX_SYS includes */
#include <pixlib/pixlib.h>
#include <pixlib/pix_sys_proto.h>
#include <linux.h>

/* PIX_COMM includes */
#include <pixlib/pix_comm_proto.h>
#include <linux_if.h>
#include <linux_ppp.h>
#include <linux_wireless.h>

/* PIX IO includes */
#include <sound_dsp.h>
#include <pixlib/pixio_proto.h>

pix_sys_func_t pix_sys_functions = {
    linux_set_date,		/* set date */
    linux_get_date,		/* get date */
    PIX_SYS_PROTO_NO_FUNCTION,	/* set backlight */
    linux_get_cpu_load,		/* get CPU load */
    linux_get_memory_usage,	/* Get memory usage */
    PIX_SYS_PROTO_NO_FUNCTION,	/* Get battery */
    pix_get_net_value,
    pix_write_net_values
};

pix_comm_func_t pix_comm_functions = {
    linux_do_ip_address,	/* handle ip address */
    linux_do_default_gateway,	/* handle gateway */
    pix_set_nameserver,		/* Set the name server */
    linux_ppp_connect,		/* Connect a PPP session */
    linux_ppp_disconnect,	/* Disconnect a PPP session */
    linux_get_if_list,		/* Get a list of interfaces */
    linux_if_active,
    linux_set_if_status,
    linux_if_dhcp,
    linux_ppp_get_stats,
    linux_ppp_write_info,
    linux_ppp_read_info,
    linux_ppp_ip_address,
    0,
    0,
    wireless_essid,
    wireless_get_statistics,
    wireless_get_if_list,
    0,
    0
};

pix_io_functions_t pix_io_functions = {
    dspPlayWAVFile,
    dspWriteWAVFile,
    dspReadWAVFile,
    dspGetWAVFileStats,
    dspOpenStream,
    dspStreamRecord,
    dspStreamPlay,
    mixer_get_devices,
    mixer_get_level,
    mixer_set_level
};

--- NEW FILE: linux_wireless.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/wireless.h>

#include <pixlib/pixlib.h>
#include <linux_wireless.h>

/* Defined in linux_if.c */

int linux_open_socket();

static int
wireless_do_ioctl(char *interface, int cmd, struct iwreq *data)
{
    int ret;
    int fd = linux_open_socket();

    if (fd < 0)
	return (errno);

    strcpy(data->ifr_ifrn.ifrn_name, interface);

    /* Now, do the ioctl call */
    ret = ioctl(fd, cmd, data);

    if (ret < 0)
	ret = errno;

    close(fd);

    return (ret);
}

int
wireless_name(char *interface, char *name)
{
    int cmd = SIOCGIWNAME;
    struct iwreq data;

    data.u.name[0] = '\0';

    if (wireless_do_ioctl(interface, cmd, &data) < 0) {
	return (PIX_COMM_ERROR);
    } else {
	strcpy(name, data.u.name);
	return (PIX_COMM_OK);
    }

}

int
wireless_encode(int operation, char *interface, char *name)
{
    int cmd = 0;
    struct iwreq data;

    switch (operation) {
    case PIX_COMM_GET:
	cmd = SIOCGIWENCODE;
	break;

    case PIX_COMM_SET:
	cmd = SIOCSIWENCODE;
	break;
    }

    data.u.encoding.pointer = (caddr_t) name;

    if (wireless_do_ioctl(interface, cmd, &data) < 0)
	return (PIX_COMM_ERROR);
    else
	return (PIX_COMM_OK);
}

int
wireless_essid(int operation, char *interface, char *name)
{
    int cmd = 0;
    struct iwreq data;

    switch (operation) {
    case PIX_COMM_GET:
	cmd = SIOCGIWESSID;
	break;

    case PIX_COMM_SET:
	cmd = SIOCSIWESSID;
	break;
    }

    printf("data.u.essid.pather = %s\n", name);
    data.u.essid.pointer = (caddr_t) name;

    if (wireless_do_ioctl(interface, cmd, &data) < 0) {
	return (PIX_COMM_ERROR);
    } else {
	return (PIX_COMM_OK);
    }

}

int
wireless_get_statistics(char *interface, pix_comm_wirestats_t * stats)
{
    char tmpstr[3];
    char buffer[BUFSIZ];

    FILE *wfile = fopen("/proc/net/wireless", "r");

    if (NULL == wfile)
	return (PIX_COMM_ERROR);

    /* Read the first couple of lines */
    fgets(buffer, BUFSIZ, wfile);
    fgets(buffer, BUFSIZ, wfile);

    /* Now, go through all the interfaces until we find one that */
    /* we want */

    while (1) {
	if (feof(wfile))
	    break;

	fgets(buffer, BUFSIZ, wfile);
	if (!strncmp(buffer, interface, strlen(interface))) {
	    sscanf(buffer,
		   "%6s: %04hx  %3hhd%c  %3hhd%c  %3hhd%c  %6ld %6ld %6ld\n",
		   stats->name, &(stats->status), &(stats->quality),
		   &tmpstr[0], &stats->level, &tmpstr[1], &stats->noise,
		   &tmpstr[2], &stats->discard.nwid, &stats->discard.code,
		   &stats->discard.misc);

	    fclose(wfile);
	    return (PIX_COMM_OK);
	}
    }

    fclose(wfile);
    return (PIX_COMM_ERROR);
}

int
wireless_get_if_list(pix_comm_interface_t * iflist, int *ifcount)
{
    char tmpstr[3];
    char ifname[10];
    char buffer[BUFSIZ];
    int idx = 0;
    int retcount = -1;
    int err = PIX_COMM_ERROR;
    pix_comm_wirestats_t stats;

    /* We want to return a list of interfaces and some stats */
    FILE *wfile = fopen("/proc/net/wireless", "r");

    if (NULL == wfile)
	return (PIX_COMM_ERROR);

    /* Read the first couple of lines */
    fgets(buffer, BUFSIZ, wfile);
    fgets(buffer, BUFSIZ, wfile);

    while (1) {
	if (feof(wfile))
	    break;
	fgets(buffer, BUFSIZ, wfile);
	sscanf(buffer,
	       "%6s: %04hx  %3hhd%c  %3hhd%c  %3hhd%c  %6ld %6ld %6ld\n",
	       stats.name, &(stats.status), &(stats.quality), &tmpstr[0],
	       &stats.level, &tmpstr[1], &stats.noise, &tmpstr[2],
	       &stats.discard.nwid, &stats.discard.code, &stats.discard.misc);

	for (idx = 0; idx < 4; idx++) {
	    sprintf(ifname, "eth%d", idx);
	    if (0 == strncmp(ifname, stats.name, strlen(ifname))) {
		retcount++;
		strcpy(iflist[retcount].name, ifname);
		if (retcount >= *ifcount)
		    break;
	    }
	    sprintf(ifname, "wvlan%d", idx);
	    if (0 == strncmp(ifname, stats.name, strlen(ifname))) {
		retcount++;
		strcpy(iflist[retcount].name, ifname);
		if (retcount >= *ifcount)
		    break;
	    }
	}
    }

    if (retcount != -1) {
	err = PIX_COMM_OK;
	*ifcount = retcount;
    } else {
	err = PIX_COMM_NO_INTERFACES;
	*ifcount = 0;
    }
    fclose(wfile);
    return (err);
}

--- NEW FILE: pix_sys_api.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <pixlib/pixlib.h>
#include <pixlib/pix_sys_proto.h>

/* This is a structure (defined elsewhere for each 
 * individual platform), that give us a gateway to the
 * actualy system dependent functions for each API 
 * call 
 */

extern pix_sys_func_t pix_sys_functions;

/******** SYSTEM SETTINGS **********/

/* 
 * pix_sys_set_date()
 * This function sets the date / time on the system
 */

int
pix_sys_set_date(pix_sys_date_t * date_struct)
{
    if (pix_sys_functions.sysdep_set_date)
	return (pix_sys_functions.sysdep_set_date(date_struct));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/* 
 * pix_sys_get_date()
 * This function get the date / time from the system
 */

int
pix_sys_get_date(pix_sys_date_t * date_struct)
{
    if (pix_sys_functions.sysdep_get_date)
	return (pix_sys_functions.sysdep_get_date(date_struct));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/******** POWER MANAGEMENT **********/

/* 
 * pix_sys_set_backlight(brightness)
 * This function sets the backlight on the system
 * where brigtness is a percentage of the brightness
 */

int
pix_sys_set_backlight(unsigned char brightness, unsigned char power)
{
    if (brightness > 100)
	return (PIX_SYS_ERROR);

    if (pix_sys_functions.sysdep_set_backlight)
	return (pix_sys_functions.sysdep_set_backlight(brightness, power));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/******** STATISTICS **********/

/* 
 * pix_sys_get_cpu_load()
 * This function gets the current CPU load 
 */

int
pix_sys_get_cpu_load(pix_sys_cpu_t * cpu_struct)
{
    if (pix_sys_functions.sysdep_get_cpu_load)
	return (pix_sys_functions.sysdep_get_cpu_load(cpu_struct));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/* 
 * pix_sys_get_memory_usage()
 * This function gets the current CPU memory usage 
 */

int
pix_sys_get_memory_usage(pix_sys_memory_t * mem_struct)
{
    if (pix_sys_functions.sysdep_get_memory_usage)
	return (pix_sys_functions.sysdep_get_memory_usage(mem_struct));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/* 
 * pix_sys_get_battery()
 * This function gets the current battery life
 */

int
pix_sys_get_battery(pix_sys_battery_t * battery_struct)
{
    if (pix_sys_functions.sysdep_get_battery)
	return (pix_sys_functions.sysdep_get_battery(battery_struct));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/*
 * pix_sys_get_net_value
 * This function get the value specified by key
 * 
 */
int
pix_sys_get_net_value(char *key, char *ret)
{
    if (pix_sys_functions.sysdep_get_net_value)
	return (pix_sys_functions.sysdep_get_net_value(key, ret));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

/*
 * pix_sys_write_net_values
 * This function writes the values to the correct file
 *
 */
int
pix_sys_write_net_values(pix_sys_ipaddr_str_t ip_info, pix_sys_dns_t dns_info)
{
    if (pix_sys_functions.sysdep_write_net_values)
	return (pix_sys_functions.sysdep_write_net_values(ip_info, dns_info));
    else
	return (PIX_SYS_NOT_IMPLEMENTED);
}

--- NEW FILE: linux_ppp.c ---
/*                                                                       
 * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.     
 *                                                                       
 * This file is part of the PIXIL Operating Environment                 
 *                                                                       
 * The use, copying and distribution of this file is governed by one    
 * of two licenses, the PIXIL Commercial License, or the GNU General    
 * Public License, version 2.                                           
 *                                                                       
 * Licensees holding a valid PIXIL Commercial License may use this file 
 * in accordance with the PIXIL Commercial License Agreement provided   
 * with the Software. Others are governed under the terms of the GNU   
 * General Public License version 2.                                    
 *                                                                       
 * This file may be distributed and/or modified under the terms of the  
 * GNU General Public License version 2 as published by the Free        
 * Software Foundation and appearing in the file LICENSE.GPL included   
 * in the packaging of this file.                                      
 *                                                                       
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING  
 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A            
 * PARTICULAR PURPOSE.                                                  
 *                                                                       
 * RESTRICTED RIGHTS LEGEND                                             
 *                                                                     
 * Use, duplication, or disclosure by the government is subject to      
 * restriction as set forth in paragraph (b)(3)(b) of the Rights in     
 * Technical Data and Computer Software clause in DAR 7-104.9(a).       
 *                                                                      
 * See http://www.pixil.org/gpl/ for GPL licensing       
 * information.                                                         
 *                                                                      
 * See http://www.pixil.org/license.html or              
 * email cetsales at centurysoftware.com for information about the PIXIL   
 * Commercial License Agreement, or if any conditions of this licensing 
 * are not clear to you.                                                
 */


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#include <net/if.h>
#include <net/ppp_defs.h>
#include <net/if_ppp.h>

#include <netinet/in.h>

#include <pixlib/pixlib.h>
#include <linux_if.h>
#include <linux_ppp.h>

extern int linux_open_socket();
extern int get_if_flags(char *ifname, unsigned long *flags);

typedef struct
{
    char keyword[15];
    char *value;
}
keywords_t;


/* This function replaces various keywords in a given script with the correct */
/* options */

static void
replace_keywords(keywords_t * keywords, int kcount,
		 const char *incmd, char *outcmd)
{
    const char *inptr = incmd;
    char *outptr = outcmd;

    /* Go through and look for a $.  When one is found, handle it */

    while (1) {
	for (; *inptr != '$' && *inptr; inptr++)
	    *outptr++ = *inptr;

	if (!*inptr) {
	    *outptr = 0;
	    return;
	}

	if (*inptr == '$') {
	    int i;

	    inptr++;

	    for (i = 0; i < kcount; i++) {
		if (!strncmp
		    (inptr, keywords[i].keyword,
		     strlen(keywords[i].keyword))) {
		    strcat(outptr, keywords[i].value);
		    inptr += strlen(keywords[i].value);
		    outptr += strlen(keywords[i].value);
		    break;
		}
	    }
	}
    }
}

static inline void
addr_to_ascii(unsigned long addr, char *str)
{
    sprintf(str, "%d.%d.%d.%d",
	    (unsigned char) (addr >> 24) & 0xFF,
	    (unsigned char) (addr >> 16) & 0xFF,
	    (unsigned char) (addr >> 8) & 0xFF, (unsigned char) addr & 0xFF);
}

#define MODE_SRDWR S_IRUSR|S_IWUSR
int
ppp_write_secrets(pix_comm_ppp_options_t * ppp_options)
{
    char *chap_file = "/etc/ppp/chap-secrets";
    char *pap_file = "/etc/ppp/pap-secrets";
    FILE *fp;
    char buf[255];

    fp = fopen(chap_file, "w");
    if (NULL == fp) {
	perror("PPP_WRITE_SECRETS (FOPEN)");
	return (PIX_COMM_ERROR);
    }
    fputs("# Secrets for authentication using PAP\n", fp);
    fputs("# client\tserver\tsecret\t\t\tIP addresses\n", fp);
    sprintf(buf, "\"%s\"\t*\t\"%s\"", ppp_options->account,
	    ppp_options->password);
    fputs(buf, fp);
    fclose(fp);
    fp = fopen(pap_file, "w");
    if (NULL == fp) {
	perror("PPP_WRITE_SECRETS (FOPEN)");
	return (PIX_COMM_ERROR);
    }
    fputs("# Secrets for authentication using PAP\n", fp);
    fputs("# client\tserver\tsecret\t\t\tIP addresses\n", fp);
    sprintf(buf, "\"%s\"\t*\t\"%s\"", ppp_options->account,
	    ppp_options->password);
    fputs(buf, fp);
    fclose(fp);
    chmod(chap_file, MODE_SRDWR);
    chmod(pap_file, MODE_SRDWR);
    return (PIX_COMM_OK);
}

int
locate_chat_bin(char *bin)
{
    struct stat stat_buf;
    char buf[255];
    int err;

    sprintf(buf, "/usr/sbin/chat");
    err = stat(buf, &stat_buf);
    if (err == 0) {
	strcpy(bin, buf);
	return (PIX_COMM_OK);
    }
    sprintf(buf, "/sbin/chat");
    err = stat(buf, &stat_buf);
    if (err == 0) {
	strcpy(bin, buf);
	return (PIX_COMM_OK);
    }
    sprintf(buf, "/root/chat");
    err = stat(buf, &stat_buf);
    if (err == 0) {
	strcpy(bin, buf);
	return (PIX_COMM_OK);
    }
    return (PIX_COMM_ERROR);
}


int
ppp_write_peer(pix_comm_ppp_options_t * ppp_options, char *config)
{
    char peer_file[255];
    char buf[255];
    FILE *fp;
    char chat_bin[255];
    int err;

    err = locate_chat_bin(chat_bin);
    if (0 > err) {
	return (PIX_COMM_ERROR);
    }
    sprintf(peer_file, "/etc/ppp/peers/%s", config);
    fp = fopen(peer_file, "w");
    if (NULL == peer_file) {
	perror("PPP_WRITE_PEER (FOPEN)");
	return (PIX_COMM_ERROR);
    }
    sprintf(buf,
	    "%s %d -detach crtscts defaultroute usepeerdns -chap user \"%s\"\n",
	    ppp_options->device, ppp_options->speed, ppp_options->account);
    fputs(buf, fp);
    sprintf(buf, "connect '%s -v -f /tmp/ppp/chat-%s'\n", chat_bin, config);
    fputs(buf, fp);
    sprintf(buf, "noauth\n");
    fputs(buf, fp);
    fclose(fp);
    return (PIX_COMM_OK);
}

#define SCRIPT_PRE "/tmp/ppp/chat-"
#define MODE_RDWR  S_IROTH|S_IWOTH|S_IRGRP|S_IWGRP|S_IRUSR|S_IWUSR
int
ppp_write_default_script(pix_comm_ppp_options_t * ppp_options, char *config)
{
    char buf[255];
    char chat_file[255];
    FILE *fp;

    sprintf(chat_file, "%s%s", SCRIPT_PRE, config);
    fp = fopen(chat_file, "w");
    if (NULL == fp) {
	perror("PPP_WRITE_SCRIPT (FOPEN)");
	return (PIX_COMM_ERROR);
    }
    sprintf(buf, "ABORT \"NO CARRIER\"\nABORT \"NO DIALTONE\"\n");
    fputs(buf, fp);
    sprintf(buf, "ABORT \"ERROR\"\nABORT \"NO ANSWER\"\nABORT \"BUSY\"\n");
    fputs(buf, fp);
    sprintf(buf, "ABORT \"Username/Password Incorrect\"\n");
    fputs(buf, fp);
    sprintf(buf, "'' 'AT'\n'OK' 'ATM0L0'\n 'OK' 'ATDT%s'\n",
	    ppp_options->telephone);
    fputs(buf, fp);
    sprintf(buf, "'CONNECT' ''\n'name:' '%s'\n", ppp_options->account);
    fputs(buf, fp);
    sprintf(buf, "'ord:' '%s'\n", ppp_options->password);
    fputs(buf, fp);
    sprintf(buf, "'TIMEOUT' '5'\n");
    fputs(buf, fp);
    sprintf(buf, "'~--' ''\n");
    fputs(buf, fp);
    fclose(fp);
    chmod(chat_file, MODE_RDWR);
    return (PIX_COMM_OK);
}

int
ppp_write_script(pix_comm_ppp_options_t * ppp_options, char *config,
		 char **pppd_commands, int count)
{
    char chat_file[255];
    FILE *fp;
    int idx;

    sprintf(chat_file, "%s%s", SCRIPT_PRE, config);
    fp = fopen(chat_file, "w");
    if (NULL == fp) {
	perror("PPP_WRITE_SCRIPT (FOPEN)");
	return (PIX_COMM_ERROR);
    }
    for (idx = 0; idx < count; idx++) {
	fputs(pppd_commands[idx], fp);
	fputs("\n", fp);
    }
    fclose(fp);
    chmod(chat_file, MODE_RDWR);
    return (PIX_COMM_OK);
}

int
locate_pppd_bin(char *bin)
{
    int err;
    char buf[255];
    struct stat stat_buf;

    sprintf(buf, "/usr/sbin/pppd");
    err = stat(buf, &stat_buf);
    if (0 == err) {
	strcpy(bin, buf);
	return (PIX_COMM_OK);
    }
    sprintf(buf, "/sbin/pppd");
    err = stat(buf, &stat_buf);
    if (0 == err) {
	strcpy(bin, buf);
	return (PIX_COMM_OK);
    }
    return (PIX_COMM_ERROR);
}

#define PPPD_STR 		"-detach defaultroute lock lcp-echo-interval 5 lcp-echo-failure 3 noipdefault"
#define PPPD_SETUP 	"-detach noauth nocrtscts lock"
#define PPPD_OGIN  	"-v -t3 ogin--ogin: ppp"
static int
ppp_nullmodem_connect(pix_comm_ppp_options_t * ppp_options)
{
    char ipaddr[25];
    char cmds[128];
    char pppd_command[1024];
    char *pptr = pppd_command;
    pid_t childpid;
    int err, tries;
    int max_tries = 10;
    int idx;
    /* Determine the commands we want to send to the pppd */
    cmds[0] = 0;

    if (ppp_options->flags & PIX_COMM_PPP_AUTH)
	strcat(cmds, "auth ");
    else
	strcat(cmds, "noauth ");

    if (ppp_options->flags & PIX_COMM_PPP_HWFLOW)
	strcat(cmds, "ctrscts ");
    else
	strcat(cmds, "nocrtscts ");

    sprintf(pptr, "pppd %s %s %s %d ",
	    PPPD_STR, cmds, ppp_options->device, ppp_options->speed);

    if (ppp_options->local_ipaddr || ppp_options->remote_ipaddr) {
	addr_to_ascii(ppp_options->local_ipaddr, ipaddr);
	strcat(pptr, ipaddr);
	strcat(pptr, ":");
	addr_to_ascii(ppp_options->remote_ipaddr, ipaddr);
	strcat(pptr, ipaddr);
    }

    if ((childpid = fork()) == -1) {
	perror("PPP_MODEM_CONNECT (FORK)");
	return (PIX_COMM_ERROR);
    } else if (childpid == 0) {	// in child
	for (idx = 3; idx < 20; idx++)
	    close(idx);
	err = system(pptr);
	if (0 > err)
	    perror("PPP_MODEM_CONNECT (SYSTEM)");
	exit(1);
    } else {			//in parent
	//wait(&child_status);
	tries = 0;
	while ((PIX_COMM_INACTIVE == linux_if_active("ppp0"))
	       && (tries < max_tries)) {
	    tries++;
	    sleep(3);
	}
	if (PIX_COMM_INACTIVE == linux_if_active("ppp0")) {
	    linux_ppp_disconnect("ppp0");
	    return (PIX_COMM_ERROR);
	} else
	    return (PIX_COMM_OK);
    }
    return (PIX_COMM_OK);
}

/*
 *
 */
int
ppp_modem_connect(pix_comm_ppp_options_t * ppp_options,
		  char **ppp_commands, int ccount, int dhcp, char *config)
{
    int i;

    keywords_t ppp_keyword[] = { {"TELEPHONE", ppp_options->telephone},
    {"ACCOUNT", ppp_options->account},
    {"PASSWORD", ppp_options->password}
    };

    char pppd_command[4500];
    char connect_script[4096];
    char ipaddr[25];
    char pppd_bin[255];
    char chat_bin[255];

    char *pptr = pppd_command;
    char *cptr = connect_script;

    pid_t childpid;
    int err;
    int max_tries = 20;
    int tries = 0;
    int idx;
    /* Determine where pppd and chat live */
    err = locate_pppd_bin(pppd_bin);
    if (0 > err)
	return (PIX_COMM_ERROR);

    /* Construct the output script */
    if (1 == dhcp && NULL == ppp_commands) {
	err = ppp_write_secrets(ppp_options);
	if (err)
	    return (PIX_COMM_ERROR);
	err = ppp_write_peer(ppp_options, config);
	if (err)
	    return (PIX_COMM_ERROR);
	err = ppp_write_default_script(ppp_options, config);
	if (err)
	    return (PIX_COMM_ERROR);
	sprintf(pptr, "%s call %s", pppd_bin, config);

    } else if (1 == dhcp && NULL != ppp_commands) {
	err = ppp_write_secrets(ppp_options);
	if (err)
	    return (PIX_COMM_ERROR);
	err = ppp_write_peer(ppp_options, config);
	if (err)
	    return (PIX_COMM_ERROR);
	err = ppp_write_script(ppp_options, config, ppp_commands, ccount);
	if (err)
	    return (PIX_COMM_ERROR);
	sprintf(pptr, "%s call %s", pppd_bin, config);
    } else if (0 == dhcp && NULL == ppp_commands) {

	err = ppp_nullmodem_connect(ppp_options);
	if (0 > err)
	    return (PIX_COMM_ERROR);
	else
	    return (PIX_COMM_OK);
    } else {
	for (i = 0; i < ccount; i++) {
	    char cline[256];
	    replace_keywords(ppp_keyword, 3, ppp_commands[i], cline);
	    strcat(cptr, cline);
	}

	sprintf(pptr, "pppd %s %d ", ppp_options->device, ppp_options->speed);

	addr_to_ascii(ppp_options->local_ipaddr, ipaddr);
	strcat(pptr, ipaddr);

	/* Add the remote address */

	addr_to_ascii(ppp_options->remote_ipaddr, ipaddr);
	strcat(pptr, ":");
	strcat(pptr, ipaddr);
	strcat(pptr, " ");

	strcat(pptr, PPPD_SETUP);
	strcat(pptr, " ");

	/* Add the connect address */
	strcat(pptr, "connect '");
	err = locate_chat_bin(chat_bin);
	if (err != 0)
	    return (PIX_COMM_ERROR);
	strcat(pptr, chat_bin);
	strcat(pptr, " ");
	strcat(pptr, PPPD_OGIN);
	strcat(pptr, "'");
    }
    /* Fire away! */
    if ((childpid = fork()) == -1) {
	perror("PPP_MODEM_CONNECT (FORK)");
	return (PIX_COMM_ERROR);
    } else if (childpid == 0) {	// in child
	/* system(pppd_command); */
	err = locate_pppd_bin(pppd_bin);
	if (0 > err)
	    return (PIX_COMM_ERROR);
	for (idx = 3; idx < 20; idx++)
	    close(idx);
	err = system(pptr);
	if (0 > err)
	    perror("PPP_MODEM_CONNECT (SYSTEM)");
	exit(1);
    } else {			//in parent
	//wait(&child_status);
	tries = 0;
	while ((PIX_COMM_INACTIVE == linux_if_active("ppp0"))
	       && (tries < max_tries)) {
	    tries++;
	    sleep(3);
	}
	if (PIX_COMM_INACTIVE == linux_if_active("ppp0")) {
	    linux_ppp_disconnect("ppp0");
	    return (PIX_COMM_ERROR);
	} else
	    return (PIX_COMM_OK);
    }

    return (PIX_COMM_OK);
}

/* Here we need to define the various commands that are required */
/* This is the current standard for the ipaq, but they should probably */
/* be passed in by a client */



/* For Century Software PPP connections, we have a script that 
 * gets called when IP goes up and down.  It writes a file in 
 * /tmp called censoft-ppp-<dev>.info.  Thats what we read to
 * get the IP info to return to the system.  
 */

#ifdef NOTUSED

static int
read_line(char **ptr, char *str, int maxlen)
{
    char *tptr = *ptr;
    int len;

    for (; *tptr != '\n' && *tptr; tptr++);
    len = (int) (tptr - *ptr);

    strncpy(str, *ptr, len);
    *ptr = tptr + 1;
    return (len);
}
#endif

int
linux_ppp_get_interface(char *device, char *ifname, int ifnamesize)
{
    char *dptr;
    char filen[BUFSIZ];
    int fd;
    ssize_t len;

    /* First, strip everything except for the end device name off */
    for (dptr = device + strlen(device); *dptr != '/' && dptr != device;
	 dptr--);

    if (dptr != device)
	dptr++;

    /* Now try to open up the info file */
    sprintf(filen, "/tmp/censoft-ppp-%s.info", dptr);
    fd = open(filen, O_RDONLY);

    if (fd == -1)
	return (PIX_COMM_INACTIVE);

    /* We write lots of stuff in that file, but for now we really only care */
    /* about the interface name, since we can get everything else from that */

    len = read(fd, ifname, ifnamesize - 1);
    close(fd);

    if (len == -1)
	return (PIX_COMM_ERROR);
    else {
	ifname[len] = 0;
	return (PIX_COMM_OK);
    }
}

/* *********** API CALLS ***********/

int
linux_ppp_connect(int type, pix_comm_ppp_options_t * ppp_options,
		  char **ppp_commands, int ccount, int dhcp, char *config)
{
    switch (type) {
    case PIX_COMM_PPP_NULLMODEM:
	return (ppp_nullmodem_connect(ppp_options));

    case PIX_COMM_PPP_MODEM:
	return (ppp_modem_connect
		(ppp_options, ppp_commands, ccount, dhcp, config));
    }

    return (PIX_COMM_ERROR);
}

/*
 * linux_read_ppp_info()
 * Read in PPP info
 */

static void
strip_newline(char *src, char *dest)
{
    char *sptr = src;
    char *dptr = dest;

    for (; *sptr != 0 && *sptr != '\n'; sptr++, dptr++)
	*dptr = *sptr;

    *dptr = 0;
}

int
linux_ppp_read_info(char *filename, pix_comm_ppp_info_t * ppp_info)
{
    int err = PIX_COMM_ERROR;

    char buffer[512];
    FILE *stream = 0;

    stream = fopen(filename, "r");

    if (!stream)
	return (PIX_COMM_ERROR);

    fgets(buffer, sizeof(buffer) - 1, stream);
    if (ferror(stream))
	goto end;
    strip_newline(buffer, ppp_info->device);

    fgets(buffer, sizeof(buffer) - 1, stream);
    if (ferror(stream))
	goto end;
    strip_newline(buffer, ppp_info->ifname);

    fgets(buffer, sizeof(buffer) - 1, stream);
    if (ferror(stream))
	goto end;
    strip_newline(buffer, ppp_info->remote_ipaddr);

    fgets(buffer, sizeof(buffer) - 1, stream);
    if (ferror(stream))
	goto end;
    strip_newline(buffer, ppp_info->local_ipaddr);

    fgets(buffer, sizeof(buffer) - 1, stream);
    if (ferror(stream))
	goto end;
    ppp_info->speed = atoi(buffer);

    fgets(buffer, sizeof(buffer) - 1, stream);
    if (ferror(stream))
	goto end;
    ppp_info->start_time = atoi(buffer);

    err = PIX_COMM_OK;
  end:
    fclose(stream);
    return (err);
}

/*
 * linux_write_ppp_info()
 * Write the specified information to a file 
 */

int
linux_ppp_write_info(char *filename, pix_comm_ppp_info_t * ppp_info)
{
    char outbuf[sizeof(ppp_info) + 20];

    int fd, len;

    fd = open(filename, O_WRONLY);

    if (fd == -1)
	return (PIX_COMM_ERROR);

    sprintf(outbuf, "%s\n%s\n%s\n%s\n%d\n%ld\n",
	    ppp_info->device, ppp_info->ifname, ppp_info->remote_ipaddr,
	    ppp_info->local_ipaddr, ppp_info->speed, ppp_info->start_time);

    len = write(fd, &outbuf, strlen(outbuf));

    close(fd);

    if (len != strlen(outbuf))
	return (PIX_COMM_ERROR);
    else
	return (PIX_COMM_OK);
}

/*
 * linux_ppp_get_stats()
 * Given an interface name, return the statistics 
 */

int
linux_ppp_get_stats(char *ifname, pix_comm_ppp_stats_t * ppp_stats)
{
    int fd;
    unsigned long flags;
    struct ifpppstatsreq req;

    ppp_stats->in_bytes = 0;
    ppp_stats->out_bytes = 0;

    if (get_if_flags(ifname, &flags) == -1)
	return (PIX_COMM_ERROR);

    if (!(flags & IFF_UP))
	return (PIX_COMM_ERROR);

    req.stats_ptr = (caddr_t) & req.stats;

    strncpy(req.ifr__name, ifname, sizeof(req.ifr__name));

    /* Open up a socket so we can communicate */

    if ((fd = linux_open_socket()) < 0)
	return (PIX_COMM_ERROR);

    if (ioctl(fd, SIOCGPPPSTATS, &req) != 0)
	return (PIX_COMM_ERROR);

    ppp_stats->in_bytes = (unsigned long) req.stats.p.ppp_ibytes;
    ppp_stats->out_bytes = (unsigned long) req.stats.p.ppp_obytes;

    return (PIX_COMM_OK);
}

/*
 * linux_ppp_disconnect()
 * Given an interface name, shut down the PPPD 
 */

int
linux_ppp_disconnect(char *ifname)
{
    char buf[15];
    char filename[128];
    int fd;
    int err;

    /* Look for the pid file */

    if (!ifname)
	sprintf(filename, "/var/run/%s.pid", "ppp0");
    else
	sprintf(filename, "/var/run/%s.pid", ifname);

    fd = open(filename, O_RDONLY);

    if (fd == -1) {
	if (errno != EACCES)
	    return (PIX_COMM_ERROR);
	else
	    return (PIX_COMM_OK);
    }

    err = -1;

    if (read(fd, &buf, sizeof(buf)))
	err = kill(atoi(buf), SIGINT);

    close(fd);

    /* If there was an error, then erase the file */

    if (err == -1)
	unlink(filename);

    return (PIX_COMM_OK);
}

int
linux_ppp_ip_address(char *ifname, pix_comm_ppp_options_t * ppp_options)
{
    int err = PIX_COMM_IPADDR_ERROR;
    int fd;
    struct ifreq ifr;
    struct sockaddr_in *sin = (void *) &ifr.ifr_addr;

    memset(&ifr, 0, sizeof(ifr));
    strcpy(ifr.ifr_name, ifname);

    /* Open up a socket so we can communicate */
    if ((fd = linux_open_socket()) < 0)
	return (PIX_COMM_ERROR);
    if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
	perror("GET_IP_ADDR (IOCTL)");
	err = PIX_COMM_INVALID;
    }
    ppp_options->local_ipaddr = ntohl(sin->sin_addr.s_addr);

    if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) {
	perror("GET_IP_ADDR (IOCTL)");
	err = PIX_COMM_INVALID;
    }
    ppp_options->netmask = ntohl(sin->sin_addr.s_addr);


    if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0) {
	perror("GET_DSTIP_ADDR (IOCTL)");
	err = PIX_COMM_INVALID;
    }
    ppp_options->remote_ipaddr = ntohl(sin->sin_addr.s_addr);
    close(fd);
    return (err);
}




More information about the dslinux-commit mailing list