mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 18:45:54 +02:00
Beta der Netzwerkdialoge.
Ueberfluessige Buildscripts noch geloescht. git-svn-id: http://svn.ipfire.org/svn/ipfire/trunk@484 ea5c0bd1-69bd-2848-81d8-4f18e57aeed8
This commit is contained in:
@@ -1 +1,2 @@
|
||||
usr/local/sbin/setup
|
||||
bin/probenic.sh
|
||||
|
||||
90
lfs/eciadsl
90
lfs/eciadsl
@@ -1,90 +0,0 @@
|
||||
###############################################################################
|
||||
# This file is part of the IPCop Firewall. #
|
||||
# #
|
||||
# IPCop is free software; you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation; either version 2 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# IPCop is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with IPCop; if not, write to the Free Software #
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
# #
|
||||
# Makefiles are based on LFSMake, which is #
|
||||
# Copyright (C) 2002 Rod Roard <rod@sunsetsystems.com> #
|
||||
# #
|
||||
# Modifications by: #
|
||||
# ??-12-2003 Mark Wormgoor < mark@wormgoor.com> #
|
||||
# - Modified Makefile for IPCop build #
|
||||
# #
|
||||
# $Id: eciadsl,v 1.4.2.11 2005/11/14 21:55:29 gespinasse Exp $
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Definitions
|
||||
###############################################################################
|
||||
|
||||
include Config
|
||||
|
||||
VER = 0.11
|
||||
|
||||
THISAPP = eciadsl-usermode-$(VER)
|
||||
DL_FILE = $(THISAPP).tar.gz
|
||||
DL_FROM = http://eciadsl.flashtux.org/download
|
||||
DIR_APP = $(DIR_SRC)/$(THISAPP)
|
||||
TARGET = $(DIR_INFO)/$(THISAPP)
|
||||
|
||||
###############################################################################
|
||||
# Top-level Rules
|
||||
###############################################################################
|
||||
|
||||
objects = $(DL_FILE)
|
||||
|
||||
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
|
||||
|
||||
$(DL_FILE)_MD5 = c3c60c83f6df30021e11da50a699dec9
|
||||
|
||||
install : $(TARGET)
|
||||
|
||||
check : $(patsubst %,$(DIR_CHK)/%,$(objects))
|
||||
|
||||
download :$(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
|
||||
md5 : $(subst %,%_MD5,$(objects))
|
||||
|
||||
###############################################################################
|
||||
# Downloading, checking, md5sum
|
||||
###############################################################################
|
||||
|
||||
$(patsubst %,$(DIR_CHK)/%,$(objects)) :
|
||||
@$(CHECK)
|
||||
|
||||
$(patsubst %,$(DIR_DL)/%,$(objects)) :
|
||||
@$(LOAD)
|
||||
|
||||
$(subst %,%_MD5,$(objects)) :
|
||||
@$(MD5)
|
||||
|
||||
###############################################################################
|
||||
# Installation Details
|
||||
###############################################################################
|
||||
|
||||
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
@$(PREBUILD)
|
||||
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
|
||||
cd $(DIR_APP) && ./configure --prefix=/usr
|
||||
cd $(DIR_APP) && make
|
||||
# no more hack GS7070 binary in /usr/bin , GS7470 in /usr/sbin, all in /usr/sbin
|
||||
cd $(DIR_APP) && install -c -p -m 0755 eciadsl-firmware eciadsl-synch eciadsl-pppoeci /usr/sbin
|
||||
-mkdir -p /etc/eciadsl
|
||||
cd $(DIR_APP) && install -c -p -m 0644 firmware00.bin /etc/eciadsl
|
||||
cd $(DIR_APP) && install -c -p -m 0644 modems.db /etc/eciadsl
|
||||
touch /etc/eciadsl/eciadsl.conf
|
||||
@rm -rf $(DIR_APP)
|
||||
@$(POSTBUILD)
|
||||
85
lfs/lpd
85
lfs/lpd
@@ -1,85 +0,0 @@
|
||||
###############################################################################
|
||||
# This file is part of the IPCop Firewall. #
|
||||
# #
|
||||
# IPCop is free software; you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation; either version 2 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# IPCop is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with IPCop; if not, write to the Free Software #
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
# #
|
||||
# Makefiles are based on LFSMake, which is #
|
||||
# Copyright (C) 2002 Rod Roard <rod@sunsetsystems.com> #
|
||||
# #
|
||||
# Modifications by: #
|
||||
# ??-12-2003 Mark Wormgoor < mark@wormgoor.com> #
|
||||
# - Modified Makefile for IPCop build #
|
||||
# #
|
||||
# $Id: ntp,v 1.6.2.3 2005/02/05 15:38:15 gespinasse Exp $
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Definitions
|
||||
###############################################################################
|
||||
|
||||
include Config
|
||||
|
||||
VER = 3.8.28
|
||||
|
||||
THISAPP = LPRng-$(VER)
|
||||
DL_FILE = $(THISAPP).tgz
|
||||
DL_FROM = http://www.lprng.com/DISTRIB/LPRng
|
||||
DIR_APP = $(DIR_SRC)/$(THISAPP)
|
||||
TARGET = $(DIR_INFO)/$(THISAPP)
|
||||
|
||||
###############################################################################
|
||||
# Top-level Rules
|
||||
###############################################################################
|
||||
|
||||
objects = $(DL_FILE)
|
||||
|
||||
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
|
||||
|
||||
$(DL_FILE)_MD5 = 1b3a0abd291b260eab6087ac0e61ed84
|
||||
|
||||
install : $(TARGET)
|
||||
|
||||
check : $(patsubst %,$(DIR_CHK)/%,$(objects))
|
||||
|
||||
download :$(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
|
||||
md5 : $(subst %,%_MD5,$(objects))
|
||||
|
||||
###############################################################################
|
||||
# Downloading, checking, md5sum
|
||||
###############################################################################
|
||||
|
||||
$(patsubst %,$(DIR_CHK)/%,$(objects)) :
|
||||
@$(CHECK)
|
||||
|
||||
$(patsubst %,$(DIR_DL)/%,$(objects)) :
|
||||
@$(LOAD)
|
||||
|
||||
$(subst %,%_MD5,$(objects)) :
|
||||
@$(MD5)
|
||||
|
||||
###############################################################################
|
||||
# Installation Details
|
||||
###############################################################################
|
||||
|
||||
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
@$(PREBUILD)
|
||||
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
|
||||
cd $(DIR_APP) && ./configure --prefix=/usr --sysconfdir=/etc --disable-shared --disable-kerberos --enable-ssl --enable-force_localhost
|
||||
cd $(DIR_APP) && make clean all
|
||||
cd $(DIR_APP) && make install POSTINSTALL=NO
|
||||
@rm -rf $(DIR_APP)
|
||||
@$(POSTBUILD)
|
||||
82
lfs/sane
82
lfs/sane
@@ -1,82 +0,0 @@
|
||||
###############################################################################
|
||||
# This file is part of the IPCop Firewall. #
|
||||
# #
|
||||
# IPCop is free software; you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation; either version 2 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# IPCop is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with IPCop; if not, write to the Free Software #
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
# #
|
||||
# Makefiles are based on LFSMake, which is #
|
||||
# Copyright (C) 2002 Rod Roard <rod@sunsetsystems.com> #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# Definitions
|
||||
###############################################################################
|
||||
|
||||
include Config
|
||||
|
||||
VER = 1.0.17
|
||||
|
||||
THISAPP = sane-backends-$(VER)
|
||||
DL_FILE = $(THISAPP).tar.gz
|
||||
DL_FROM = $(URL_IPFIRE)
|
||||
DIR_APP = $(DIR_SRC)/$(THISAPP)
|
||||
TARGET = $(DIR_INFO)/$(THISAPP)
|
||||
|
||||
###############################################################################
|
||||
# Top-level Rules
|
||||
###############################################################################
|
||||
|
||||
objects = $(DL_FILE)
|
||||
|
||||
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
|
||||
|
||||
$(DL_FILE)_MD5 = b51c10da8a81a04e1bae88c9e6556df2
|
||||
|
||||
install : $(TARGET)
|
||||
|
||||
check : $(patsubst %,$(DIR_CHK)/%,$(objects))
|
||||
|
||||
download :$(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
|
||||
md5 : $(subst %,%_MD5,$(objects))
|
||||
|
||||
dist:
|
||||
make-packages.sh sane $(THISAPP)-ipfire-beta-1
|
||||
|
||||
###############################################################################
|
||||
# Downloading, checking, md5sum
|
||||
###############################################################################
|
||||
|
||||
$(patsubst %,$(DIR_CHK)/%,$(objects)) :
|
||||
@$(CHECK)
|
||||
|
||||
$(patsubst %,$(DIR_DL)/%,$(objects)) :
|
||||
@$(LOAD)
|
||||
|
||||
$(subst %,%_MD5,$(objects)) :
|
||||
@$(MD5)
|
||||
|
||||
###############################################################################
|
||||
# Installation Details
|
||||
###############################################################################
|
||||
|
||||
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
@$(PREBUILD)
|
||||
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
|
||||
cd $(DIR_APP) && ./configure --prefix=/usr --sysconfdir=/var/ipfire/sane --disable-translations && \
|
||||
make
|
||||
cd $(DIR_APP) && make install
|
||||
@rm -rf $(DIR_APP)
|
||||
@$(POSTBUILD)
|
||||
@@ -61,5 +61,6 @@ $(TARGET) :
|
||||
-DSLOGAN='\"$(SLOGAN)\"' -DCONFIG_ROOT='\"$(CONFIG_ROOT)\"'"
|
||||
|
||||
cd $(DIR_APP)/setup && install -m 0755 setup /usr/local/sbin
|
||||
install -m 0755 $(DIR_SRC)/src/install+setup/install/probenic.sh /bin
|
||||
@rm -rf $(DIR_APP)
|
||||
@$(POSTBUILD)
|
||||
|
||||
@@ -48,14 +48,12 @@ int networkmenu(struct keyvalue *ethernetkv)
|
||||
errorbox(ctr[TR_PROBE_FAILED]);
|
||||
else
|
||||
{
|
||||
findnicdescription(driver, description);
|
||||
//findnicdescription(driver, description);
|
||||
sprintf (title, "%s v%s - %s", NAME, VERSION, SLOGAN);
|
||||
sprintf(message, ctr[TR_FOUND_NIC], NAME, description);
|
||||
newtWinMessage(title, ctr[TR_OK], message);
|
||||
}
|
||||
}
|
||||
else if (rc == 2)
|
||||
choosecards(driver, driveroptions);
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
|
||||
@@ -70,8 +68,6 @@ int networkmenu(struct keyvalue *ethernetkv)
|
||||
/* Smoothie is not untarred yet, so we have to delay actually writing the
|
||||
* settings till later. */
|
||||
replacekeyvalue(ethernetkv, "CONFIG_TYPE", "0");
|
||||
replacekeyvalue(ethernetkv, "GREEN_DRIVER", driver);
|
||||
replacekeyvalue(ethernetkv, "GREEN_DRIVER_OPTIONS", driveroptions);
|
||||
replacekeyvalue(ethernetkv, "GREEN_DEV", "eth0");
|
||||
replacekeyvalue(ethernetkv, "GREEN_DISPLAYDRIVER", driver);
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
hwinfo --netcard | egrep "Model|HW Address" | \
|
||||
awk -F": " '{ print $2 }' | sed -e '/..:..:..:..:..:../a\\' -e "s/$/\;/g" | \
|
||||
tr "\n" "XX" | sed -e "s/XX/\n/g" -e "s/\;X/\;/g" | \
|
||||
sort > /tmp/scanned_nics 2>/dev/null
|
||||
sort > /var/ipfire/ethernet/scanned_nics 2>/dev/null
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
* (c) Lawrence Manning, 2001
|
||||
* Contains prototypes for library functions.
|
||||
*
|
||||
* $Id: libsmooth.h,v 1.4.2.3 2005/10/30 23:25:35 franck78 Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ___LIBSMOOTH_H
|
||||
@@ -45,23 +43,24 @@
|
||||
#define DHCP 3
|
||||
#define NETCHANGE_TOTAL 4
|
||||
|
||||
#define KNOWN_NICS "/var/ipfire/ethernet/known_nics"
|
||||
#define SCANNED_NICS "/var/ipfire/ethernet/scanned_nics"
|
||||
|
||||
struct keyvalue
|
||||
{
|
||||
char key[STRING_SIZE];
|
||||
char value[STRING_SIZE];
|
||||
struct keyvalue *next;
|
||||
};
|
||||
|
||||
/* for stuff in net.c */
|
||||
struct nic
|
||||
{
|
||||
char *description;
|
||||
char *modulename;
|
||||
char description[256];
|
||||
char macaddr[20];
|
||||
};
|
||||
struct driver
|
||||
struct knic
|
||||
{
|
||||
char *description;
|
||||
char *modulename;
|
||||
char description[256];
|
||||
char macaddr[20];
|
||||
};
|
||||
|
||||
/* libsmooth.c */
|
||||
@@ -85,11 +84,8 @@ int gettype(char *type);
|
||||
int setnetaddress(struct keyvalue *kv, char *colour);
|
||||
void networkdialogcallbacktype(newtComponent cm, void *data);
|
||||
int interfacecheck(struct keyvalue *kv, char *colour);
|
||||
int probecards(char *driver, char *driveroptions);
|
||||
int choosecards(char *driver, char *driveroptions);
|
||||
int nicmenu(char *colour);
|
||||
int manualdriver(char *driver, char *driveroptions);
|
||||
int countcards(void);
|
||||
int findnicdescription(char *modulename, char *description);
|
||||
|
||||
/* data.c */
|
||||
struct keyvalue *initkeyvalues(void);
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
* (c) Lawrence Manning, 2001
|
||||
* Contains network library functions.
|
||||
*
|
||||
* $Id: netstuff.c,v 1.19.2.7 2004/11/05 23:40:17 alanh Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libsmooth.h"
|
||||
@@ -322,261 +320,184 @@ int interfacecheck(struct keyvalue *kv, char *colour)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Network probing! */
|
||||
struct nic nics[] = {
|
||||
{ "100VG-AnyLan Network Adapters, HP J2585B, J2585A, etc", "hp100" },
|
||||
{ "3Com EtherLink III", "3c509" },
|
||||
{ "3Com 3c501", "3c501" },
|
||||
{ "3Com ISA EtherLink XL", "3c515" },
|
||||
{ "3Com 3c503 and 3c503/16", "3c503" },
|
||||
{ "3Com EtherLink MC (3c523)", "3c523" },
|
||||
{ "3Com EtherLink MC/32 (3c527)", "3c527" },
|
||||
{ "3Com EtherLink Plus (3c505)", "3c505" },
|
||||
{ "3Com EtherLink 16", "3c507" },
|
||||
{ "3Com \"Corkscrew\" EtherLink PCI III/XL, etc.", "3c59x" },
|
||||
{ "3Com Typhoon Family (3C990, 3CR990, and variants)", "typhoon" },
|
||||
{ "Adaptec Starfire/DuraLAN", "starfire" },
|
||||
{ "Alteon AceNIC/3Com 3C985/Netgear GA620 Gigabit", "acenic" },
|
||||
{ "AMD8111 based 10/100 Ethernet Controller", "amd8111e" },
|
||||
{ "AMD LANCE/PCnetAllied Telesis AT1500, J2405A, etc", "lance" },
|
||||
{ "AMD PCnet32 and AMD PCnetPCI", "pcnet32" },
|
||||
{ "Ansel Communications EISA 3200", "ac3200" },
|
||||
{ "Apricot 680x0 VME, 82596 chipset", "82596" },
|
||||
{ "AT1700/1720", "at1700" },
|
||||
{ "Broadcom 4400", "b44" },
|
||||
{ "Broadcom Tigon3", "tg3" },
|
||||
{ "Cabletron E2100 series ethercards", "e2100" },
|
||||
{ "CATC USB NetMate-based Ethernet", "catc" },
|
||||
{ "CDC USB Ethernet", "CDCEther" },
|
||||
{ "Crystal LAN CS8900/CS8920", "cs89x0" },
|
||||
{ "Compaq Netelligent 10/100 TX PCI UTP, etc", "tlan" },
|
||||
{ "D-Link DL2000-based Gigabit Ethernet", "dl2k" },
|
||||
{ "Digi Intl. RightSwitch SE-X EISA and PCI", "dgrs" },
|
||||
{ "Digital 21x4x Tulip PCI ethernet cards, etc.", "tulip" },
|
||||
{ "Digital DEPCA & EtherWORKS,DEPCA, DE100, etc", "depca" },
|
||||
{ "DM9102 PCI Fast Ethernet Adapter", "dmfe", },
|
||||
{ "Dummy Network Card (testing)", "dummy", },
|
||||
{ "EtherWORKS DE425 TP/COAX EISA, DE434 TP PCI, etc.", "de4x5" },
|
||||
{ "EtherWORKS 3 (DE203, DE204 and DE205)", "ewrk3" },
|
||||
{ "HP PCLAN/plus", "hp-plus" },
|
||||
{ "HP LAN ethernet", "hp" },
|
||||
{ "IBM LANA", "ibmlana" },
|
||||
{ "ICL EtherTeam 16i/32" ,"eth16i" },
|
||||
{ "Intel i82557/i82558 PCI EtherExpressPro", "e100" },
|
||||
{ "Intel EtherExpress Cardbus Ethernet", "eepro100_cb" },
|
||||
{ "Intel i82595 ISA EtherExpressPro10/10+ driver" ,"eepro" },
|
||||
{ "Intel EtherExpress 16 (i82586)", "eexpress" },
|
||||
{ "Intel Panther onboard i82596 driver", "lp486e" },
|
||||
{ "Intel PRO/1000 Gigabit Ethernet", "e1000" },
|
||||
{ "KLSI USB KL5USB101-based", "kaweth" },
|
||||
{ "MiCom-Interlan NI5010 ethercard", "ni5010" },
|
||||
{ "Mylex EISA LNE390A/B", "lne390", },
|
||||
{ "Myson MTD-8xx PCI Ethernet", "fealnx" },
|
||||
{ "National Semiconductor DP8381x" , "natsemi" },
|
||||
{ "National Semiconductor DP83820" , "ns83820" },
|
||||
{ "NE/2 MCA", "ne2" },
|
||||
{ "NE2000 PCI cards, RealTEk RTL-8029, etc", "ne2k-pci" },
|
||||
{ "NE1000 / NE2000 (non-pci)", "ne" },
|
||||
{ "NI50 card (i82586 Ethernet chip)", "ni52" },
|
||||
{ "NI6510, ni6510 EtherBlaster", "ni65" },
|
||||
{ "Novell/Eagle/Microdyne NE3210 EISA", "ne3210" },
|
||||
{ "NVidia Nforce2 Driver", "forcedeth" },
|
||||
{ "Packet Engines Hamachi GNIC-II", "hamachi" },
|
||||
{ "Packet Engines Yellowfin Gigabit-NIC", "yellowfin" },
|
||||
{ "Pegasus/Pegasus-II USB ethernet", "pegasus" },
|
||||
{ "PureData PDUC8028,WD8003 and WD8013 compatibles", "wd" },
|
||||
{ "Racal-Interlan EISA ES3210", "es3210" },
|
||||
{ "RealTek RTL-8139 Fast Ethernet", "8139too" },
|
||||
{ "RealTek RTL-8139C+ series 10/100 PCI Ethernet", "8139cp" },
|
||||
{ "RealTek RTL-8150 USB ethernet", "rtl8150" },
|
||||
{ "RealTek RTL-8169 Gigabit Ethernet", "r8169" },
|
||||
{ "SiS 900 PCI", "sis900" },
|
||||
{ "SKnet MCA", "sk_mca" },
|
||||
{ "SMC 9000 series of ethernet cards", "smc9194" },
|
||||
{ "SMC EtherPower II", "epic100" },
|
||||
{ "SMC Ultra/EtherEZ ISA/PnP Ethernet", "smc-ultra" },
|
||||
{ "SMC Ultra32 EISA Ethernet", "smc-ultra32" },
|
||||
{ "SMC Ultra MCA Ethernet", "smc-mca" },
|
||||
{ "Sundance Alta", "sundance" },
|
||||
{ "SysKonnect SK-98xx", "sk98lin" },
|
||||
{ "Toshiba TC35815 Ethernet", "tc35815" },
|
||||
{ "Tulip chipset Cardbus Ethernet", "tulip_cb" },
|
||||
{ "USB Ethernet", "usbnet" },
|
||||
{ "VIA Rhine PCI Fast Ethernet, etc", "via-rhine" },
|
||||
{ "Winbond W89c840 Ethernet", "winbond-840" },
|
||||
{ "Xircom Cardbus Ethernet", "xircom_cb" },
|
||||
{ "Xircom (tulip-like) Cardbus Ethernet", "xircom_tulip_cb" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Funky routine for loading all drivers (cept those are already loaded.). */
|
||||
int probecards(char *driver, char *driveroptions)
|
||||
{
|
||||
int c;
|
||||
char **sections;
|
||||
char drivercount;
|
||||
int rc;
|
||||
int choice;
|
||||
int done = 0;
|
||||
char message[1000];
|
||||
char commandstring[STRING_SIZE];
|
||||
FILE *handle;
|
||||
char line[STRING_SIZE];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Count all nics. */
|
||||
mysystem("/bin/probenic.sh count");
|
||||
if ((handle = fopen("/drivercount", "r")))
|
||||
fgets(line, STRING_SIZE-1, handle);
|
||||
fclose(handle);
|
||||
//system("rm -f /drivercount");
|
||||
line[strlen(line) - 1] = 0;
|
||||
drivercount = strtok(line, ".");
|
||||
fprintf(flog, "Detected %s NICs in your system.\n", drivercount);
|
||||
if (!drivercount > 0) {
|
||||
char *strupper(char *s)
|
||||
{
|
||||
int n;
|
||||
for (n=0;s[n];n++) s[n]=toupper(s[n]);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
int write_configs_netudev(char *description, char *macaddr, char *colour)
|
||||
{
|
||||
#define UDEV_NET_CONF "/etc/udev/rules.d/30-persistent-network.rules"
|
||||
|
||||
FILE *fp;
|
||||
char commandstring[STRING_SIZE];
|
||||
struct keyvalue *kv = initkeyvalues();
|
||||
char temp1[STRING_SIZE], temp2[STRING_SIZE], temp3[STRING_SIZE];
|
||||
char ucolour[STRING_SIZE];
|
||||
|
||||
sprintf(ucolour, colour);
|
||||
strupper(ucolour);
|
||||
|
||||
if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
|
||||
{
|
||||
freekeyvalues(kv);
|
||||
errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sprintf(temp1, "%s_DEV", ucolour);
|
||||
sprintf(temp2, "%s_MACADDR", ucolour);
|
||||
sprintf(temp3, "%s0", colour);
|
||||
replacekeyvalue(kv, temp1, temp3);
|
||||
replacekeyvalue(kv, temp2, macaddr);
|
||||
|
||||
writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
|
||||
freekeyvalues(kv);
|
||||
|
||||
if( (fp = fopen(KNOWN_NICS, "a")) == NULL )
|
||||
{
|
||||
fprintf(stderr,"Couldn't open "KNOWN_NICS);
|
||||
return 1;
|
||||
}
|
||||
fprintf(fp,"%s;%s;\n", description, macaddr);
|
||||
fclose(fp);
|
||||
|
||||
sections = malloc(drivercount * sizeof(char *));
|
||||
// Make sure that there is no conflict
|
||||
snprintf(commandstring, STRING_SIZE, "/usr/bin/touch "UDEV_NET_CONF" >/dev/null 2>&1");
|
||||
system(commandstring);
|
||||
snprintf(commandstring, STRING_SIZE, "/bin/cat "UDEV_NET_CONF" | /bin/grep -v \"%s\" > "UDEV_NET_CONF" 2>/dev/null", macaddr);
|
||||
system(commandstring);
|
||||
snprintf(commandstring, STRING_SIZE, "/bin/cat "UDEV_NET_CONF" | /bin/grep -v \"%s\" > "UDEV_NET_CONF" 2>/dev/null", colour);
|
||||
system(commandstring);
|
||||
|
||||
struct driver drivers[drivercount];
|
||||
strcpy(drivers[0].modulename, "pcnet32");
|
||||
|
||||
fprintf(flog, "TEST0.\n");
|
||||
c = 0;
|
||||
while (drivers[c - 1].modulename)
|
||||
if( (fp = fopen(UDEV_NET_CONF, "a")) == NULL )
|
||||
{
|
||||
sections[c] = drivers[c - 1].description;
|
||||
fprintf(flog, "TEST1.\n");
|
||||
c++;
|
||||
}
|
||||
sections[c] = NULL;
|
||||
fprintf(flog, "TEST2.\n");
|
||||
|
||||
strcpy(driver, "");
|
||||
strcpy(driveroptions, "");
|
||||
|
||||
done = 0; choice = 1;
|
||||
while (!done)
|
||||
{
|
||||
rc = newtWinMenu(ctr[TR_SELECT_NETWORK_DRIVER],
|
||||
ctr[TR_SELECT_NETWORK_DRIVER_LONG], 50, 5, 5, 6,
|
||||
sections, &choice, ctr[TR_OK], ctr[TR_CANCEL], NULL);
|
||||
if (rc == 0 || rc == 1)
|
||||
{
|
||||
if (choice > 0)
|
||||
{
|
||||
/* Find module number, load module. */
|
||||
c = choice - 1;
|
||||
|
||||
if (!checkformodule(nics[c].modulename))
|
||||
{
|
||||
sprintf(commandstring, "/sbin/modprobe %s", nics[c].modulename);
|
||||
sprintf(message, ctr[TR_LOOKING_FOR_NIC], nics[c].description);
|
||||
if (runcommandwithstatus(commandstring, message) == 0)
|
||||
{
|
||||
strcpy(driver, nics[c].modulename);
|
||||
strcpy(driveroptions, "");
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
errorbox(ctr[TR_UNABLE_TO_LOAD_DRIVER_MODULE]);
|
||||
}
|
||||
else
|
||||
errorbox(ctr[TR_THIS_DRIVER_MODULE_IS_ALREADY_LOADED]);
|
||||
}
|
||||
else
|
||||
{
|
||||
manualdriver(driver, driveroptions);
|
||||
if (strlen(driver))
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
fprintf(stderr,"Couldn't open" UDEV_NET_CONF);
|
||||
return 1;
|
||||
}
|
||||
fprintf(fp,"ACTION==\"add\", SUBSYSTEM==\"net\", SYSFS{address}==\"%s\", NAME=\"%s0\" # %s\n", macaddr, colour, description);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* A listbox for selected the card... with a * MANUAL * entry at top for
|
||||
* manual module names. */
|
||||
int choosecards(char *driver, char *driveroptions)
|
||||
int nicmenu(char *colour)
|
||||
{
|
||||
int c;
|
||||
char **sections;
|
||||
int drivercount;
|
||||
int rc;
|
||||
int choice;
|
||||
char commandstring[STRING_SIZE];
|
||||
char message[STRING_SIZE];
|
||||
int done = 0;
|
||||
|
||||
/* Count 'em */
|
||||
c = 0; drivercount = 0;
|
||||
while (nics[c].modulename)
|
||||
{
|
||||
drivercount++;
|
||||
c++;
|
||||
}
|
||||
drivercount++;
|
||||
sections = malloc((drivercount + 1) * sizeof(char *));
|
||||
|
||||
/* Copy 'em. */
|
||||
c = 0;
|
||||
sections[c] = ctr[TR_MANUAL];
|
||||
c++;
|
||||
while (nics[c - 1].modulename)
|
||||
{
|
||||
sections[c] = nics[c - 1].description;
|
||||
c++;
|
||||
}
|
||||
sections[c] = NULL;
|
||||
|
||||
strcpy(driver, "");
|
||||
strcpy(driveroptions, "");
|
||||
|
||||
done = 0; choice = 1;
|
||||
while (!done)
|
||||
{
|
||||
rc = newtWinMenu(ctr[TR_SELECT_NETWORK_DRIVER],
|
||||
ctr[TR_SELECT_NETWORK_DRIVER_LONG], 50, 5, 5, 6,
|
||||
sections, &choice, ctr[TR_OK], ctr[TR_CANCEL], NULL);
|
||||
if (rc == 0 || rc == 1)
|
||||
{
|
||||
if (choice > 0)
|
||||
{
|
||||
/* Find module number, load module. */
|
||||
c = choice - 1;
|
||||
|
||||
if (!checkformodule(nics[c].modulename))
|
||||
{
|
||||
sprintf(commandstring, "/sbin/modprobe %s", nics[c].modulename);
|
||||
sprintf(message, ctr[TR_LOOKING_FOR_NIC], nics[c].description);
|
||||
if (runcommandwithstatus(commandstring, message) == 0)
|
||||
{
|
||||
strcpy(driver, nics[c].modulename);
|
||||
strcpy(driveroptions, "");
|
||||
done = 1;
|
||||
}
|
||||
else
|
||||
errorbox(ctr[TR_UNABLE_TO_LOAD_DRIVER_MODULE]);
|
||||
}
|
||||
else
|
||||
errorbox(ctr[TR_THIS_DRIVER_MODULE_IS_ALREADY_LOADED]);
|
||||
}
|
||||
else
|
||||
{
|
||||
manualdriver(driver, driveroptions);
|
||||
if (strlen(driver))
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}
|
||||
FILE *fp;
|
||||
char temp_line[STRING_SIZE];
|
||||
struct nic nics[20], *pnics;
|
||||
pnics = nics;
|
||||
struct knic knics[20], *pknics;
|
||||
pknics = knics;
|
||||
int rc, choise, count = 0, kcount = 0, i, found;
|
||||
char macaddr[STRING_SIZE], description[STRING_SIZE];
|
||||
char message[STRING_SIZE];
|
||||
|
||||
return 1;
|
||||
char MenuInhalt[20][80];
|
||||
char *pMenuInhalt[20];
|
||||
|
||||
mysystem("/bin/probenic.sh");
|
||||
|
||||
// Read the nics we already use
|
||||
if( (fp = fopen(KNOWN_NICS, "r")) == NULL )
|
||||
{
|
||||
fprintf(flog,"Couldn't open " KNOWN_NICS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (fgets(temp_line, STRING_SIZE, fp) != NULL)
|
||||
{
|
||||
strcpy(knics[kcount].description, strtok(temp_line,";"));
|
||||
strcpy(knics[kcount].macaddr , strtok(NULL,";"));
|
||||
if (strlen(knics[kcount].macaddr) > 5 ) kcount++;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
// Read our scanned nics
|
||||
if( (fp = fopen(SCANNED_NICS, "r")) == NULL )
|
||||
{
|
||||
fprintf(stderr,"Couldn't open "SCANNED_NICS);
|
||||
return 1;
|
||||
}
|
||||
while (fgets(temp_line, STRING_SIZE, fp) != NULL)
|
||||
{
|
||||
strcpy(description, strtok(temp_line,";"));
|
||||
strcpy(macaddr, strtok(NULL,";"));
|
||||
found = 0;
|
||||
if (strlen(macaddr) > 5 ) {
|
||||
for (i=0; i < kcount; i++)
|
||||
{
|
||||
// Check if the nic is already in use
|
||||
if (strcmp(pknics[i].macaddr, macaddr) == NULL )
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
strcpy( pnics[count].description , description );
|
||||
strcpy( pnics[count].macaddr , macaddr );
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
// If new nics are found...
|
||||
if (count > 0) {
|
||||
char cMenuInhalt[STRING_SIZE];
|
||||
for (i=0 ; i < count ; i++)
|
||||
{
|
||||
if ( strlen(nics[i].description) < 52 )
|
||||
strncpy(MenuInhalt[i], nics[i].description + 1, strlen(nics[i].description)- 2);
|
||||
else
|
||||
{
|
||||
strncpy(cMenuInhalt, nics[i].description + 1, 50);
|
||||
strncpy(MenuInhalt[i], cMenuInhalt,(strrchr(cMenuInhalt,' ') - cMenuInhalt));
|
||||
strcat (MenuInhalt[i], "...");
|
||||
}
|
||||
while ( strlen(MenuInhalt[i]) < 50)
|
||||
// Fill with space.
|
||||
strcat( MenuInhalt[i], " ");
|
||||
|
||||
strcat(MenuInhalt[i], " (");
|
||||
strcat(MenuInhalt[i], nics[i].macaddr);
|
||||
strcat(MenuInhalt[i], ")");
|
||||
pMenuInhalt[i] = MenuInhalt[i];
|
||||
}
|
||||
|
||||
sprintf(message, "Es wurde(n) %d freie Netzwerkkarte(n) in Ihrem System gefunden.\nBitte waehlen Sie im naechsten Dialog eine davon aus.\n", count);
|
||||
|
||||
newtWinMessage("NetcardMenu", ctr[TR_OK], message);
|
||||
|
||||
sprintf(message, "Bitte waehlen Sie eine der untenstehenden Netzwerkkarten fuer die Schnittstelle \"%s\" aus.\n", colour);
|
||||
|
||||
rc = newtWinMenu("NetcardMenu", message, 50, 5, 5, 6, pMenuInhalt, &choise, ctr[TR_OK], ctr[TR_SELECT], ctr[TR_CANCEL], NULL);
|
||||
|
||||
if ( rc == 0 || rc == 1) {
|
||||
write_configs_netudev(pnics[choise].description, pnics[choise].macaddr, colour);
|
||||
} else if (rc == 2) {
|
||||
manualdriver("pcnet32","");
|
||||
} else {
|
||||
errorbox("Sie haben keine Netzwerkkarte ausgewaehlt.\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
// We have to add here that you can manually add a device
|
||||
newtWinMessage("NetcardMenu", ctr[TR_OK], "Es wurden leider keine freien Netzwerkkarten fuer die Schnittstelle \"%s\" in ihrem System gefunden.", colour);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Manual entry for gurus. */
|
||||
@@ -624,56 +545,3 @@ int manualdriver(char *driver, char *driveroptions)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Returns the total number of nics current available as ethX devices. */
|
||||
int countcards(void)
|
||||
{
|
||||
FILE *file;
|
||||
char buffer[STRING_SIZE];
|
||||
char *start;
|
||||
int niccount = 0;
|
||||
|
||||
if (!(file = fopen("/proc/net/dev", "r")))
|
||||
{
|
||||
fprintf(flog, "Unable to open /proc/net/dev in countnics()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buffer, STRING_SIZE, file))
|
||||
{
|
||||
start = buffer;
|
||||
while (*start == ' ') start++;
|
||||
if (strncmp(start, "eth", strlen("eth")) == 0)
|
||||
niccount++;
|
||||
if (strncmp(start, "dummy", strlen("dummy")) == 0)
|
||||
niccount++;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return niccount;
|
||||
}
|
||||
|
||||
/* Finds the listed module name and copies the card description back. */
|
||||
int findnicdescription(char *modulename, char *description)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
if (strcmp(modulename, "pcmcia") == 0) {
|
||||
strcpy(description, "PCMCIA Ethernet card");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (nics[c].description)
|
||||
{
|
||||
if (strcmp(nics[c].modulename, modulename) == 0)
|
||||
{
|
||||
strcpy(description, nics[c].description);
|
||||
return 1;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
|
||||
strcpy(description, "UNKNOWN");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,199 +1,197 @@
|
||||
/* SmoothWall libsmooth.
|
||||
*
|
||||
* This program is distributed under the terms of the GNU General Public
|
||||
* Licence. See the file COPYING for details.
|
||||
*
|
||||
* (c) Lawrence Manning, 2001
|
||||
* Contains functions for manipulation files full of VAR=VAL pairs.
|
||||
*
|
||||
* 2003-07-27 Robert Kerr - Added cooperative file locking to prevent any
|
||||
* clashes between setuid programs reading configuration and cgi scripts
|
||||
* trying to write it
|
||||
*
|
||||
* $Id: varval.c,v 1.4 2003/12/11 11:25:53 riddles Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libsmooth.h"
|
||||
|
||||
/* Sets up the list. First entry is a dummy one to avoid having to special
|
||||
* case empty lists. */
|
||||
struct keyvalue *initkeyvalues(void)
|
||||
{
|
||||
struct keyvalue *head = malloc(sizeof(struct keyvalue));
|
||||
|
||||
strcpy(head->key, "KEY");
|
||||
strcpy(head->value, "VALUE");
|
||||
head->next = NULL;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/* Splats all the entries in a list. */
|
||||
void freekeyvalues(struct keyvalue *head)
|
||||
{
|
||||
struct keyvalue *cur = head->next;
|
||||
struct keyvalue *next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
next = cur->next;
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reads from a file into a new list. Uses appendkeyvalue to add entries.
|
||||
* Will bomb out on a error (eg bad format line). */
|
||||
int readkeyvalues(struct keyvalue *head, char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
char buffer[STRING_SIZE];
|
||||
char *temp;
|
||||
char *key, *value;
|
||||
|
||||
if (!(file = fopen(filename, "r")))
|
||||
return 0;
|
||||
|
||||
if (flock(fileno(file), LOCK_SH))
|
||||
{
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buffer, STRING_SIZE, file))
|
||||
{
|
||||
temp = buffer;
|
||||
while (*temp)
|
||||
{
|
||||
if (*temp =='\n') *temp = '\0';
|
||||
temp++;
|
||||
}
|
||||
if (!strlen(buffer))
|
||||
continue;
|
||||
if (!(temp = strchr(buffer, '=')))
|
||||
{
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
*temp = '\0';
|
||||
key = buffer; value = temp + 1;
|
||||
/* See if string is quoted. If so, skip first quote, and
|
||||
* nuke the one at the end. */
|
||||
if (value[0] == '\'')
|
||||
{
|
||||
value++;
|
||||
if ((temp = strrchr(value, '\'')))
|
||||
*temp = '\0';
|
||||
else
|
||||
{
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (strlen(key))
|
||||
appendkeyvalue(head, key, value);
|
||||
}
|
||||
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Writes out a list to a file. Easy. */
|
||||
int writekeyvalues(struct keyvalue *head, char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
struct keyvalue *cur = head->next;
|
||||
|
||||
if (!(file = fopen(filename, "w")))
|
||||
return 0;
|
||||
|
||||
if (flock(fileno(file), LOCK_EX))
|
||||
{
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while (cur)
|
||||
{
|
||||
/* No space in value? If there is, we need to quote the value
|
||||
* so the shell can read it. */
|
||||
if (!strchr(cur->value, ' '))
|
||||
fprintf(file, "%s=%s\n", cur->key, cur->value);
|
||||
else
|
||||
fprintf(file, "%s=\'%s\'\n", cur->key, cur->value);
|
||||
cur = cur->next;
|
||||
}
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Finds a key and copies the value back. value must be at least STRING_SIZE
|
||||
* long. Would be nice to have a func that just returns a pointer to the value?
|
||||
*/
|
||||
int findkey(struct keyvalue *head, char *key, char *value)
|
||||
{
|
||||
struct keyvalue *cur = head->next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (strcmp(key, cur->key) == 0)
|
||||
{
|
||||
strncpy(value, cur->value, STRING_SIZE);
|
||||
value[STRING_SIZE-1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Appends a entry. Not very efficent because it rescans the list looking
|
||||
* for the end. Maybe fix this later. */
|
||||
void appendkeyvalue(struct keyvalue *head, char *key, char *value)
|
||||
{
|
||||
struct keyvalue *new = malloc(sizeof(struct keyvalue));
|
||||
struct keyvalue *cur = head->next;
|
||||
struct keyvalue *tail = head;
|
||||
|
||||
strncpy(new->key, key, STRING_SIZE);
|
||||
strncpy(new->value, value, STRING_SIZE);
|
||||
new->key[STRING_SIZE-1] = '\0';
|
||||
new->value[STRING_SIZE-1] = '\0';
|
||||
new->next = NULL;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
tail = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
tail->next = new;
|
||||
}
|
||||
|
||||
/* Otherwrites a key with a new value, or if it dosn't exist, appends it
|
||||
* on the end. */
|
||||
void replacekeyvalue(struct keyvalue *head, char *key, char *value)
|
||||
{
|
||||
struct keyvalue *cur = head->next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (strcmp(cur->key, key) == 0)
|
||||
{
|
||||
strncpy(cur->value, value, STRING_SIZE);
|
||||
cur->value[STRING_SIZE-1] = '\0';
|
||||
return;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
appendkeyvalue(head, key, value);
|
||||
}
|
||||
/* SmoothWall libsmooth.
|
||||
*
|
||||
* This program is distributed under the terms of the GNU General Public
|
||||
* Licence. See the file COPYING for details.
|
||||
*
|
||||
* (c) Lawrence Manning, 2001
|
||||
* Contains functions for manipulation files full of VAR=VAL pairs.
|
||||
*
|
||||
* 2003-07-27 Robert Kerr - Added cooperative file locking to prevent any
|
||||
* clashes between setuid programs reading configuration and cgi scripts
|
||||
* trying to write it
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libsmooth.h"
|
||||
|
||||
/* Sets up the list. First entry is a dummy one to avoid having to special
|
||||
* case empty lists. */
|
||||
struct keyvalue *initkeyvalues(void)
|
||||
{
|
||||
struct keyvalue *head = malloc(sizeof(struct keyvalue));
|
||||
|
||||
strcpy(head->key, "KEY");
|
||||
strcpy(head->value, "VALUE");
|
||||
head->next = NULL;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
/* Splats all the entries in a list. */
|
||||
void freekeyvalues(struct keyvalue *head)
|
||||
{
|
||||
struct keyvalue *cur = head->next;
|
||||
struct keyvalue *next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
next = cur->next;
|
||||
free(cur);
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reads from a file into a new list. Uses appendkeyvalue to add entries.
|
||||
* Will bomb out on a error (eg bad format line). */
|
||||
int readkeyvalues(struct keyvalue *head, char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
char buffer[STRING_SIZE];
|
||||
char *temp;
|
||||
char *key, *value;
|
||||
|
||||
if (!(file = fopen(filename, "r")))
|
||||
return 0;
|
||||
|
||||
if (flock(fileno(file), LOCK_SH))
|
||||
{
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buffer, STRING_SIZE, file))
|
||||
{
|
||||
temp = buffer;
|
||||
while (*temp)
|
||||
{
|
||||
if (*temp =='\n') *temp = '\0';
|
||||
temp++;
|
||||
}
|
||||
if (!strlen(buffer))
|
||||
continue;
|
||||
if (!(temp = strchr(buffer, '=')))
|
||||
{
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
*temp = '\0';
|
||||
key = buffer; value = temp + 1;
|
||||
/* See if string is quoted. If so, skip first quote, and
|
||||
* nuke the one at the end. */
|
||||
if (value[0] == '\'')
|
||||
{
|
||||
value++;
|
||||
if ((temp = strrchr(value, '\'')))
|
||||
*temp = '\0';
|
||||
else
|
||||
{
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (strlen(key))
|
||||
appendkeyvalue(head, key, value);
|
||||
}
|
||||
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Writes out a list to a file. Easy. */
|
||||
int writekeyvalues(struct keyvalue *head, char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
struct keyvalue *cur = head->next;
|
||||
|
||||
if (!(file = fopen(filename, "w")))
|
||||
return 0;
|
||||
|
||||
if (flock(fileno(file), LOCK_EX))
|
||||
{
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while (cur)
|
||||
{
|
||||
/* No space in value? If there is, we need to quote the value
|
||||
* so the shell can read it. */
|
||||
if (!strchr(cur->value, ' '))
|
||||
fprintf(file, "%s=%s\n", cur->key, cur->value);
|
||||
else
|
||||
fprintf(file, "%s=\'%s\'\n", cur->key, cur->value);
|
||||
cur = cur->next;
|
||||
}
|
||||
flock(fileno(file), LOCK_UN);
|
||||
fclose(file);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Finds a key and copies the value back. value must be at least STRING_SIZE
|
||||
* long. Would be nice to have a func that just returns a pointer to the value?
|
||||
*/
|
||||
int findkey(struct keyvalue *head, char *key, char *value)
|
||||
{
|
||||
struct keyvalue *cur = head->next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (strcmp(key, cur->key) == 0)
|
||||
{
|
||||
strncpy(value, cur->value, STRING_SIZE);
|
||||
value[STRING_SIZE-1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Appends a entry. Not very efficent because it rescans the list looking
|
||||
* for the end. Maybe fix this later. */
|
||||
void appendkeyvalue(struct keyvalue *head, char *key, char *value)
|
||||
{
|
||||
struct keyvalue *new = malloc(sizeof(struct keyvalue));
|
||||
struct keyvalue *cur = head->next;
|
||||
struct keyvalue *tail = head;
|
||||
|
||||
strncpy(new->key, key, STRING_SIZE);
|
||||
strncpy(new->value, value, STRING_SIZE);
|
||||
new->key[STRING_SIZE-1] = '\0';
|
||||
new->value[STRING_SIZE-1] = '\0';
|
||||
new->next = NULL;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
tail = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
tail->next = new;
|
||||
}
|
||||
|
||||
/* Otherwrites a key with a new value, or if it dosn't exist, appends it
|
||||
* on the end. */
|
||||
void replacekeyvalue(struct keyvalue *head, char *key, char *value)
|
||||
{
|
||||
struct keyvalue *cur = head->next;
|
||||
|
||||
while (cur)
|
||||
{
|
||||
if (strcmp(cur->key, key) == 0)
|
||||
{
|
||||
strncpy(cur->value, value, STRING_SIZE);
|
||||
cur->value[STRING_SIZE-1] = '\0';
|
||||
return;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
appendkeyvalue(head, key, value);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,6 @@ int handlenetworking(void)
|
||||
ctr[TR_PUSHING_NETWORK_DOWN]);
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network start",
|
||||
ctr[TR_PULLING_NETWORK_UP]);
|
||||
// mysystem("/etc/rc.d/rc.pcmcia start");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,11 +244,7 @@ int configtypemenu(void)
|
||||
|
||||
if (rc == 0 || rc == 1)
|
||||
{
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network red down",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network blue down",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network orange down",
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network stop red blue orange",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
|
||||
sprintf(temp, "%d", choice);
|
||||
@@ -269,12 +264,15 @@ int configtypemenu(void)
|
||||
/* Driver menu. Choose drivers.. */
|
||||
int drivermenu(void)
|
||||
{
|
||||
FILE *fp;
|
||||
struct keyvalue *kv = initkeyvalues();
|
||||
char message[1000];
|
||||
char message[1000], macaddr[STRING_SIZE];
|
||||
char temp_line[STRING_SIZE];
|
||||
char temp[STRING_SIZE], temp1[STRING_SIZE];
|
||||
char driver[STRING_SIZE], dev[STRING_SIZE];
|
||||
struct knic knics[20], *pknics;
|
||||
pknics = knics;
|
||||
int configtype;
|
||||
int rc;
|
||||
int rc, i = 0, kcount = 0;
|
||||
|
||||
if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
|
||||
{
|
||||
@@ -295,38 +293,60 @@ int drivermenu(void)
|
||||
|
||||
strcpy(message, ctr[TR_CONFIGURE_NETWORK_DRIVERS]);
|
||||
|
||||
/* This horrible big formats the heading :( */
|
||||
strcpy(driver, ""); findkey(kv, "GREEN_DISPLAYDRIVER", driver);
|
||||
findnicdescription(driver, temp);
|
||||
strcpy(dev, ctr[TR_UNSET]); findkey(kv, "GREEN_DEV", dev);
|
||||
if (!strlen(dev)) strcpy(dev, ctr[TR_UNSET]);
|
||||
sprintf(temp1, "GREEN: %s (%s)\n", temp, dev);
|
||||
if( (fp = fopen(KNOWN_NICS, "r")) == NULL )
|
||||
{
|
||||
fprintf(flog,"Couldn't open " KNOWN_NICS);
|
||||
return 1;
|
||||
}
|
||||
while (fgets(temp_line, STRING_SIZE, fp) != NULL)
|
||||
{
|
||||
strcpy(knics[kcount].description, strtok(temp_line,";"));
|
||||
strcpy(knics[kcount].macaddr , strtok(NULL,";"));
|
||||
if (strlen(knics[kcount].macaddr) > 5 ) kcount++;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
strcpy(macaddr, ctr[TR_UNSET]);
|
||||
findkey(kv, "GREEN_MACADDR", macaddr);
|
||||
for (i=0; i < kcount; i++)
|
||||
{ // Check if the nic is already in use
|
||||
if (strcmp(pknics[i].macaddr, macaddr) == NULL )
|
||||
break;
|
||||
}
|
||||
sprintf(temp1, "GREEN: %s (%s / green0)\n", pknics[i].description, pknics[i].macaddr);
|
||||
strcat(message, temp1);
|
||||
if (HAS_BLUE)
|
||||
{
|
||||
strcpy(driver, ""); findkey(kv, "BLUE_DISPLAYDRIVER", driver);
|
||||
findnicdescription(driver, temp);
|
||||
strcpy(dev, ctr[TR_UNSET]); findkey(kv, "BLUE_DEV", dev);
|
||||
if (!strlen(dev)) strcpy(dev, ctr[TR_UNSET]);
|
||||
sprintf(temp1, "BLUE: %s (%s)\n", temp, dev);
|
||||
|
||||
if (HAS_BLUE) {
|
||||
strcpy(macaddr, ctr[TR_UNSET]);
|
||||
findkey(kv, "BLUE_MACADDR", macaddr);
|
||||
for (i=0; i < kcount; i++)
|
||||
{ // Check if the nic is already in use
|
||||
if (strcmp(pknics[i].macaddr, macaddr) == NULL )
|
||||
break;
|
||||
}
|
||||
sprintf(temp1, "BLUE: %s (%s / blue0)\n", pknics[i].description, pknics[i].macaddr);
|
||||
strcat(message, temp1);
|
||||
}
|
||||
if (HAS_ORANGE)
|
||||
{
|
||||
strcpy(driver, ""); findkey(kv, "ORANGE_DISPLAYDRIVER", driver);
|
||||
findnicdescription(driver, temp);
|
||||
strcpy(dev, ctr[TR_UNSET]); findkey(kv, "ORANGE_DEV", dev);
|
||||
if (!strlen(dev)) strcpy(dev, ctr[TR_UNSET]);
|
||||
sprintf(temp1, "ORANGE: %s (%s)\n", temp, dev);
|
||||
if (HAS_ORANGE) {
|
||||
strcpy(macaddr, ctr[TR_UNSET]);
|
||||
findkey(kv, "ORANGE_MACADDR", macaddr);
|
||||
for (i=0; i < kcount; i++)
|
||||
{ // Check if the nic is already in use
|
||||
if (strcmp(pknics[i].macaddr, macaddr) == NULL )
|
||||
break;
|
||||
}
|
||||
sprintf(temp1, "ORANGE: %s (%s / orange0)\n", pknics[i].description, pknics[i].macaddr);
|
||||
strcat(message, temp1);
|
||||
}
|
||||
if (HAS_RED)
|
||||
{
|
||||
strcpy(driver, ""); findkey(kv, "RED_DISPLAYDRIVER", driver);
|
||||
findnicdescription(driver, temp);
|
||||
strcpy(dev, ctr[TR_UNSET]); findkey(kv, "RED_DEV", dev);
|
||||
if (!strlen(dev)) strcpy(dev, ctr[TR_UNSET]);
|
||||
sprintf(temp1, "RED: %s (%s)\n", temp, dev);
|
||||
if (HAS_RED) {
|
||||
strcpy(macaddr, ctr[TR_UNSET]);
|
||||
findkey(kv, "RED_MACADDR", macaddr);
|
||||
for (i=0; i < kcount; i++)
|
||||
{ // Check if the nic is already in use
|
||||
if (strcmp(pknics[i].macaddr, macaddr) == NULL )
|
||||
break;
|
||||
}
|
||||
sprintf(temp1, "RED: %s (%s / red0)\n", pknics[i].description, pknics[i].macaddr);
|
||||
strcat(message, temp1);
|
||||
}
|
||||
strcat(message, ctr[TR_DO_YOU_WISH_TO_CHANGE_THESE_SETTINGS]);
|
||||
@@ -343,26 +363,22 @@ int drivermenu(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cardassigned(char *colour)
|
||||
{
|
||||
char command[STRING_SIZE];
|
||||
sprintf(command, "grep -q %s < /etc/udev/rules.d/30-persistent-network.rules 2>/dev/null", colour);
|
||||
if (system(command))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int changedrivers(void)
|
||||
{
|
||||
struct keyvalue *kv = initkeyvalues();
|
||||
char message[1000];
|
||||
char temp[STRING_SIZE];
|
||||
char driver[STRING_SIZE];
|
||||
int configtype;
|
||||
int rc;
|
||||
int c;
|
||||
int needcards, sofarallocated, countofcards, toallocate;
|
||||
char *orange = "ORANGE";
|
||||
char *blue = "BLUE";
|
||||
char *red = "RED";
|
||||
char *sections[4];
|
||||
int choice;
|
||||
char nexteth[STRING_SIZE];
|
||||
int abort;
|
||||
char currentdriver[STRING_SIZE], currentdriveroptions[STRING_SIZE];
|
||||
char displaydriver[STRING_SIZE];
|
||||
struct stat st;
|
||||
int green = 0, red = 0, blue = 0, orange = 0;
|
||||
|
||||
if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
|
||||
{
|
||||
@@ -370,186 +386,46 @@ int changedrivers(void)
|
||||
errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
strcpy(temp, "0"); findkey(kv, "CONFIG_TYPE", temp);
|
||||
configtype = atol(temp);
|
||||
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network red down",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network blue down",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network orange down",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
|
||||
/* Remove all modules not needed for green networking. */
|
||||
c = 0;
|
||||
strcpy(driver, ""); findkey(kv, "GREEN_DRIVER", driver);
|
||||
if (strcmp(driver, "pcmcia") != 0) {
|
||||
stat("/proc/bus/pccard", &st);
|
||||
mysystem("/etc/rc.d/rc.pcmcia stop");
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
mysystem("/sbin/modprobe pcmcia_core");
|
||||
mysystem("/sbin/modprobe pcmcia-controller");
|
||||
mysystem("/sbin/modprobe ds");
|
||||
}
|
||||
}
|
||||
while (nics[c].modulename)
|
||||
{
|
||||
if (strcmp(nics[c].modulename, driver) != 0)
|
||||
{
|
||||
if (checkformodule(nics[c].modulename))
|
||||
{
|
||||
sprintf(temp, "/sbin/rmmod %s", nics[c].modulename);
|
||||
mysystem(temp);
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
|
||||
/* Blank them so the rc.netaddress.up does not get confused. */
|
||||
replacekeyvalue(kv, "ORANGE_DEV", "");
|
||||
replacekeyvalue(kv, "BLUE_DEV", "");
|
||||
replacekeyvalue(kv, "RED_DEV", "");
|
||||
|
||||
runcommandwithstatus("/etc/rc.d/init.d/network stop red blue orange",
|
||||
ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);
|
||||
|
||||
if (configtype == 0)
|
||||
needcards = 1;
|
||||
else if (configtype == 1 || configtype == 2 || configtype == 4)
|
||||
needcards = 2;
|
||||
{ green = 1; }
|
||||
else if (configtype == 1)
|
||||
{ green = 1; orange = 1; }
|
||||
else if (configtype == 2)
|
||||
{ green = 1; red = 1; }
|
||||
else if (configtype == 3)
|
||||
{ green = 1; red = 1; orange = 1; }
|
||||
else if (configtype == 4)
|
||||
{ green = 1; blue = 1; }
|
||||
else if (configtype == 5)
|
||||
{ green = 1; blue = 1; orange = 1; }
|
||||
else if (configtype == 6)
|
||||
{ green = 1; red = 1; blue = 1; }
|
||||
else if (configtype == 7)
|
||||
needcards = 4;
|
||||
else
|
||||
needcards = 3;
|
||||
|
||||
/* This is the green card. */
|
||||
sofarallocated = 1;
|
||||
|
||||
findkey(kv, "GREEN_DRIVER", currentdriver);
|
||||
findkey(kv, "GREEN_DRIVER_OPTIONS", currentdriveroptions);
|
||||
strcpy(displaydriver, currentdriver);
|
||||
{ green = 1; red = 1; blue = 1; orange = 1;}
|
||||
|
||||
if (countcards() > 1)
|
||||
strcpy(currentdriver, "");
|
||||
|
||||
abort = 0;
|
||||
/* Keep going till all cards are got, or they give up. */
|
||||
while (sofarallocated < needcards && !abort)
|
||||
{
|
||||
countofcards = countcards();
|
||||
|
||||
/* This is how many cards were added by the last module. */
|
||||
toallocate = countofcards - sofarallocated;
|
||||
while (toallocate > 0 && sofarallocated < needcards)
|
||||
{
|
||||
findnicdescription(displaydriver, temp);
|
||||
sprintf(message, ctr[TR_UNCLAIMED_DRIVER], temp);
|
||||
c = 0; choice = 0;
|
||||
strcpy(temp, ""); findkey(kv, "BLUE_DEV", temp);
|
||||
if (HAS_BLUE && !strlen(temp))
|
||||
{
|
||||
sections[c] = blue;
|
||||
c++;
|
||||
}
|
||||
strcpy(temp, ""); findkey(kv, "ORANGE_DEV", temp);
|
||||
if (HAS_ORANGE && !strlen(temp))
|
||||
{
|
||||
sections[c] = orange;
|
||||
c++;
|
||||
}
|
||||
strcpy(temp, ""); findkey(kv, "RED_DEV", temp);
|
||||
if (HAS_RED && !strlen(temp))
|
||||
{
|
||||
sections[c] = red;
|
||||
c++;
|
||||
}
|
||||
sections[c] = NULL;
|
||||
rc = newtWinMenu(ctr[TR_CARD_ASSIGNMENT],
|
||||
message, 50, 5, 5, 6, sections, &choice, ctr[TR_OK],
|
||||
ctr[TR_CANCEL], NULL);
|
||||
if (rc == 0 || rc == 1)
|
||||
{
|
||||
/* Now we see which iface needs its settings changed. */
|
||||
sprintf(nexteth, "eth%d", sofarallocated);
|
||||
if (strcmp(sections[choice], blue) == 0)
|
||||
{
|
||||
replacekeyvalue(kv, "BLUE_DEV", nexteth);
|
||||
replacekeyvalue(kv, "BLUE_DRIVER", currentdriver);
|
||||
replacekeyvalue(kv, "BLUE_DRIVER_OPTIONS", currentdriveroptions);
|
||||
replacekeyvalue(kv, "BLUE_DISPLAYDRIVER", displaydriver);
|
||||
sofarallocated++;
|
||||
toallocate--;
|
||||
strcpy(currentdriver, "");
|
||||
strcpy(currentdriveroptions, "");
|
||||
}
|
||||
if (strcmp(sections[choice], orange) == 0)
|
||||
{
|
||||
replacekeyvalue(kv, "ORANGE_DEV", nexteth);
|
||||
replacekeyvalue(kv, "ORANGE_DRIVER", currentdriver);
|
||||
replacekeyvalue(kv, "ORANGE_DRIVER_OPTIONS", currentdriveroptions);
|
||||
replacekeyvalue(kv, "ORANGE_DISPLAYDRIVER", displaydriver);
|
||||
sofarallocated++;
|
||||
toallocate--;
|
||||
strcpy(currentdriver, "");
|
||||
strcpy(currentdriveroptions, "");
|
||||
}
|
||||
if (strcmp(sections[choice], red) == 0)
|
||||
{
|
||||
replacekeyvalue(kv, "RED_DEV", nexteth);
|
||||
replacekeyvalue(kv, "RED_DRIVER", currentdriver);
|
||||
replacekeyvalue(kv, "RED_DRIVER_OPTIONS", currentdriveroptions);
|
||||
replacekeyvalue(kv, "RED_DISPLAYDRIVER", displaydriver);
|
||||
sofarallocated++;
|
||||
toallocate--;
|
||||
strcpy(currentdriver, "");
|
||||
strcpy(currentdriveroptions, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Need another module! The nitty gritty code is in libsmooth. */
|
||||
if (sofarallocated < needcards)
|
||||
{
|
||||
rc = newtWinTernary(ctr[TR_CARD_ASSIGNMENT], ctr[TR_PROBE],
|
||||
ctr[TR_SELECT], ctr[TR_CANCEL], ctr[TR_NO_UNALLOCATED_CARDS]);
|
||||
|
||||
if (rc == 0 || rc == 1)
|
||||
{
|
||||
probecards(currentdriver, currentdriveroptions);
|
||||
if (!strlen(currentdriver))
|
||||
errorbox(ctr[TR_PROBE_FAILED]);
|
||||
}
|
||||
else if (rc == 2)
|
||||
choosecards(currentdriver, currentdriveroptions);
|
||||
else
|
||||
abort = 1;
|
||||
|
||||
strcpy(displaydriver, currentdriver);
|
||||
}
|
||||
}
|
||||
if (green && !cardassigned("green"))
|
||||
nicmenu("green");
|
||||
if (red && !cardassigned("red"))
|
||||
nicmenu("red");
|
||||
if (blue && !cardassigned("blue"))
|
||||
nicmenu("blue");
|
||||
if (orange && !cardassigned("orange"))
|
||||
nicmenu("orange");
|
||||
|
||||
countofcards = countcards();
|
||||
|
||||
if (countofcards >= needcards)
|
||||
{
|
||||
newtWinMessage(ctr[TR_CARD_ASSIGNMENT], ctr[TR_OK],
|
||||
ctr[TR_ALL_CARDS_SUCCESSFULLY_ALLOCATED]);
|
||||
}
|
||||
else
|
||||
errorbox(ctr[TR_NOT_ENOUGH_CARDS_WERE_ALLOCATED]);
|
||||
|
||||
writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
|
||||
// writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
|
||||
|
||||
freekeyvalues(kv);
|
||||
|
||||
netaddresschange = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Let user change GREEN address. */
|
||||
// Let user change GREEN address.
|
||||
int greenaddressmenu(void)
|
||||
{
|
||||
struct keyvalue *kv = initkeyvalues();
|
||||
@@ -581,7 +457,7 @@ int greenaddressmenu(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* They can change BLUE, ORANGE and GREEN too :) */
|
||||
// They can change BLUE, ORANGE and GREEN too :)
|
||||
int addressesmenu(void)
|
||||
{
|
||||
struct keyvalue *kv = initkeyvalues();
|
||||
|
||||
Reference in New Issue
Block a user