#!/bin/bash # # /etc/rc.d/rc.sysinit - run once at boot time # # # Useful functions # function nthword () { n=0 for foo in $* ; do if [ $n -eq $1 ] then echo $foo fi n=$(($n+1)) done } function runme () { echo "Scanning for $1 repair scripts" for foo in /var/persist/*.$1 ; do if [ -f $foo ] then echo "Running repair program $foo" rm -f $foo.old mv $foo $foo.old chmod 555 $foo.old if /tvbin/crypto -vfs $foo.sig $foo.old /tvlib/misc/service-v3-s.pub ; then $foo.old || echo "$foo failed." else echo "$foo failed signature check." fi rm -f $foo.old $foo.sig fi done } function fixmodem { typeset MAXTRIES=3 typeset MODEMTYPE=/tvlib/modem/utils/modemtype.expect if test ! -r $MODEMTYPE ; then echo "fixmodem: no modem id program: $MODEMTYPE" return fi typeset modem_name=$(/bin/expect $MODEMTYPE) if test -z "$modem_name" ; then echo "fixmodem: no modem name" return fi typeset PATCHER=/tvlib/modem/patches/$modem_name/ram/expect_script if test ! -r $PATCHER ; then echo "fixmodem: no patcher: $PATCHER" return fi # # There is a patcher. # Let's see how many times we have tried to use it. # The file is supposed to consist of a single line; the number # of characters on that line is the number of tries so far. # typeset FLAGFILE=/var/persist/modem_patch_tries # # The FLAGFILE must be a regular file, and it must be readable and writable. # Otherwise, the file is created from scratch. # test -f $FLAGFILE -a -r $FLAGFILE -a -w $FLAGFILE || { rm -rf $FLAGFILE echo 'X' > $FLAGFILE } echo "Attempting to fix modem using: $PATCHER" /bin/expect $PATCHER typeset result=$? if test $result -ne 0 ; then typeset line tries read line < $FLAGFILE tries=${#line} if test $tries -lt $MAXTRIES ; then echo "Failed to fix modem; this was try #$tries" line="${line}X" echo $line > $FLAGFILE # # Verify that the file size has actually changed # typeset new_line read new_line < $FLAGFILE if test "$new_line" = "$line" ; then sync sync sync echo "Rebooting system to attempt another modem patch" reboot fi echo "Failed to increase try count (file system full ?)" else echo "Too many unsuccessful tries to patch modem: $tries (giving up)" fi fi # # Eliminate the FLAGFILE, so that next time we reboot, we start # the whole patch process again. # rm -f $FLAGFILE } # Set the path PATH=/devbin:/bin:/sbin:/tvbin:/hack/bin export PATH # Read in our testing configuration, if there is one. [ ! -f /test.conf ] || source /test.conf if [ "$sysgen" = true ]; then echo Starting shared library installation environment echo You may either Telnet in or type into secondary echo serial port. Both the serial port and the telnet echo connection will run bash as the login shell. echo setting hostname to `/bin/getprom -hostname` >& /dev/console /bin/hostname `/bin/getprom -hostname` >& /dev/console echo setting ipaddr to `/bin/getprom -ipaddr` >& /dev/console echo setting macaddr to `/bin/getprom -macaddr` >& /dev/console /sbin/ifconfig eth0 hw ether `/bin/getprom -macaddr` `/bin/getprom -ipaddr` >& /dev/console echo Starting Telnet Listner ... >& /dev/console /sbin/tnlited 23 /bin/bash >& /dev/console echo Starting /proc Listener ... >& /dev/console mount /proc >& /dev/console /tvbin/procd >& /dev/console >& /dev/console while true; do sleep 1000; done fi # Some tcl scripts expect TIVO_ROOT to be set. It would be cleaner to # just use the path, but that's not the way it is right now. The # contents of TIVO_ROOT is prepended to paths, so the empty string is # just fine. TIVO_ROOT= export TIVO_ROOT echo "Starting rc.sysinit" # Release the old initrd echo "Releasing /initrd and clearing ramdisk, if they exist" umount -n /initrd freeramdisk /dev/ram # Start up swapping. echo "Activating swap partitions" swapon -a echo "Loading i2c driver" insmod /lib/modules/i2c.o videoconfig=`getprom -videoconfig` # By default, we are running in NTSC mode. if [ "$TV_STD" = "" ]; then case $videoconfig in 0|1|2|3|4|5|6) export TV_STD=NTSC;; 7) export TV_STD=PAL;; esac fi echo "Box setup for $TV_STD mode" # This shouldn't be here... Drivers should autoconfig. echo "Loading FPGA driver" case $videoconfig in 0 | 1) insmod /lib/modules/fpga7114_p15.o sTVStandard=$TV_STD;; 2) insmod /lib/modules/fpga7112.o sTVStandard=$TV_STD;; 3|4|7) insmod /lib/modules/fpga7114.o sTVStandard=$TV_STD;; 5|6) insmod /lib/modules/fpgacombo.o sTVStandard=$TV_STD;; esac # This should be read from /etc/fstab... or a config file somewhere. export varpartition=/dev/hda9 # Check for panic signal echo "Checking for Kickstart panic signal" checkpanic panic=$? export EMERGENCY_REINSTALL=0 do_mfs_assert=0 do_mfs_cleanup=0 if [ $panic -ne 0 ] ; then case $panic in 169) echo "Kickstart code 5 2 - emergency reinstall" export EMERGENCY_REINSTALL=1 ;; 174) echo "Kickstart code 5 7 - force MFS check" do_mfs_assert=1 ;; 175) echo "Kickstart code 5 8 - perform MFS cleanup" do_mfs_cleanup=1 ;; *) kickstart $panic reboot ;; esac fi echo "Cleanup $varpartition pass 1" if e2fsck -p $varpartition ; then echo "$varpartition is clean" else echo "Cleanup $varpartition pass 2" if e2fsck -p $varpartition ; then echo "$varpartition is clean after pass 2" else echo "Can't clean $varpartition - rebuilding" mke2fs -c $varpartition echo "Mounting /var to rebuild it" mount -t ext2 -n $varpartition /var mkdir /var/log /var/tmp /var/run /var/packages /var/dev /var/bin /var/utils /var/persist rm -f /var/hack ln -sf /hack /var/hack rm -f /var/mfs_ftp ln -sf /hack/mfs_ftp /var/mfs_ftp umount -n /var fi fi echo "Mounting /var" # If this is an NFS root, we may want to allow for /var to stay in root mount -v -n /var echo "Cleaning up /var/mtab..." cp /dev/null /var/mtab # Set the TIVO_SVR_ADDR up. if [ ! "$xTIVO_SVR_ADDR" = "" ]; then echo "Changing SVR ADDR to $xTIVO_SVR_ADDR" export TIVO_SVR_ADDR=$xTIVO_SVR_ADDR else echo "Using default TIVO_SVR_ADDR" export TIVO_SVR_ADDR=192.168.50.1:80 fi echo "Mounting initial environment..." mount -f / mount -f /var mount /proc /proc -t proc echo "Cleaning up temporary files in /var/tmp" rm -rf /var/tmp mkdir /var/tmp for dir in /var/log /var/run /var/packages /var/utils /var/persist /var/dev ; do if [ ! -d $dir ] ; then rm -rf $dir mkdir $dir fi done echo "Cleaning up old slices and bundles in /var/packages..." rm -f /var/packages/*slice rm -f /var/packages/*bnd rm -f /var/packages/*jpm rm -f /var/packages/*cpio rm -f /var/packages/*gz echo "Checking space in /var" dfspace=$(df -P /var) purge=0 if [ ! -z "$dfspace" ]; then spacepct=$(nthword 12 $dfspace) if [ ! -z "$spacepct" ]; then spaceused=${spacepct%'%'} if [ ! -z "$spaceused" ]; then if [ $spaceused -gt 40 ]; then purge=1 fi fi fi fi old_log_cleanup=0 too_big_logs="" if [ $purge -ne 0 ]; then echo "/var partition is rather full..." du -s /var echo "Removing old logs..." rm -f /var/log/O* old_log_cleanup=1 for foo in /var/log/* ; do filesize=$(du -s "$foo") if [ ! -z "$filesize" ]; then kbytes=$(nthword 1 $filesize) if [ ! -z "$kbytes" ]; then if [ $kbytes -gt 10000 ]; then echo "$foo is too big, removing it" too_big_logs="$too_big_logs $foo" rm -f "$foo" fi fi fi done echo "Performed an emergency /var cleanup" >> /var/log/messages fi fixmodem # Run the Phase 1 (/var is mounted and has some free space) scripts runme phase1 echo "Initializing TiVo extension..." # TODO: tivosetup ??? what does this do in tivosh? echo "Set up environment vars for hardware configuration..." # Need a way to override these... # Should just source /etc/tivoconfig/hardware... It should set these up... if [ "$TIVO_REMOTE" = "" ]; then export TIVO_REMOTE=TIVO; fi echo "Remote control is " $TIVO_REMOTE if [ "$MFS_DEVICE" = "" ]; then export MFS_DEVICE=/dev/hda10; fi echo "MFS partition on " $MFS_DEVICE echo "Loading media drivers..." if [ "$runideturbo" = false ]; then echo "Running without ideturbo mode ..." else echo "Loading ideturbo ..." insmod /lib/modules/ideturbo.o fi if [ "$LOG5505TOSERIAL" = true ]; then echo "installing oslink.o" insmod /lib/modules/oslink.o echo "Waiting for response on DSS serial port" /bin/expect /etc/boot.expect > /dev/ttyDSS < /dev/ttyDSS if [ ! $? = 0 ]; then jeiboot=true else echo "Booting from oslink..." > /dev/ttyDSS fi fi asicversion=`/bin/asicVersion` if [[ "$oslink" = false || "$jeiboot" = true ]]; then echo "Not going to boot over oslink ..." else echo "Auto-detecting oslink module (asic $asicversion)." #if [ "$tuner1" = "" ]; then # tuner1=199; #fi #if [ "$tuner2" = "" ]; then # tuner2=199; #fi # #case $tuner1 in #199) # tunerboot1="/etccombo/boot199.btl" # ;; #299) # tunerboot1="/etccombo/boot299.btl" # ;; #esac # #case $tuner2 in #199) # tunerboot2="/etccombo/boot199.btl" # ;; #299) # tunerboot2="/etccombo/boot299.btl" # ;; #esac case `/bin/getprom -tunerconfig` in 0) tuner1=199 tuner2=199 ;; 1) tuner1=299 tuner2=199 ;; 2) tuner1=199 tuner2=299 ;; 3) tuner1=299 tuner2=299 ;; esac if [ "$DUAL" = true ] ; then echo "Dual Sniffer Verifier Enabled" tunerboot1="/etccombo/ndsdualboot"$tuner1".btl" tunerboot2="/etccombo/ndsdualboot"$tuner2".btl" else if [ "$NDS" = true ] ; then echo "Sniffer Verifier Enabled" tunerboot1="/etccombo/ndsboot"$tuner1".btl" tunerboot2="/etccombo/ndsboot"$tuner2".btl" else echo "Multi-Verifier" tunerboot1="/etccombo/boot"$tuner1".btl" tunerboot2="/etccombo/boot"$tuner2".btl" fi fi case $asicversion in 0|1) echo "Not Installing oslink module." irmicrofile='/sbin/irmicro.hex' ;; 2|3) echo "Installing oslink module (tuner $tuner1)" irmicrofile='/sbin/irbmicro.hex' insmod /lib/modules/oslink.o cat $tunerboot1 > /dev/oslink ;; 4) echo "Installing both oslink (tuners $tuner1:$tuner2)" irmicrofile='/sbin/irbmicro.hex' insmod /lib/modules/oslink.o cat $tunerboot1 > /dev/oslink cat $tunerboot2 > /dev/oslink2 ;; esac fi echo "Loading fan ..." insmod /lib/modules/fan.o echo "Loading therm ..." insmod /lib/modules/therm.o echo "Loading pxmpegdecode ..." insmod /lib/modules/pxmpegdecode.o sTVStandard=$TV_STD echo "PALmod: Setting Oz Channel Frequencies" insmod -f /lib/modules/ukchan-2.5.5.o if [ $videoconfig = 7 ]; then echo "Loading scartmux ..." insmod /lib/modules/scartmux.o fi echo "Splash the screen..." osdwriter /tvbin/PromScreen2Version7.$TV_STD.cs22 echo "Update IR microcode using $irmicrofile" irprog -f $irmicrofile # Figure out the system serial number. (On combo box, # this is called the TiVo Service ID.) SysSerial=`crypto -gsn` if [ $? -ne 0 ]; then SysSerial=""; fi if [ -z $SysSerial ]; then SysSerial=`driveid /dev/hda`; fi if [ -z $SysSerial ]; then SysSerial=000000000000000; fi export SerialNumber=$SysSerial export HDA_ID=`/bin/driveid /dev/hda` export HDB_ID=`/bin/driveid /dev/hdb` # On combo box, determine the IRD Serial Number (which is # dependent on the exported SerialNumber environment variable). IrdSerial=`irdSerialNumber` export IrdSerialNumber=$IrdSerial # # Export the prom version information # export PROMVERSION=`getprom -version` # ??? Does this really add value? echo "Starting update ..." /sbin/update export DEBUG_BOARD=false me=`getprom -hostname` ipaddr=`getprom -ipaddr` mac=`getprom -macaddr` # # Look up /proc/ioports for TCD8390 (should be first string). If present, # assume we have a debug board. There is probably an easier way to do this, # but... # echo "Look for debug board ..." tnforce=false xxx=`cat /proc/ioports` set -- $xxx shift 2 if [ "$1" == TCD8390 ] ; then tnforce=true fi set -- if /sbin/ifconfig eth0 hw ether $mac $ipaddr || [ "$tnforce" = true ] ; then PATH=/bin:/sbin:/tvbin:/devbin export PATH echo "Starting network ..." gw=`getprom -gateway` if [ ! $gw = 0.0.0.0 ]; then route add -net 192.168.0.0 gw $gw netmask 255.255.0.0 fi export TMK_DEBUGGER=sleep export DEBUG_BOARD=true echo "Starting Telnet Listener..." if [ -x /bin/bash ] ; then tnlited 23 /bin/bash -login & else export TIVOSH_POOLSIZE=800000 tnlited 23 /tvbin/tivosh -login & fi echo "Starting /proc Listener..." procd # if [ -x /sbin/thttpd ] # then # echo "Starting http daemon..." # thttpd # ifconfig lo up # fi fi echo "Setting TCP keepalive parameters..." if [ -e /proc/sys/net/ipv4/tcp_keepalive_time ]; then echo 60 > /proc/sys/net/ipv4/tcp_keepalive_time fi if [ -e /proc/sys/net/ipv4/tcp_keepalive_probes ]; then echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes fi if [ "$runsyslog" = false ]; then echo "No logging daemons started..." else echo "Starting logging daemons..." rm -f /var/run/syslogd.pid /var/run/klogd.pid syslogd -p /var/dev/log -m 10000 klogd fi echo "Check for PROM update ..." if [ "$updateprom" = true ]; then if [ -e /prom/TiVoProm.bin ]; then osdwriter /tvbin/InstallingSoftware.$TV_STD.cs22 getprom -Update /prom/TiVoProm.bin echo "Sleep...waiting for reboot" osdwriter /tvbin/PromScreen2Version7.$TV_STD.cs22 sleep 1000000 restart fi echo "Can't find PROM image" fi echo "Loading mixaud ..." insmod /lib/modules/mixaud.o echo "Updating system clock UID=$UID" settime -rtc # If the clock is set to before 1970, ntpdate won't work. So we will # bump it up closer. The factory default seems to be 1910. year=`date +%Y` if [ $year -lt 1998 ] ; then settime 199811241010 settime -rtc fi # # Log into the moderated log any emergency cleanup deletions we # did. We need the TCD_ID, TIME and CALL_ID for this # if [ -e /var/persist/lastCallId ] ; then lastCallId=`cat /var/persist/lastCallId` else lastCallId="UNKNOWN" fi now=`date '+%s'` if [ $old_log_cleanup -ne 0 ]; then echo "emergency_cleanup TCD_ID=$SerialNumber TIME=$now CALL_ID=$lastCallId FILE=/var/log/O" >> /var/log/svclog fi for logf in $too_big_logs ; do echo "emergency_cleanup TCD_ID=$SerialNumber TIME=$now CALL_ID=$lastCallId FILE=$logf" >> /var/log/svclog done # Add second disk if there and uninitialized. No, we didn't take this out... echo "Checking for additional disk..." mfsadd if [ $do_mfs_cleanup -eq 1 ] ; then echo "Initiating MFS cleanup" /tvbin/fsfix -nokill -splash -uncollide -rehash -salvage -reboot fi # Start the EventSwitcher and MfsDaemon echo "Starting EventSwitcher..." switcherstart -m if [ $do_mfs_assert -eq 1 ] ; then echo "Rebooting to perform MFS and database check" /tvbin/mfsassert -please /tvbin/reboot fi # Start the fan control process. echo "Start fan control..." fancontrol & # Let him get started ?? sleep 1 # Run the Phase 2 (MFS is up) scripts runme phase2 # Check whether we should enter diagnostics # The authserial program detects the presence of a diagnostics test fixture. if [ ! -x /tvbin/authserial -o \ ! -x /tvbin/genkey -o \ ! -r /tvlib/misc/diagkey.pub ] ; then echo "Essential diagnostic file missing" reboot fi /tvbin/genkey 128 1 > /var/tmp/challenge.dat dodiag=false if [ "$runfactorydiag" = true ] ; then dodiag=true if [ $asicversion -gt 1 ] ; then # this is combo: # the "runfactorydiag" bootparam indicates that we are in the factory # with a brand new disk. Don't quit until we've established link # with diag station while ! /tvbin/authserial -authslave /tvlib/misc/diagkey.pub /var/tmp/challenge.dat ; do echo Diagnostics station not found, trying again sleep 1 done else # this is standalone, so we will just enter diagnostics echo "Standalone diagnostics" fi else if /tvbin/authserial -authslave /tvlib/misc/diagkey.pub /var/tmp/challenge.dat ; then echo Diagnostics station present and authenticated dodiag=true fi fi rm -f /var/tmp/challenge.dat # Run factory diagnostics? if [ "$dodiag" = true ] ; then if [ ! -x /tvbin/factorydiag ] ; then echo "No factorydiag TCL script!" else echo Entering diagnostics... if /tvbin/factorydiag ; then echo "Diagnostics passed" else echo "Error running factory diagnostics" reboot fi fi fi # Run the final test? if [ "$runfinaltest" = true ] ; then if [ -x /var/diag/finaltest ] ; then if /tvbin/crypto -vfs /var/diag/finaltest.sig /var/diag/finaltest /tvlib/misc/service-v3-s.pub ; then /var/diag/finaltest else echo "/var/diag/finaltest failed signature check." reboot fi elif [ -x /diag/finaltest ] ; then /diag/finaltest else echo "Final test not found!" fi fi # see if we need to check the battery if [ -f /var/log/battery-check-needed ] ; then if [ -x /var/diag/batterycheck ] ; then if /tvbin/crypto -vfs /var/diag/batterycheck.sig /var/diag/batterycheck /tvlib/misc/service-v3-s.pub ; then /var/diag/batterycheck else echo "/var/diag/batterycheck failed signature check." reboot fi elif [ -x /diag/batterycheck ] ; then /diag/batterycheck else echo "Battery check not found!" fi fi # combo diagnostics testmaster starts here if [ "$testmaster" = true ]; then if [ -f /etc/rc.d/rc.sysinit.diag ]; then echo "Starting Diagnostic Test Master" source /etc/rc.d/rc.sysinit.diag else echo "rc.sysinit.diag not found" fi fi if [ "$runwriteback" = true ]; then /diag/writeback /dev/hda11 256 -a2 & /diag/writeback /dev/hdb3 256 -a2 & while true; do sleep 1000; done fi if [ "$rundriverstress" = true ]; then if [ -x /diag/SimpleStress ]; then echo "Running SimpleStress" /diag/SimpleStress echo "SimpleStress exited" reboot fi fi # System Statistics to "messages" log file. syslog -t Stats "== System startup resource statistics ==" syslog -t Stats "++ System build version numbers ++" syslog -t Stats -f /etc/build-version getprom -version | syslog -t Stats IRvers=`irtest -t /dev/ttyS0 -V` syslog -t Stats "IR version $IRvers" syslog -t Stats "System Serial Number: $SysSerial" syslog -t Stats -f /proc/version syslog -t Stats "++ Memory usage ++" syslog -t Stats -f /proc/meminfo syslog -t Stats "++ CPU info ++" syslog -t Stats -f /proc/cpuinfo syslog -t Stats "++ Module info ++" syslog -t Stats -f /proc/modules syslog -t Stats "++ Device info ++" syslog -t Stats -f /proc/devices syslog -t Stats "++ Network device info ++" syslog -t Stats -f /proc/net/dev # Database conversions must happen before myworld, mcp, etc. are started. if [ "$handcraft" != true ]; then echo "Checking for database conversions..." convert-db fi if [ "$upgradesoftware" = false ]; then echo "Not upgrading software" else # TODO... Find another way to do this... tivosh /etc/rc.d/finishInstall.tcl export -n EMERGENCY_REINSTALL fi # Run the Phase 3 (MyWorld is starting) scripts runme phase3 cd /var/tmp # Launch MyWorld and other services (apg, mcp, tcphonehome, dbgc) by telling # the eventswitcher to launch it (via "switcherstart -l"). if [ "$handcraft" = true ]; then echo "Running without services." else echo "Starting Services." switcherstart -l fi if [ "$audiostress" = true ]; then echo "Starting audio stress" if [ -x /devbin/audiostress ]; then audiostress & else echo "Could not find audio stress prog" fi fi if [ "$maintuner" = "1" ]; then echo "Starting camtest for dual verifier mode" camtest & else maintuner=0 fi # Run the Phase 4 (background tasks have been started) scripts runme phase4 if [ ! "$NDS" = "" ]; then echo "Sleeping before enabling NDS sniffer output" sleep 120 echo "Enabling NDS sniffer output" /tvbin/send5505 "sniff 1" fi if [ ! "$BERR" = "" ]; then echo "Sleeping before enabling Tuner BERR Test" sleep 60 echo "Enabling Tuner BERR Test" /tvbin/send5505 "wr299 28 40" /tvbin/send5505 -i1 "wr299 28 40" fi if [ ! "$vmstat" = "" ]; then echo "Starting memory statistic gathering" vmstat 10 & fi #### START HACKS #### echo 1 > /proc/sys/net/ipv4/ip_bootp_agent if [ -f /etc/rc.d/rc.net ] then echo "Configuring network..." source /etc/rc.d/rc.net ifconfig lo up fi if [ -f /etc/rc.d/rc.net.${netcard} ] then echo "Configuring network...for ${netcard}" source /etc/rc.d/rc.net.${netcard} ifconfig lo up fi export hackpartition=/dev/hda7 export rootpartition=/dev/hda4 e2fsck -p $hackpartition echo "Cleanup $hackpartition pass 1" if e2fsck -p $hackpartition; then echo "$hackpartition is clean after pass 1" else if e2fsck -p $hackpartition; then echo "$hackpartition is clean after pass 2" else echo "Can't clean $hackpartition - rebuilding" mke2fs -c $hackpartition echo "Mounting /hack to rebuild it" mount -t ext2 -n $hackpartition /hack cd /hack gzip -cd /hack.tar.gz | cpio -H tar -i cd / umount -n /hack fi fi mount -t ext2 -n $hackpartition /hack /hack/bin/set_UK_oztivo.tcl startppponserial() { echo "Trying PPP over serial" mount -o remount,rw / rm /sbin/route ln -s /sbin/route.tivo /sbin/route /etc/rc.d/rc.ppp & sleep 5 rm /sbin/route ln -s /sbin/route.fake /sbin/route # cat /proc/net/dev |grep ppp0 # if [ "$?" == "0" ] # then # echo Exporting DYNAMIC_NET_DEV as ppp0 # export DYNAMIC_NET_DEV=ppp0 # fi mount -o remount,ro / } grep -q eth0 /proc/net/dev if [ $? == "0" ] ; then NETCARDIP=`ifconfig eth0|grep "inet addr" |cut -d: -f2|cut -d' ' -f1` if [ $NETCARDIP == "0.0.0.0" ] then echo "$netcard driver loaded but no DHCP server found" sleep 20 kill -n 15 `cat /var/run/dhclient.pid` ifconfig eth0 inet down rm /var/run/dhclient.pid unset DYNAMIC_NET_DEV startppponserial else echo IP for $netcard is $NETCARDIP fi else echo "No Network Card Present" startppponserial fi /sbin/tnlited 23 /bin/bash -login & [ ! -f /etc/rc.d/rc.sysinit.author ] || /etc/rc.d/rc.sysinit.author echo "rc.sysinit is complete"