]> Zhao Yanbai Git Server - minix.git/commitdiff
base system hooks for pkgsrc drivers
authorBen Gras <ben@minix3.org>
Thu, 13 Oct 2011 12:27:30 +0000 (12:27 +0000)
committerBen Gras <ben@minix3.org>
Wed, 16 Nov 2011 15:18:21 +0000 (16:18 +0100)
. rc script and service know to look in /usr/pkg/.. for
  extra binaries and conf files
. service split into parsing config and doing RS request
  so that a new utility (printconfig) can just print the
  config in machine-parseable format for netconf integration
. converted all base system eth drivers/netconf

32 files changed:
commands/netconf/netconf.sh
commands/service/Makefile
commands/service/config.h [new file with mode: 0644]
commands/service/parse.c [new file with mode: 0644]
commands/service/parse.h [new file with mode: 0644]
commands/service/print.c [new file with mode: 0644]
commands/service/proto.h [new file with mode: 0644]
commands/service/service.c
commands/service/util.c [new file with mode: 0644]
common/include/minix/minlib.h
drivers/atl2/Makefile
drivers/atl2/atl2.conf [new file with mode: 0644]
drivers/dec21140A/Makefile
drivers/dec21140A/dec21140A.conf [new file with mode: 0644]
drivers/e1000/Makefile
drivers/e1000/e1000.conf [new file with mode: 0644]
drivers/fxp/Makefile
drivers/fxp/fxp.conf [new file with mode: 0644]
drivers/lance/Makefile
drivers/lance/lance.conf [new file with mode: 0644]
drivers/rtl8139/Makefile
drivers/rtl8139/rtl8139.conf [new file with mode: 0644]
drivers/rtl8169/Makefile
drivers/rtl8169/rtl8169.conf [new file with mode: 0644]
etc/Makefile
etc/minix.rc.conf [new file with mode: 0644]
etc/mtree/minix.tree
etc/rc.conf
etc/system.conf
etc/usr/rc
include/paths.h
nbsd_include/minix/paths.h

index 8d29b31f11c9c6a047d4e63ff1970f5b59075df0..ca51df4a5955e6b678e477cbe7bc589bc7f5ad4f 100644 (file)
@@ -5,12 +5,17 @@
 # Changes:
 #                                              
 
+# Get system config
+. /etc/rc.conf
+
 LOCALRC=/usr/etc/rc.local
 INETCONF=/etc/inet.conf
 RCNET=/etc/rc.net
 HOSTS=/etc/hosts
 HOSTNAME=/etc/hostname.file
 USRKBFILE=/.usrkb
+LSPCI=/tmp/lspci.$$
+DEVICES=/tmp/devices.$$
 
 step1=""
 step2=""
@@ -81,7 +86,7 @@ card()
        shift 2
        while [ $# -gt 0 ]
        do 
-               lspci | grep > /dev/null "^$1" && card_avail=1
+               cat $LSPCI | grep > /dev/null "^$1" && card_avail=1
                shift
        done
        if [ $card_avail -gt 0 ]
@@ -94,29 +99,23 @@ card()
        printf "%2d. %s %s\n" "$card_number" "$card_mark" "$card_name"
 }
 
+first_pcicard=4
+
 cards()
 {
     card 0 "No Ethernet card (no networking)"
-    card 1 "Intel Pro/100" "8086:103D" "8086:1064" "8086:1229" "8086:2449" \
-           "8086:1031" "8086:1032"
-    card 2 "3Com 501 or 3Com 509 based card"
-    card 3 "Realtek 8139 based card (also emulated by KVM)"            \
-           "10EC:8139" "02AC:1012" "1065:8139" "1113:1211" "1186:1300" \
-           "1186:1340" "11DB:1234" "1259:A117" "1259:A11E" "126C:1211" \
-           "13D1:AB06" "1432:9130" "14EA:AB06" "14EA:AB07" "1500:1360" \
-           "1743:8139" "4033:1360"
-    card 4 "Realtek 8169 based card"   \
-           "10EC:8129" "10EC:8167" "10EC:8169" "1186:4300" "1259:C107" \
-           "1385:8169" "16EC:0116" "1737:1032" "10EC:8168"
-    card 5 "Realtek 8029 based card (also emulated by Qemu)" "10EC:8029"
-    card 6 "NE2000, 3com 503 or WD based card (also emulated by Bochs)"
-    card 7 "AMD LANCE (also emulated by VMWare and VirtualBox)" "1022:2000"
-    card 8 "Intel PRO/1000 Gigabit"                                   \
-           "8086:100E" "8086:107C" "8086:10CD" "8086:10D3" "8086:10DE"
-       
-    card 9 "Attansic/Atheros L2 FastEthernet" "1969:2048"
-    card 10 "DEC Tulip 21140A in VirtualPC" "1011:0009"
-    card 11 "Different Ethernet card (no networking)"
+    card 1 "3Com 501 or 3Com 509 based card"
+    card 2 "Realtek 8029 based card (also emulated by Qemu)" "10EC:8029"
+    card 3 "NE2000, 3com 503 or WD based card (also emulated by Bochs)"
+    n=$first_pcicard
+    for pcicard in $pci_list
+    do var=\$pci_descr$pcicard; descr="`eval echo $var`"
+       var=\$pci_pcilist$pcicard; pcilist="`eval echo $var`"
+       card $n "$descr" $pcilist
+       n="`expr $n + 1`"
+    done
+
+    card $first_after_pci "Different Ethernet card (no networking)"
 }
 
 warn()
@@ -124,6 +123,35 @@ warn()
     echo -e "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b ! $1"
 }
 
+config_pci_cards() {
+       rm -f $DEVICES
+
+       n=0
+
+       # Collect configs from network devices
+       for dir in $SYSTEM_CONF_DIRS
+       do      for f in $dir/$SYSTEM_CONF_SUBDIR/*
+               do      if [ -f $f ]
+                       then    printconfig $f | grep 'type net.*pci device'
+                       fi
+               done
+       done >$DEVICES
+       while read devline
+       do      pcilist="`echo $devline | sed 's/.*pci device //' | sed 's/,.*//'`"
+               descr="`echo $devline | sed 's/.*,descr //' | sed 's/,.*//'`"
+               label="`echo $devline | sed 's/.*service //' | sed 's/,.*//'`"
+               pci_list="$pci_list $n"
+               eval "pci_pcilist$n=\"$pcilist\""
+               eval "pci_descr$n=\"$descr\""
+               eval "pci_label$n=\"$label\""
+               n="`expr $n + 1`"
+       done <$DEVICES
+
+       first_after_pci=`expr $first_pcicard + $n`
+
+       rm -f $DEVICES
+}
+
 do_step1()
 {
     eth_default=0
@@ -146,26 +174,28 @@ do_step1()
 
 drv_params()
 {
+       # If this is a known pci device, we only have to set
+       # the driver.
+       if [ $1 -ge $first_pcicard -a $1 -lt $first_after_pci ]
+       then    pcicard="`expr $1 - $first_pcicard`"
+               var=\$pci_label$pcicard; driver="`eval echo $var`"
+               return
+       fi
+
+      # Other possibilities.
       case "$1" in
         0) driver=psip0;    ;;    
-       1) driver=fxp;      ;;
-       2) driver=dpeth;    driverargs="#dpeth_arg='DPETH0=port:irq:memory'";
+       1) driver=dpeth;    driverargs="#dpeth_arg='DPETH0=port:irq:memory'";
           test "$v" = 1 && echo ""
            test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration."
                ;;
-       4) driver=rtl8169;  ;;
-       3) driver=rtl8139;  ;;
-       5) driver=dp8390;   driverargs="dp8390_arg='DPETH0=pci'";       ;;
-       6) driver=dp8390;   driverargs="dp8390_arg='DPETH0=240:9'"; 
+       2) driver=dp8390;   driverargs="dp8390_arg='DPETH0=pci'";       ;;
+       3) driver=dp8390;   driverargs="dp8390_arg='DPETH0=240:9'"; 
           test "$v" = 1 && echo ""
            test "$v" = 1 && echo "Note: After installing, edit $LOCALRC to the right configuration."
            test "$v" = 1 && echo " chose option 4, the defaults for emulation by Bochs have been set."
                ;;
-        7) driver="lance"; ;;    
-       8) driver="e1000"; ;;
-        9) driver="atl2";   ;;
-        10) driver="dec21140A"; ;;    
-        11) driver="psip0"; ;;    
+        $first_after_pci) driver="psip0"; ;;    
         *) warn "choose a number"
       esac
 }
@@ -253,6 +283,9 @@ do_step2()
     fi
 }
 
+# Find pci cards we know about
+config_pci_cards
+
 # Parse options
 while getopts ":qe:p:aH:i:n:g:d:s:hc" arg; do
     case "$arg" in
@@ -279,6 +312,9 @@ while getopts ":qe:p:aH:i:n:g:d:s:hc" arg; do
     esac
 done
 
+# Run lspci once to a temp file
+lspci >$LSPCI || exit
+
 # Verify parameter count
 if [ "$dhcp" != "yes" ] ; then
     if [ $manual_opts -gt 0 ] ; then
@@ -329,6 +365,9 @@ else
 fi
 echo "$driverargs" > $LOCALRC
 
+# Remove temporary lspci output
+rm -f $LSPCI
+
 if [ -n "$manual" ]
     then
     # Backup config file if it exists and we're not running from CD
index 3669beeb8661eaaff7799603f4ee2ce80082395a..77557867afdaf1fa4f711ad3881068777ce92d30 100644 (file)
@@ -1,8 +1,11 @@
 # Makefile for service
-PROG=  service
+PROGS= service printconfig
+SRCS.service=service.c parse.c util.c
+SRCS.printconfig=print.c parse.c util.c
 
 BINDIR= /bin
-MAN=
+MAN.service=
+MAN.printconfig=
 
 CPPFLAGS+=     -I${MINIXSRCDIR}
 
diff --git a/commands/service/config.h b/commands/service/config.h
new file mode 100644 (file)
index 0000000..25aa270
--- /dev/null
@@ -0,0 +1,7 @@
+
+struct rs_config {
+       struct rs_start rs_start;       /* RS parameters */
+       const char *descr;              /* human-readable description, if specified */
+       char *type;                     /* service type, if specified */
+};
+
diff --git a/commands/service/parse.c b/commands/service/parse.c
new file mode 100644 (file)
index 0000000..20096e0
--- /dev/null
@@ -0,0 +1,1137 @@
+
+#include <stdarg.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <pwd.h>
+#include <err.h>
+#include <unistd.h>
+#include <limits.h>
+#include <lib.h>
+#include <minix/config.h>
+#include <minix/com.h>
+#include <minix/const.h>
+#include <minix/type.h>
+#include <minix/ipc.h>
+#include <minix/rs.h>
+#include <minix/syslib.h>
+#include <minix/bitmap.h>
+#include <paths.h>
+#include <minix/sef.h>
+#include <minix/dmap.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <configfile.h>
+
+#include <machine/archtypes.h>
+#include <timers.h>
+#include "kernel/proc.h"
+
+#include "config.h"
+#include "proto.h"
+
+PRIVATE int class_recurs;       /* Nesting level of class statements */
+#define MAX_CLASS_RECURS        100     /* Max nesting level for classes */
+
+#include "parse.h"
+
+#define SERVICE_LOGIN   "service"       /* passwd file entry for services */
+
+FORWARD void do_service(config_t *cpe, config_t *config, struct rs_config *);
+
+PRIVATE void do_class(config_t *cpe, config_t *config, struct rs_config *rs_config)
+{
+       config_t *cp, *cp1;
+
+       if (class_recurs > MAX_CLASS_RECURS)
+       {
+               fatal(
+               "do_class: nesting level too high for class '%s' at %s:%d",
+                       cpe->word, cpe->file, cpe->line);
+       }
+       class_recurs++;
+
+       /* Process classes */
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_class: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_uid: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               /* Find entry for the class */
+               for (cp= config; cp; cp= cp->next)
+               {
+                       if (!(cp->flags & CFG_SUBLIST))
+                       {
+                               fatal("do_class: expected list at %s:%d",
+                                       cp->file, cp->line);
+                       }
+                       cp1= cp->list;
+                       if ((cp1->flags & CFG_STRING) ||
+                               (cp1->flags & CFG_SUBLIST))
+                       {
+                               fatal("do_class: expected word at %s:%d",
+                                       cp1->file, cp1->line);
+                       }
+
+                       /* At this place we expect the word KW_SERVICE */
+                       if (strcmp(cp1->word, KW_SERVICE) != 0)
+                               fatal("do_class: exected word '%S' at %s:%d",
+                                       KW_SERVICE, cp1->file, cp1->line);
+
+                       cp1= cp1->next;
+                       if ((cp1->flags & CFG_STRING) ||
+                               (cp1->flags & CFG_SUBLIST))
+                       {
+                               fatal("do_class: expected word at %s:%d",
+                                       cp1->file, cp1->line);
+                       }
+
+                       /* At this place we expect the name of the service */
+                       if (strcmp(cp1->word, cpe->word) == 0)
+                               break;
+               }
+               if (cp == NULL)
+               {
+                       fatal(
+                       "do_class: no entry found for class '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               }
+               do_service(cp1->next, config, rs_config);
+       }
+
+       class_recurs--;
+}
+
+PRIVATE void do_uid(config_t *cpe, struct rs_start *rs_start)
+{
+       uid_t uid;
+       struct passwd *pw;
+       char *check;
+
+       /* Process a uid */
+       if (cpe->next != NULL)
+       {
+               fatal("do_uid: just one uid/login expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_uid: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_uid: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       pw= getpwnam(cpe->word);
+       if (pw != NULL)
+               uid= pw->pw_uid;
+       else
+       {
+               uid= strtol(cpe->word, &check, 0);
+               if (check[0] != '\0')
+               {
+                       fatal("do_uid: bad uid/login '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               }
+       }
+
+       rs_start->rss_uid= uid;
+}
+
+PRIVATE void do_sigmgr(config_t *cpe, struct rs_start *rs_start)
+{
+       endpoint_t sigmgr_ep;
+       int r;
+
+       /* Process a signal manager value */
+       if (cpe->next != NULL)
+       {
+               fatal("do_sigmgr: just one sigmgr value expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_sigmgr: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_sigmgr: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+
+       if(!strcmp(cpe->word, "SELF")) {
+               sigmgr_ep = SELF;
+       }
+       else {
+               if((r = minix_rs_lookup(cpe->word, &sigmgr_ep))) {
+                       fatal("do_sigmgr: unknown sigmgr %s at %s:%d",
+                       cpe->word, cpe->file, cpe->line);
+               }
+       }
+
+       rs_start->rss_sigmgr= sigmgr_ep;
+}
+
+PRIVATE void do_type(config_t *cpe, struct rs_config *rs_config)
+{
+       if (cpe->next != NULL)
+       {
+               fatal("do_type: just one type value expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_type: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if ((cpe->flags & CFG_STRING))
+       {
+               fatal("do_type: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+
+       if(rs_config->type)
+               fatal("do_type: another type at %s:%d",
+                       cpe->file, cpe->line);
+
+       if(!strcmp(cpe->word, KW_NET))
+               rs_config->type = KW_NET;
+       else
+               fatal("do_type: odd type at %s:%d",
+                       cpe->file, cpe->line);
+}
+
+PRIVATE void do_descr(config_t *cpe, struct rs_config *rs_config)
+{
+       if (cpe->next != NULL)
+       {
+               fatal("do_descr: just one description expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_descr: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (!(cpe->flags & CFG_STRING))
+       {
+               fatal("do_descr: expected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+
+       if(rs_config->descr)
+               fatal("do_descr: another descr at %s:%d",
+                       cpe->file, cpe->line);
+       rs_config->descr = cpe->word;
+}
+
+PRIVATE void do_scheduler(config_t *cpe, struct rs_start *rs_start)
+{
+       endpoint_t scheduler_ep;
+       int r;
+
+       /* Process a scheduler value */
+       if (cpe->next != NULL)
+       {
+               fatal("do_scheduler: just one scheduler value expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_scheduler: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_scheduler: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+
+       if(!strcmp(cpe->word, "KERNEL")) {
+               scheduler_ep = KERNEL;
+       }
+       else {
+               if((r = minix_rs_lookup(cpe->word, &scheduler_ep))) {
+                       fatal("do_scheduler: unknown scheduler %s at %s:%d",
+                       cpe->word, cpe->file, cpe->line);
+               }
+       }
+
+       rs_start->rss_scheduler= scheduler_ep;
+}
+
+PRIVATE void do_priority(config_t *cpe, struct rs_start *rs_start)
+{
+       int priority_val;
+       char *check;
+
+       /* Process a priority value */
+       if (cpe->next != NULL)
+       {
+               fatal("do_priority: just one priority value expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_priority: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_priority: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       priority_val= strtol(cpe->word, &check, 0);
+       if (check[0] != '\0')
+       {
+               fatal("do_priority: bad priority value '%s' at %s:%d",
+                       cpe->word, cpe->file, cpe->line);
+       }
+
+       if (priority_val < 0 || priority_val >= NR_SCHED_QUEUES)
+       {
+               fatal("do_priority: priority %d out of range at %s:%d",
+                       priority_val, cpe->file, cpe->line);
+       }
+       rs_start->rss_priority= priority_val;
+}
+
+PRIVATE void do_quantum(config_t *cpe, struct rs_start *rs_start)
+{
+       int quantum_val;
+       char *check;
+
+       /* Process a quantum value */
+       if (cpe->next != NULL)
+       {
+               fatal("do_quantum: just one quantum value expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_quantum: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_quantum: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       quantum_val= strtol(cpe->word, &check, 0);
+       if (check[0] != '\0')
+       {
+               fatal("do_quantum: bad quantum value '%s' at %s:%d",
+                       cpe->word, cpe->file, cpe->line);
+       }
+
+       if (quantum_val <= 0)
+       {
+               fatal("do_quantum: quantum %d out of range at %s:%d",
+                       quantum_val, cpe->file, cpe->line);
+       }
+       rs_start->rss_quantum= quantum_val;
+}
+
+PRIVATE void do_cpu(config_t *cpe, struct rs_start *rs_start)
+{
+       int cpu;
+       char *check;
+
+       /* Process a quantum value */
+       if (cpe->next != NULL)
+       {
+               fatal("do_cpu: just one value expected at %s:%d",
+                       cpe->file, cpe->line);
+       }       
+       
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_cpu: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_cpu: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       cpu= strtol(cpe->word, &check, 0);
+       if (check[0] != '\0')
+       {
+               fatal("do_cpu: bad value '%s' at %s:%d",
+                       cpe->word, cpe->file, cpe->line);
+       }
+
+       if (cpu < 0)
+       {
+               fatal("do_cpu: %d out of range at %s:%d",
+                       cpu, cpe->file, cpe->line);
+       }
+       rs_start->rss_cpu= cpu;
+}
+
+PRIVATE void do_irq(config_t *cpe, struct rs_start *rs_start)
+{
+       int irq;
+       int first;
+       char *check;
+
+       /* Process a list of IRQs */
+       first = TRUE;
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_irq: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_irq: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               /* No IRQ allowed? (default) */
+               if(!strcmp(cpe->word, KW_NONE)) {
+                       if(!first || cpe->next) {
+                               fatal("do_irq: %s keyword not allowed in list",
+                               KW_NONE);
+                       }
+                       break;
+               }
+
+               /* All IRQs are allowed? */
+               if(!strcmp(cpe->word, KW_ALL)) {
+                       if(!first || cpe->next) {
+                               fatal("do_irq: %s keyword not allowed in list",
+                               KW_ALL);
+                       }
+                       rs_start->rss_nr_irq = RSS_IO_ALL;
+                       break;
+               }
+
+               /* Set single IRQs as specified in the configuration. */
+               irq= strtoul(cpe->word, &check, 0);
+               if (check[0] != '\0')
+               {
+                       fatal("do_irq: bad irq '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               }
+               if (rs_start->rss_nr_irq >= RSS_NR_IRQ)
+                       fatal("do_irq: too many IRQs (max %d)", RSS_NR_IRQ);
+               rs_start->rss_irq[rs_start->rss_nr_irq]= irq;
+               rs_start->rss_nr_irq++;
+               first = FALSE;
+       }
+}
+
+PRIVATE void do_io(config_t *cpe, struct rs_start *rs_start)
+{
+       unsigned base, len;
+       int first;
+       char *check;
+
+       /* Process a list of I/O ranges */
+       first = TRUE;
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_io: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_io: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               /* No range allowed? (default) */
+               if(!strcmp(cpe->word, KW_NONE)) {
+                       if(!first || cpe->next) {
+                               fatal("do_io: %s keyword not allowed in list",
+                               KW_NONE);
+                       }
+                       break;
+               }
+
+               /* All ranges are allowed? */
+               if(!strcmp(cpe->word, KW_ALL)) {
+                       if(!first || cpe->next) {
+                               fatal("do_io: %s keyword not allowed in list",
+                               KW_ALL);
+                       }
+                       rs_start->rss_nr_io = RSS_IO_ALL;
+                       break;
+               }
+
+               /* Set single ranges as specified in the configuration. */
+               base= strtoul(cpe->word, &check, 0x10);
+               len= 1;
+               if (check[0] == ':')
+               {
+                       len= strtoul(check+1, &check, 0x10);
+               }
+               if (check[0] != '\0')
+               {
+                       fatal("do_io: bad I/O range '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               }
+
+               if (rs_start->rss_nr_io >= RSS_NR_IO)
+                       fatal("do_io: too many I/O ranges (max %d)", RSS_NR_IO);
+               rs_start->rss_io[rs_start->rss_nr_io].base= base;
+               rs_start->rss_io[rs_start->rss_nr_io].len= len;
+               rs_start->rss_nr_io++;
+               first = FALSE;
+       }
+}
+
+PRIVATE void do_pci_device(config_t *cpe, struct rs_start *rs_start)
+{
+       u16_t vid, did;
+       char *check, *check2;
+
+       /* Process a list of PCI device IDs */
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_pci_device: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_pci_device: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               vid= strtoul(cpe->word, &check, 0x10);
+               if (check[0] == '/')
+                       did= strtoul(check+1, &check2, 0x10);
+               if (check[0] != '/' || check2[0] != '\0')
+               {
+                       fatal("do_pci_device: bad ID '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               }
+               if (rs_start->rss_nr_pci_id >= RS_NR_PCI_DEVICE)
+               {
+                       fatal("do_pci_device: too many device IDs (max %d)",
+                               RS_NR_PCI_DEVICE);
+               }
+               rs_start->rss_pci_id[rs_start->rss_nr_pci_id].vid= vid;
+               rs_start->rss_pci_id[rs_start->rss_nr_pci_id].did= did;
+               rs_start->rss_nr_pci_id++;
+       }
+}
+
+PRIVATE void do_pci_class(config_t *cpe, struct rs_start *rs_start)
+{
+       u8_t baseclass, subclass, interface;
+       u32_t class_id, mask;
+       char *check;
+
+       /* Process a list of PCI device class IDs */
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_pci_device: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_pci_device: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               baseclass= strtoul(cpe->word, &check, 0x10);
+               subclass= 0;
+               interface= 0;
+               mask= 0xff0000;
+               if (check[0] == '/')
+               {
+                       subclass= strtoul(check+1, &check, 0x10);
+                       mask= 0xffff00;
+                       if (check[0] == '/')
+                       {
+                               interface= strtoul(check+1, &check, 0x10);
+                               mask= 0xffffff;
+                       }
+               }
+
+               if (check[0] != '\0')
+               {
+                       fatal("do_pci_class: bad class ID '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               }
+               class_id= (baseclass << 16) | (subclass << 8) | interface;
+               if (rs_start->rss_nr_pci_class >= RS_NR_PCI_CLASS)
+               {
+                       fatal("do_pci_class: too many class IDs (max %d)",
+                               RS_NR_PCI_CLASS);
+               }
+               rs_start->rss_pci_class[rs_start->rss_nr_pci_class].pciclass=
+                       class_id;
+               rs_start->rss_pci_class[rs_start->rss_nr_pci_class].mask= mask;
+               rs_start->rss_nr_pci_class++;
+       }
+}
+
+PRIVATE void do_pci(config_t *cpe, struct rs_start *rs_start)
+{
+       if (cpe == NULL)
+               return; /* Empty PCI statement */
+
+       if (cpe->flags & CFG_SUBLIST)
+       {
+               fatal("do_pci: unexpected sublist at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->flags & CFG_STRING)
+       {
+               fatal("do_pci: unexpected string at %s:%d",
+                       cpe->file, cpe->line);
+       }
+
+       if (strcmp(cpe->word, KW_DEVICE) == 0)
+       {
+               do_pci_device(cpe->next, rs_start);
+               return;
+       }
+       if (strcmp(cpe->word, KW_CLASS) == 0)
+       {
+               do_pci_class(cpe->next, rs_start);
+               return;
+       }
+       fatal("do_pci: unexpected word '%s' at %s:%d",
+               cpe->word, cpe->file, cpe->line);
+}
+
+PRIVATE void do_ipc(config_t *cpe, struct rs_start *rs_start)
+{
+       char *list;
+       const char *word;
+       char *word_all = RSS_IPC_ALL;
+       char *word_all_sys = RSS_IPC_ALL_SYS;
+       size_t listsize, wordlen;
+       int first;
+
+       list= NULL;
+       listsize= 1;
+       list= malloc(listsize);
+       if (list == NULL)
+               fatal("do_ipc: unable to malloc %d bytes", listsize);
+       list[0]= '\0';
+
+       /* Process a list of process names that are allowed to be
+        * contacted
+        */
+       first = TRUE;
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_ipc: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_ipc: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               word = cpe->word;
+
+               /* All (system) ipc targets are allowed? */
+               if(!strcmp(word, KW_ALL) || !strcmp(word, KW_ALL_SYS)) {
+                       if(!first || cpe->next) {
+                               fatal("do_ipc: %s keyword not allowed in list",
+                               word);
+                       }
+                       word = !strcmp(word, KW_ALL) ? word_all : word_all_sys;
+               }
+
+               wordlen= strlen(word);
+
+               listsize += 1 + wordlen;
+               list= realloc(list, listsize);
+               if (list == NULL)
+               {
+                       fatal("do_ipc: unable to realloc %d bytes",
+                               listsize);
+               }
+               strcat(list, " ");
+               strcat(list, word);
+               first = FALSE;
+       }
+#if 0
+       printf("do_ipc: got list '%s'\n", list);
+#endif
+
+       if (rs_start->rss_ipc)
+               fatal("do_ipc: req_ipc is set");
+        rs_start->rss_ipc = list+1;
+       rs_start->rss_ipclen= strlen(rs_start->rss_ipc);
+}
+
+
+struct
+{
+       char *label;
+       int call_nr;
+} vm_table[] =
+{
+       { "EXIT",               VM_EXIT },
+       { "FORK",               VM_FORK },
+       { "BRK",                VM_BRK },
+       { "EXEC_NEWMEM",        VM_EXEC_NEWMEM },
+       { "PUSH_SIG",           VM_PUSH_SIG },
+       { "WILLEXIT",           VM_WILLEXIT },
+       { "ADDDMA",             VM_ADDDMA },
+       { "DELDMA",             VM_DELDMA },
+       { "GETDMA",             VM_GETDMA },
+       { "REMAP",              VM_REMAP },
+       { "SHM_UNMAP",          VM_SHM_UNMAP },
+       { "GETPHYS",            VM_GETPHYS },
+       { "GETREF",             VM_GETREF },
+       { "RS_SET_PRIV",        VM_RS_SET_PRIV },
+       { "QUERY_EXIT",         VM_QUERY_EXIT },
+       { "WATCH_EXIT",         VM_WATCH_EXIT },
+       { "NOTIFY_SIG",         VM_NOTIFY_SIG },
+       { "INFO",               VM_INFO },
+       { "RS_UPDATE",          VM_RS_UPDATE },
+       { "RS_MEMCTL",          VM_RS_MEMCTL },
+       { NULL,                 0 },
+};
+
+PRIVATE void do_vm(config_t *cpe, struct rs_start *rs_start)
+{
+       int i, first;
+
+       first = TRUE;
+       for (; cpe; cpe = cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_vm: unexpected sublist at %s:%d",
+                             cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_vm: unexpected string at %s:%d",
+                             cpe->file, cpe->line);
+               }
+
+               /* Only basic calls allowed? (default). */
+               if(!strcmp(cpe->word, KW_BASIC)) {
+                       if(!first || cpe->next) {
+                               fatal("do_vm: %s keyword not allowed in list",
+                               KW_NONE);
+                       }
+                       break;
+               }
+
+               /* No calls allowed? */
+               if(!strcmp(cpe->word, KW_NONE)) {
+                       if(!first || cpe->next) {
+                               fatal("do_vm: %s keyword not allowed in list",
+                               KW_NONE);
+                       }
+                       rs_start->rss_flags &= ~RSS_VM_BASIC_CALLS;
+                       break;
+               }
+
+               /* All calls are allowed? */
+               if(!strcmp(cpe->word, KW_ALL)) {
+                       if(!first || cpe->next) {
+                               fatal("do_vm: %s keyword not allowed in list",
+                               KW_ALL);
+                       }
+                       for (i = 0; i < NR_VM_CALLS; i++)
+                               SET_BIT(rs_start->rss_vm, i);
+                       break;
+               }
+
+               /* Set single calls as specified in the configuration. */
+               for (i = 0; vm_table[i].label != NULL; i++)
+                       if (!strcmp(cpe->word, vm_table[i].label))
+                               break;
+               if (vm_table[i].label == NULL)
+                       fatal("do_vm: unknown call '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               SET_BIT(rs_start->rss_vm, vm_table[i].call_nr - VM_RQ_BASE);
+               first = FALSE;
+       }
+}
+
+struct
+{
+       char *label;
+       int call_nr;
+} system_tab[]=
+{
+       { "PRIVCTL",            SYS_PRIVCTL },
+       { "TRACE",              SYS_TRACE },
+       { "KILL",               SYS_KILL },
+       { "UMAP",               SYS_UMAP },
+       { "VIRCOPY",            SYS_VIRCOPY },
+       { "PHYSCOPY",           SYS_PHYSCOPY },
+       { "UMAP_REMOTE",        SYS_UMAP_REMOTE },
+       { "IRQCTL",             SYS_IRQCTL },
+       { "INT86",              SYS_INT86 },
+       { "DEVIO",              SYS_DEVIO },
+       { "SDEVIO",             SYS_SDEVIO },
+       { "VDEVIO",             SYS_VDEVIO },
+       { "ABORT",              SYS_ABORT },
+       { "IOPENABLE",          SYS_IOPENABLE },
+       { "READBIOS",           SYS_READBIOS },
+       { "STIME",              SYS_STIME },
+       { "VMCTL",              SYS_VMCTL },
+       { NULL,         0 }
+};
+
+PRIVATE void do_system(config_t *cpe, struct rs_start *rs_start)
+{
+       int i, first;
+
+       /* Process a list of 'system' calls that are allowed */
+       first = TRUE;
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_system: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_system: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               /* Only basic calls allowed? (default). */
+               if(!strcmp(cpe->word, KW_BASIC)) {
+                       if(!first || cpe->next) {
+                               fatal("do_system: %s keyword not allowed in list",
+                               KW_NONE);
+                       }
+                       break;
+               }
+
+               /* No calls allowed? */
+               if(!strcmp(cpe->word, KW_NONE)) {
+                       if(!first || cpe->next) {
+                               fatal("do_system: %s keyword not allowed in list",
+                               KW_NONE);
+                       }
+                       rs_start->rss_flags &= ~RSS_SYS_BASIC_CALLS;
+                       break;
+               }
+
+               /* All calls are allowed? */
+               if(!strcmp(cpe->word, KW_ALL)) {
+                       if(!first || cpe->next) {
+                               fatal("do_system: %s keyword not allowed in list",
+                               KW_ALL);
+                       }
+                       for (i = 0; i < NR_SYS_CALLS; i++)
+                               SET_BIT(rs_start->rss_system, i);
+                       break;
+               }
+
+               /* Set single calls as specified in the configuration. */
+               for (i = 0; system_tab[i].label != NULL; i++)
+                       if (!strcmp(cpe->word, system_tab[i].label))
+                               break;
+               if (system_tab[i].label == NULL)
+                       fatal("do_system: unknown call '%s' at %s:%d",
+                               cpe->word, cpe->file, cpe->line);
+               SET_BIT(rs_start->rss_system, system_tab[i].call_nr - KERNEL_CALL);
+               first = FALSE;
+       }
+}
+
+PRIVATE void do_control(config_t *cpe, struct rs_start *rs_start)
+{
+       int nr_control = 0;
+
+       /* Process a list of 'control' labels. */
+       for (; cpe; cpe= cpe->next)
+       {
+               if (cpe->flags & CFG_SUBLIST)
+               {
+                       fatal("do_control: unexpected sublist at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (cpe->flags & CFG_STRING)
+               {
+                       fatal("do_control: unexpected string at %s:%d",
+                               cpe->file, cpe->line);
+               }
+               if (nr_control >= RS_NR_CONTROL)
+               {
+                       fatal(
+                       "do_control: RS_NR_CONTROL is too small (%d needed)",
+                               nr_control+1);
+               }
+
+               rs_start->rss_control[nr_control].l_addr = (char*) cpe->word;
+               rs_start->rss_control[nr_control].l_len = strlen(cpe->word);
+               rs_start->rss_nr_control = ++nr_control;
+       }
+}
+
+PRIVATE void do_service(config_t *cpe, config_t *config, struct rs_config *rs_config)
+{
+       struct rs_start *rs_start = &rs_config->rs_start;
+       config_t *cp;
+
+       /* At this point we expect one sublist that contains the varios
+        * resource allocations
+        */
+       if (!(cpe->flags & CFG_SUBLIST))
+       {
+               fatal("do_service: expected list at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       if (cpe->next != NULL)
+       {
+               cpe= cpe->next;
+               fatal("do_service: expected end of list at %s:%d",
+                       cpe->file, cpe->line);
+       }
+       cpe= cpe->list;
+
+       /* Process the list */
+       for (cp= cpe; cp; cp= cp->next)
+       {
+               if (!(cp->flags & CFG_SUBLIST))
+               {
+                       fatal("do_service: expected list at %s:%d",
+                               cp->file, cp->line);
+               }
+               cpe= cp->list;
+               if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
+               {
+                       fatal("do_service: expected word at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               if (strcmp(cpe->word, KW_CLASS) == 0)
+               {
+                       do_class(cpe->next, config, rs_config);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_UID) == 0)
+               {
+                       do_uid(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_SIGMGR) == 0)
+               {
+                       do_sigmgr(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_TYPE) == 0)
+               {
+                       do_type(cpe->next, rs_config);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_DESCR) == 0)
+               {
+                       do_descr(cpe->next, rs_config);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_SCHEDULER) == 0)
+               {
+                       do_scheduler(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_PRIORITY) == 0)
+               {
+                       do_priority(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_QUANTUM) == 0)
+               {
+                       do_quantum(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_CPU) == 0)
+               {
+                       do_cpu(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_IRQ) == 0)
+               {
+                       do_irq(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_IO) == 0)
+               {
+                       do_io(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_PCI) == 0)
+               {
+                       do_pci(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_SYSTEM) == 0)
+               {
+                       do_system(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_IPC) == 0)
+               {
+                       do_ipc(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_VM) == 0)
+               {
+                       do_vm(cpe->next, rs_start);
+                       continue;
+               }
+               if (strcmp(cpe->word, KW_CONTROL) == 0)
+               {
+                       do_control(cpe->next, rs_start);
+                       continue;
+               }
+       }
+}
+
+PRIVATE const char *do_config(const char *label, char *filename, struct rs_config *rs_config)
+{
+       config_t *config, *cp, *cpe;
+       struct passwd *pw;
+       struct rs_start *rs_start = &rs_config->rs_start;
+
+       if(!(config= config_read(filename, 0, NULL)))
+               return NULL; /* config file read failed. */
+
+       /* Set clean rs_start defaults. */
+       memset(rs_config, 0, sizeof(*rs_config));
+       if(!(pw= getpwnam(SERVICE_LOGIN)))
+               fatal("no passwd file entry for '%s'", SERVICE_LOGIN);
+       rs_start->rss_uid= pw->pw_uid;
+       rs_start->rss_sigmgr= DSRV_SM;
+       rs_start->rss_scheduler= DSRV_SCH;
+       rs_start->rss_priority= DSRV_Q;
+       rs_start->rss_quantum= DSRV_QT;
+       rs_start->rss_cpu = DSRV_CPU;
+       rs_start->rss_flags = RSS_VM_BASIC_CALLS | RSS_SYS_BASIC_CALLS;
+
+       /* Find an entry for our service */
+       for (cp= config; cp; cp= cp->next)
+       {
+               if (!(cp->flags & CFG_SUBLIST))
+               {
+                       fatal("do_config: expected list at %s:%d",
+                               cp->file, cp->line);
+               }
+               cpe= cp->list;
+               if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
+               {
+                       fatal("do_config: expected word at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               /* At this place we expect the word KW_SERVICE */
+               if (strcmp(cpe->word, KW_SERVICE) != 0)
+                       fatal("do_config: exected word '%S' at %s:%d",
+                               KW_SERVICE, cpe->file, cpe->line);
+
+               cpe= cpe->next;
+               if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
+               {
+                       fatal("do_config: expected word at %s:%d",
+                               cpe->file, cpe->line);
+               }
+
+               /* At this place we expect the name of the service. */
+               if (!label || strcmp(cpe->word, label) == 0) {
+                       label = cpe->word;
+                       break;
+               }
+       }
+       if (cp == NULL)
+       {
+               fprintf(stderr, "service: service '%s' not found in '%s'\n",
+                       label, filename);
+               exit(1);
+       }
+
+       cpe= cpe->next;
+
+       do_service(cpe, config, rs_config);
+
+       {
+               char *default_ipc = RSS_IPC_ALL_SYS;
+               if(!rs_start->rss_ipc) {
+                     rs_start->rss_ipc= default_ipc;
+                     rs_start->rss_ipclen= strlen(default_ipc);
+               }
+       }
+
+       /* config file read ok. */
+       return label;
+}
+
+/* returns failure */
+PUBLIC const char *parse_config(char *progname, int custom_config, char *req_config,
+       struct rs_config *rs_config)
+{
+        char *specificconfig, *specific_pkg_config;
+       const char *l;
+
+       /* Config file specified? */
+        if(custom_config)
+          return do_config(progname, req_config, rs_config);
+
+       /* No specific config file. */
+        if(asprintf(&specificconfig, "%s/%s", _PATH_SYSTEM_CONF_DIR,
+              progname) < 0) {
+              errx(1, "no memory");
+        }
+
+        if(asprintf(&specific_pkg_config, "%s/%s", _PATH_SYSTEM_CONF_PKG_DIR,
+              progname) < 0) {
+              errx(1, "no memory");
+        }
+
+        /* Try specific config filename first, in base system
+        * and package locations, * and only if it fails, the global
+        * system one.
+         */
+       if((l=do_config(progname, specific_pkg_config, rs_config))) return l;
+       if((l=do_config(progname, specificconfig, rs_config))) return l;
+       if((l=do_config(progname, req_config, rs_config))) return l;
+
+       return NULL;
+}
+
diff --git a/commands/service/parse.h b/commands/service/parse.h
new file mode 100644 (file)
index 0000000..08487b6
--- /dev/null
@@ -0,0 +1,23 @@
+#define KW_SERVICE     "service"
+#define KW_UID         "uid"
+#define KW_SIGMGR      "sigmgr"
+#define KW_SCHEDULER   "scheduler"
+#define KW_PRIORITY    "priority"
+#define KW_QUANTUM     "quantum"
+#define KW_CPU         "cpu"
+#define KW_IRQ         "irq"
+#define KW_IO          "io"
+#define KW_PCI         "pci"
+#define KW_DEVICE      "device"
+#define KW_CLASS       "class"
+#define KW_SYSTEM      "system"
+#define KW_IPC         "ipc"
+#define KW_VM          "vm"
+#define KW_CONTROL     "control"
+#define KW_ALL         "ALL"
+#define KW_ALL_SYS     "ALL_SYS"
+#define KW_NONE                "NONE"
+#define KW_BASIC       "BASIC"
+#define KW_TYPE                "type"  /* set service type */
+#define KW_NET         "net"   /* ethernet driver type */
+#define KW_DESCR       "descr" /* human-readable string */
diff --git a/commands/service/print.c b/commands/service/print.c
new file mode 100644 (file)
index 0000000..52ea796
--- /dev/null
@@ -0,0 +1,97 @@
+
+#include <stdarg.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <limits.h>
+#include <lib.h>
+#include <minix/config.h>
+#include <minix/com.h>
+#include <minix/const.h>
+#include <minix/type.h>
+#include <minix/ipc.h>
+#include <minix/rs.h>
+#include <minix/syslib.h>
+#include <minix/bitmap.h>
+#include <paths.h>
+#include <minix/sef.h>
+#include <minix/dmap.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <configfile.h>
+
+#include <machine/archtypes.h>
+#include <timers.h>
+#include <err.h>
+
+#include "config.h"
+#include "proto.h"
+#include "parse.h"
+
+#define MAXDEPTH 10
+
+static struct {
+       const char *field, *str;
+} configstack[MAXDEPTH];
+
+int depth = 0;
+
+void printstack(void)
+{
+       int i;
+       for(i = 0; i < depth; i++)
+               printf("%s %s,", configstack[i].field,
+                       configstack[i].str);
+}
+
+void print(const char *field, const char *str)
+{
+       printstack();
+       printf("%s %s\n", field, str);
+}
+
+void push(const char *field, const char *str)
+{
+       assert(depth < MAXDEPTH);
+       configstack[depth].field = field;
+       configstack[depth].str = str;
+       depth++;
+       printstack();
+       printf("\n");
+}
+
+int main(int argc, char **argv)
+{
+       struct rs_config config;
+       const char *label;
+        int id;
+
+       if(argc != 2) {
+               fprintf(stderr, "usage: %s <config>\n", argv[0]);
+               return 1;
+       }
+
+       memset(&config, 0, sizeof(config));
+       if(!(label = parse_config(NULL, 1, argv[1], &config)))
+               errx(1, "parse_config failed");
+
+       push(KW_SERVICE, label);
+       if(config.type) push(KW_TYPE, config.type);
+
+       if(config.descr) push(KW_DESCR, config.descr);
+       if(config.rs_start.rss_nr_pci_id > 0) {
+               printstack();
+               printf("%s %s ", KW_PCI, KW_DEVICE);
+               for(id = 0; id < config.rs_start.rss_nr_pci_id; id++) {
+                       printf("%04X:%04X ",
+                               config.rs_start.rss_pci_id[id].vid,
+                               config.rs_start.rss_pci_id[id].did);
+               }
+               printf("\n");
+       }
+}
+
diff --git a/commands/service/proto.h b/commands/service/proto.h
new file mode 100644 (file)
index 0000000..48cfb78
--- /dev/null
@@ -0,0 +1,3 @@
+void fatal(char *fmt, ...);
+const char *parse_config(char *progname, int custom, char *configname,
+       struct rs_config *config);
index 68314c8f6c066e116071d6609994dc0a49a9cded..8f2b56d663a44138185e055933526a0e7d94bbe7 100644 (file)
 
 #include <machine/archtypes.h>
 #include <timers.h>
+#include <err.h>
 #include "kernel/proc.h"
 
+#include "config.h"
+#include "proto.h"
 
 /* This array defines all known requests. */
 PRIVATE char *known_requests[] = {
@@ -98,10 +101,6 @@ PRIVATE char *known_requests[] = {
 #define ARG_DEVMANID   "-devid"    /* the id of the devman device this
                                        driver should be able to access  */
 
-#define SERVICE_LOGIN  "service"       /* passwd file entry for services */
-
-#define MAX_CLASS_RECURS       100     /* Max nesting level for classes */
-
 /* The function parse_arguments() verifies and parses the command line 
  * parameters passed to this utility. Request parameters that are needed
  * are stored globally in the following variables:
@@ -117,19 +116,14 @@ PRIVATE int devman_id = 0;
 PRIVATE int req_dev_style = STYLE_NDEV;
 PRIVATE long req_period = 0;
 PRIVATE char *req_script = NULL;
-PRIVATE char *req_ipc = NULL;
 PRIVATE char *req_config = PATH_CONFIG;
 PRIVATE int custom_config_file = 0;
-PRIVATE int class_recurs;      /* Nesting level of class statements */
 PRIVATE int req_lu_state = DEFAULT_LU_STATE;
 PRIVATE int req_lu_maxtime = DEFAULT_LU_MAXTIME;
 
 /* Buffer to build "/command arg1 arg2 ..." string to pass to RS server. */
 PRIVATE char command[4096];    
 
-/* Arguments for RS to start a new service */
-PRIVATE struct rs_start rs_start;
-
 /* An error occurred. Report the problem, print the usage, and exit. 
  */
 PRIVATE void print_usage(char *app_name, char *problem) 
@@ -161,7 +155,7 @@ PRIVATE void failure(int request)
 /* Parse and verify correctness of arguments. Report problem and exit if an 
  * error is found. Store needed parameters in global variables.
  */
-PRIVATE int parse_arguments(int argc, char **argv)
+PRIVATE int parse_arguments(int argc, char **argv, u32_t *rss_flags)
 {
   struct stat stat_buf;
   char *hz, *buff;
@@ -226,28 +220,28 @@ PRIVATE int parse_arguments(int argc, char **argv)
        req_nr = RS_RQ_BASE + req_type;
   }
 
-  rs_start.rss_flags = RSS_SYS_BASIC_CALLS | RSS_VM_BASIC_CALLS;
+  *rss_flags = 0;
   if (req_nr == RS_UP || req_nr == RS_UPDATE || req_nr == RS_EDIT) {
       u32_t system_hz;
 
       if (c_flag)
-       rs_start.rss_flags |= RSS_COPY;
+       *rss_flags |= RSS_COPY;
 
       if(r_flag)
-        rs_start.rss_flags |= RSS_REUSE;
+        *rss_flags |= RSS_REUSE;
 
       if(n_flag)
-        rs_start.rss_flags |= RSS_NOBLOCK;
+        *rss_flags |= RSS_NOBLOCK;
 
       if(p_flag)
-        rs_start.rss_flags |= RSS_REPLICA;
+        *rss_flags |= RSS_REPLICA;
 
       req_path = argv[optind+ARG_PATH];
       if(req_nr == RS_UPDATE && !strcmp(req_path, SELF_BINARY)) {
           /* Self update needs no real path or configuration file. */
           req_config = NULL;
           req_path = req_path_self;
-          rs_start.rss_flags |= RSS_SELF_LU;
+          *rss_flags |= RSS_SELF_LU;
       }
 
       if (do_run)
@@ -263,7 +257,7 @@ PRIVATE int parse_arguments(int argc, char **argv)
       }
 
       /* Verify the name of the binary of the system service. */
-      if(!(rs_start.rss_flags & RSS_SELF_LU)) {
+      if(!(*rss_flags & RSS_SELF_LU)) {
           if (req_path[0] != '/') {
               print_usage(argv[ARG_NAME], "binary should be absolute path");
               exit(EINVAL);
@@ -406,7 +400,7 @@ PRIVATE int parse_arguments(int argc, char **argv)
         /* no extra arguments required */
   }
 
-  label_required = (rs_start.rss_flags & RSS_SELF_LU) || (req_nr == RS_EDIT);
+  label_required = (*rss_flags & RSS_SELF_LU) || (req_nr == RS_EDIT);
   if(label_required && !req_label) {
       print_usage(argv[ARG_NAME], "label option mandatory for target action");
       exit(EINVAL);
@@ -416,1014 +410,6 @@ PRIVATE int parse_arguments(int argc, char **argv)
   return(req_nr);
 }
 
-PRIVATE void fatal(char *fmt, ...)
-{
-       va_list ap;
-
-       fprintf(stderr, "fatal error: ");
-       va_start(ap, fmt);
-       vfprintf(stderr, fmt, ap);
-       va_end(ap);
-       fprintf(stderr, "\n");
-
-       exit(1);
-}
-
-#define KW_SERVICE     "service"
-#define KW_UID         "uid"
-#define KW_SIGMGR      "sigmgr"
-#define KW_SCHEDULER   "scheduler"
-#define KW_PRIORITY    "priority"
-#define KW_QUANTUM     "quantum"
-#define KW_CPU         "cpu"
-#define KW_IRQ         "irq"
-#define KW_IO          "io"
-#define KW_PCI         "pci"
-#define KW_DEVICE      "device"
-#define KW_CLASS       "class"
-#define KW_SYSTEM      "system"
-#define KW_IPC         "ipc"
-#define KW_VM          "vm"
-#define KW_CONTROL     "control"
-#define KW_ALL         "ALL"
-#define KW_ALL_SYS     "ALL_SYS"
-#define KW_NONE                "NONE"
-#define KW_BASIC       "BASIC"
-
-FORWARD void do_service(config_t *cpe, config_t *config);
-
-PRIVATE void do_class(config_t *cpe, config_t *config)
-{
-       config_t *cp, *cp1;
-
-       if (class_recurs > MAX_CLASS_RECURS)
-       {
-               fatal(
-               "do_class: nesting level too high for class '%s' at %s:%d",
-                       cpe->word, cpe->file, cpe->line);
-       }
-       class_recurs++;
-
-       /* Process classes */
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_class: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_uid: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               /* Find entry for the class */
-               for (cp= config; cp; cp= cp->next)
-               {
-                       if (!(cp->flags & CFG_SUBLIST))
-                       {
-                               fatal("do_class: expected list at %s:%d",
-                                       cp->file, cp->line);
-                       }
-                       cp1= cp->list;
-                       if ((cp1->flags & CFG_STRING) ||
-                               (cp1->flags & CFG_SUBLIST))
-                       {
-                               fatal("do_class: expected word at %s:%d",
-                                       cp1->file, cp1->line);
-                       }
-
-                       /* At this place we expect the word KW_SERVICE */
-                       if (strcmp(cp1->word, KW_SERVICE) != 0)
-                               fatal("do_class: exected word '%S' at %s:%d",
-                                       KW_SERVICE, cp1->file, cp1->line);
-
-                       cp1= cp1->next;
-                       if ((cp1->flags & CFG_STRING) ||
-                               (cp1->flags & CFG_SUBLIST))
-                       {
-                               fatal("do_class: expected word at %s:%d",
-                                       cp1->file, cp1->line);
-                       }
-
-                       /* At this place we expect the name of the service */
-                       if (strcmp(cp1->word, cpe->word) == 0)
-                               break;
-               }
-               if (cp == NULL)
-               {
-                       fatal(
-                       "do_class: no entry found for class '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               }
-               do_service(cp1->next, config);
-       }
-
-       class_recurs--;
-}
-
-PRIVATE void do_uid(config_t *cpe)
-{
-       uid_t uid;
-       struct passwd *pw;
-       char *check;
-
-       /* Process a uid */
-       if (cpe->next != NULL)
-       {
-               fatal("do_uid: just one uid/login expected at %s:%d",
-                       cpe->file, cpe->line);
-       }       
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_uid: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_uid: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       pw= getpwnam(cpe->word);
-       if (pw != NULL)
-               uid= pw->pw_uid;
-       else
-       {
-               uid= strtol(cpe->word, &check, 0);
-               if (check[0] != '\0')
-               {
-                       fatal("do_uid: bad uid/login '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               }
-       }
-
-       rs_start.rss_uid= uid;
-}
-
-PRIVATE void do_sigmgr(config_t *cpe)
-{
-       endpoint_t sigmgr_ep;
-       int r;
-
-       /* Process a signal manager value */
-       if (cpe->next != NULL)
-       {
-               fatal("do_sigmgr: just one sigmgr value expected at %s:%d",
-                       cpe->file, cpe->line);
-       }       
-       
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_sigmgr: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_sigmgr: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-
-       if(!strcmp(cpe->word, "SELF")) {
-               sigmgr_ep = SELF;
-       }
-       else {
-               r = minix_rs_lookup(cpe->word, &sigmgr_ep);
-               if(r != OK) {
-                       fatal("do_sigmgr: unknown sigmgr %s at %s:%d",
-                       cpe->word, cpe->file, cpe->line);
-               }
-       }
-
-       rs_start.rss_sigmgr= sigmgr_ep;
-}
-
-PRIVATE void do_scheduler(config_t *cpe)
-{
-       endpoint_t scheduler_ep;
-       int r;
-
-       /* Process a scheduler value */
-       if (cpe->next != NULL)
-       {
-               fatal("do_scheduler: just one scheduler value expected at %s:%d",
-                       cpe->file, cpe->line);
-       }       
-       
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_scheduler: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_scheduler: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-
-       if(!strcmp(cpe->word, "KERNEL")) {
-               scheduler_ep = KERNEL;
-       }
-       else {
-               r = minix_rs_lookup(cpe->word, &scheduler_ep);
-               if(r != OK) {
-                       fatal("do_scheduler: unknown scheduler %s at %s:%d",
-                       cpe->word, cpe->file, cpe->line);
-               }
-       }
-
-       rs_start.rss_scheduler= scheduler_ep;
-}
-
-PRIVATE void do_priority(config_t *cpe)
-{
-       int priority_val;
-       char *check;
-
-       /* Process a priority value */
-       if (cpe->next != NULL)
-       {
-               fatal("do_priority: just one priority value expected at %s:%d",
-                       cpe->file, cpe->line);
-       }       
-       
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_priority: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_priority: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       priority_val= strtol(cpe->word, &check, 0);
-       if (check[0] != '\0')
-       {
-               fatal("do_priority: bad priority value '%s' at %s:%d",
-                       cpe->word, cpe->file, cpe->line);
-       }
-
-       if (priority_val < 0 || priority_val >= NR_SCHED_QUEUES)
-       {
-               fatal("do_priority: priority %d out of range at %s:%d",
-                       priority_val, cpe->file, cpe->line);
-       }
-       rs_start.rss_priority= priority_val;
-}
-
-PRIVATE void do_quantum(config_t *cpe)
-{
-       int quantum_val;
-       char *check;
-
-       /* Process a quantum value */
-       if (cpe->next != NULL)
-       {
-               fatal("do_quantum: just one quantum value expected at %s:%d",
-                       cpe->file, cpe->line);
-       }       
-       
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_quantum: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_quantum: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       quantum_val= strtol(cpe->word, &check, 0);
-       if (check[0] != '\0')
-       {
-               fatal("do_quantum: bad quantum value '%s' at %s:%d",
-                       cpe->word, cpe->file, cpe->line);
-       }
-
-       if (quantum_val <= 0)
-       {
-               fatal("do_quantum: quantum %d out of range at %s:%d",
-                       quantum_val, cpe->file, cpe->line);
-       }
-       rs_start.rss_quantum= quantum_val;
-}
-
-PRIVATE void do_cpu(config_t *cpe)
-{
-       int cpu;
-       char *check;
-
-       /* Process a quantum value */
-       if (cpe->next != NULL)
-       {
-               fatal("do_cpu: just one value expected at %s:%d",
-                       cpe->file, cpe->line);
-       }       
-       
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_cpu: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_cpu: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       cpu= strtol(cpe->word, &check, 0);
-       if (check[0] != '\0')
-       {
-               fatal("do_cpu: bad value '%s' at %s:%d",
-                       cpe->word, cpe->file, cpe->line);
-       }
-
-       if (cpu < 0)
-       {
-               fatal("do_cpu: %d out of range at %s:%d",
-                       cpu, cpe->file, cpe->line);
-       }
-       rs_start.rss_cpu= cpu;
-}
-
-PRIVATE void do_irq(config_t *cpe)
-{
-       int irq;
-       int first;
-       char *check;
-
-       /* Process a list of IRQs */
-       first = TRUE;
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_irq: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_irq: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               /* No IRQ allowed? (default) */
-               if(!strcmp(cpe->word, KW_NONE)) {
-                       if(!first || cpe->next) {
-                               fatal("do_irq: %s keyword not allowed in list",
-                               KW_NONE);
-                       }
-                       break;
-               }
-
-               /* All IRQs are allowed? */
-               if(!strcmp(cpe->word, KW_ALL)) {
-                       if(!first || cpe->next) {
-                               fatal("do_irq: %s keyword not allowed in list",
-                               KW_ALL);
-                       }
-                       rs_start.rss_nr_irq = RSS_IO_ALL;
-                       break;
-               }
-
-               /* Set single IRQs as specified in the configuration. */
-               irq= strtoul(cpe->word, &check, 0);
-               if (check[0] != '\0')
-               {
-                       fatal("do_irq: bad irq '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               }
-               if (rs_start.rss_nr_irq >= RSS_NR_IRQ)
-                       fatal("do_irq: too many IRQs (max %d)", RSS_NR_IRQ);
-               rs_start.rss_irq[rs_start.rss_nr_irq]= irq;
-               rs_start.rss_nr_irq++;
-               first = FALSE;
-       }
-}
-
-PRIVATE void do_io(config_t *cpe)
-{
-       unsigned base, len;
-       int first;
-       char *check;
-
-       /* Process a list of I/O ranges */
-       first = TRUE;
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_io: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_io: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               /* No range allowed? (default) */
-               if(!strcmp(cpe->word, KW_NONE)) {
-                       if(!first || cpe->next) {
-                               fatal("do_io: %s keyword not allowed in list",
-                               KW_NONE);
-                       }
-                       break;
-               }
-
-               /* All ranges are allowed? */
-               if(!strcmp(cpe->word, KW_ALL)) {
-                       if(!first || cpe->next) {
-                               fatal("do_io: %s keyword not allowed in list",
-                               KW_ALL);
-                       }
-                       rs_start.rss_nr_io = RSS_IO_ALL;
-                       break;
-               }
-
-               /* Set single ranges as specified in the configuration. */
-               base= strtoul(cpe->word, &check, 0x10);
-               len= 1;
-               if (check[0] == ':')
-               {
-                       len= strtoul(check+1, &check, 0x10);
-               }
-               if (check[0] != '\0')
-               {
-                       fatal("do_io: bad I/O range '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               }
-
-               if (rs_start.rss_nr_io >= RSS_NR_IO)
-                       fatal("do_io: too many I/O ranges (max %d)", RSS_NR_IO);
-               rs_start.rss_io[rs_start.rss_nr_io].base= base;
-               rs_start.rss_io[rs_start.rss_nr_io].len= len;
-               rs_start.rss_nr_io++;
-               first = FALSE;
-       }
-}
-
-PRIVATE void do_pci_device(config_t *cpe)
-{
-       u16_t vid, did;
-       char *check, *check2;
-
-       /* Process a list of PCI device IDs */
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_pci_device: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_pci_device: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               vid= strtoul(cpe->word, &check, 0x10);
-               if (check[0] == '/')
-                       did= strtoul(check+1, &check2, 0x10);
-               if (check[0] != '/' || check2[0] != '\0')
-               {
-                       fatal("do_pci_device: bad ID '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               }
-               if (rs_start.rss_nr_pci_id >= RS_NR_PCI_DEVICE)
-               {
-                       fatal("do_pci_device: too many device IDs (max %d)",
-                               RS_NR_PCI_DEVICE);
-               }
-               rs_start.rss_pci_id[rs_start.rss_nr_pci_id].vid= vid;
-               rs_start.rss_pci_id[rs_start.rss_nr_pci_id].did= did;
-               rs_start.rss_nr_pci_id++;
-       }
-}
-
-PRIVATE void do_pci_class(config_t *cpe)
-{
-       u8_t baseclass, subclass, interface;
-       u32_t class_id, mask;
-       char *check;
-
-       /* Process a list of PCI device class IDs */
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_pci_device: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_pci_device: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               baseclass= strtoul(cpe->word, &check, 0x10);
-               subclass= 0;
-               interface= 0;
-               mask= 0xff0000;
-               if (check[0] == '/')
-               {
-                       subclass= strtoul(check+1, &check, 0x10);
-                       mask= 0xffff00;
-                       if (check[0] == '/')
-                       {
-                               interface= strtoul(check+1, &check, 0x10);
-                               mask= 0xffffff;
-                       }
-               }
-
-               if (check[0] != '\0')
-               {
-                       fatal("do_pci_class: bad class ID '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               }
-               class_id= (baseclass << 16) | (subclass << 8) | interface;
-               if (rs_start.rss_nr_pci_class >= RS_NR_PCI_CLASS)
-               {
-                       fatal("do_pci_class: too many class IDs (max %d)",
-                               RS_NR_PCI_CLASS);
-               }
-               rs_start.rss_pci_class[rs_start.rss_nr_pci_class].pciclass=
-                       class_id;
-               rs_start.rss_pci_class[rs_start.rss_nr_pci_class].mask= mask;
-               rs_start.rss_nr_pci_class++;
-       }
-}
-
-PRIVATE void do_pci(config_t *cpe)
-{
-       if (cpe == NULL)
-               return; /* Empty PCI statement */
-
-       if (cpe->flags & CFG_SUBLIST)
-       {
-               fatal("do_pci: unexpected sublist at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->flags & CFG_STRING)
-       {
-               fatal("do_pci: unexpected string at %s:%d",
-                       cpe->file, cpe->line);
-       }
-
-       if (strcmp(cpe->word, KW_DEVICE) == 0)
-       {
-               do_pci_device(cpe->next);
-               return;
-       }
-       if (strcmp(cpe->word, KW_CLASS) == 0)
-       {
-               do_pci_class(cpe->next);
-               return;
-       }
-       fatal("do_pci: unexpected word '%s' at %s:%d",
-               cpe->word, cpe->file, cpe->line);
-}
-
-PRIVATE void do_ipc(config_t *cpe)
-{
-       char *list, *word;
-       char *word_all = RSS_IPC_ALL;
-       char *word_all_sys = RSS_IPC_ALL_SYS;
-       size_t listsize, wordlen;
-       int first;
-
-       list= NULL;
-       listsize= 1;
-       list= malloc(listsize);
-       if (list == NULL)
-               fatal("do_ipc: unable to malloc %d bytes", listsize);
-       list[0]= '\0';
-
-       /* Process a list of process names that are allowed to be
-        * contacted
-        */
-       first = TRUE;
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_ipc: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_ipc: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               word = cpe->word;
-
-               /* All (system) ipc targets are allowed? */
-               if(!strcmp(word, KW_ALL) || !strcmp(word, KW_ALL_SYS)) {
-                       if(!first || cpe->next) {
-                               fatal("do_ipc: %s keyword not allowed in list",
-                               word);
-                       }
-                       word = !strcmp(word, KW_ALL) ? word_all : word_all_sys;
-               }
-
-               wordlen= strlen(word);
-
-               listsize += 1 + wordlen;
-               list= realloc(list, listsize);
-               if (list == NULL)
-               {
-                       fatal("do_ipc: unable to realloc %d bytes",
-                               listsize);
-               }
-               strcat(list, " ");
-               strcat(list, word);
-               first = FALSE;
-       }
-#if 0
-       printf("do_ipc: got list '%s'\n", list);
-#endif
-
-       if (req_ipc)
-               fatal("do_ipc: req_ipc is set");
-       req_ipc= list;
-}
-
-struct
-{
-       char *label;
-       int call_nr;
-} vm_table[] =
-{
-       { "EXIT",               VM_EXIT },
-       { "FORK",               VM_FORK },
-       { "BRK",                VM_BRK },
-       { "EXEC_NEWMEM",        VM_EXEC_NEWMEM },
-       { "PUSH_SIG",           VM_PUSH_SIG },
-       { "WILLEXIT",           VM_WILLEXIT },
-       { "ADDDMA",             VM_ADDDMA },
-       { "DELDMA",             VM_DELDMA },
-       { "GETDMA",             VM_GETDMA },
-       { "REMAP",              VM_REMAP },
-       { "SHM_UNMAP",          VM_SHM_UNMAP },
-       { "GETPHYS",            VM_GETPHYS },
-       { "GETREF",             VM_GETREF },
-       { "RS_SET_PRIV",        VM_RS_SET_PRIV },
-       { "QUERY_EXIT",         VM_QUERY_EXIT },
-       { "WATCH_EXIT",         VM_WATCH_EXIT },
-       { "NOTIFY_SIG",         VM_NOTIFY_SIG },
-       { "INFO",               VM_INFO },
-       { "RS_UPDATE",          VM_RS_UPDATE },
-       { "RS_MEMCTL",          VM_RS_MEMCTL },
-       { NULL,                 0 },
-};
-
-PRIVATE void do_vm(config_t *cpe)
-{
-       int i, first;
-
-       first = TRUE;
-       for (; cpe; cpe = cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_vm: unexpected sublist at %s:%d",
-                             cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_vm: unexpected string at %s:%d",
-                             cpe->file, cpe->line);
-               }
-
-               /* Only basic calls allowed? (default). */
-               if(!strcmp(cpe->word, KW_BASIC)) {
-                       if(!first || cpe->next) {
-                               fatal("do_vm: %s keyword not allowed in list",
-                               KW_NONE);
-                       }
-                       break;
-               }
-
-               /* No calls allowed? */
-               if(!strcmp(cpe->word, KW_NONE)) {
-                       if(!first || cpe->next) {
-                               fatal("do_vm: %s keyword not allowed in list",
-                               KW_NONE);
-                       }
-                       rs_start.rss_flags &= ~RSS_VM_BASIC_CALLS;
-                       break;
-               }
-
-               /* All calls are allowed? */
-               if(!strcmp(cpe->word, KW_ALL)) {
-                       if(!first || cpe->next) {
-                               fatal("do_vm: %s keyword not allowed in list",
-                               KW_ALL);
-                       }
-                       for (i = 0; i < NR_VM_CALLS; i++)
-                               SET_BIT(rs_start.rss_vm, i);
-                       break;
-               }
-
-               /* Set single calls as specified in the configuration. */
-               for (i = 0; vm_table[i].label != NULL; i++)
-                       if (!strcmp(cpe->word, vm_table[i].label))
-                               break;
-               if (vm_table[i].label == NULL)
-                       fatal("do_vm: unknown call '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               SET_BIT(rs_start.rss_vm, vm_table[i].call_nr - VM_RQ_BASE);
-               first = FALSE;
-       }
-}
-
-struct
-{
-       char *label;
-       int call_nr;
-} system_tab[]=
-{
-       { "PRIVCTL",            SYS_PRIVCTL },
-       { "TRACE",              SYS_TRACE },
-       { "KILL",               SYS_KILL },
-       { "UMAP",               SYS_UMAP },
-       { "VIRCOPY",            SYS_VIRCOPY },
-       { "PHYSCOPY",           SYS_PHYSCOPY },
-       { "UMAP_REMOTE",        SYS_UMAP_REMOTE },
-       { "IRQCTL",             SYS_IRQCTL },
-       { "INT86",              SYS_INT86 },
-       { "DEVIO",              SYS_DEVIO },
-       { "SDEVIO",             SYS_SDEVIO },
-       { "VDEVIO",             SYS_VDEVIO },
-       { "ABORT",              SYS_ABORT },
-       { "IOPENABLE",          SYS_IOPENABLE },
-       { "READBIOS",           SYS_READBIOS },
-       { "STIME",              SYS_STIME },
-       { "VMCTL",              SYS_VMCTL },
-       { NULL,         0 }
-};
-
-PRIVATE void do_system(config_t *cpe)
-{
-       int i, first;
-
-       /* Process a list of 'system' calls that are allowed */
-       first = TRUE;
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_system: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_system: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               /* Only basic calls allowed? (default). */
-               if(!strcmp(cpe->word, KW_BASIC)) {
-                       if(!first || cpe->next) {
-                               fatal("do_system: %s keyword not allowed in list",
-                               KW_NONE);
-                       }
-                       break;
-               }
-
-               /* No calls allowed? */
-               if(!strcmp(cpe->word, KW_NONE)) {
-                       if(!first || cpe->next) {
-                               fatal("do_system: %s keyword not allowed in list",
-                               KW_NONE);
-                       }
-                       rs_start.rss_flags &= ~RSS_SYS_BASIC_CALLS;
-                       break;
-               }
-
-               /* All calls are allowed? */
-               if(!strcmp(cpe->word, KW_ALL)) {
-                       if(!first || cpe->next) {
-                               fatal("do_system: %s keyword not allowed in list",
-                               KW_ALL);
-                       }
-                       for (i = 0; i < NR_SYS_CALLS; i++)
-                               SET_BIT(rs_start.rss_system, i);
-                       break;
-               }
-
-               /* Set single calls as specified in the configuration. */
-               for (i = 0; system_tab[i].label != NULL; i++)
-                       if (!strcmp(cpe->word, system_tab[i].label))
-                               break;
-               if (system_tab[i].label == NULL)
-                       fatal("do_system: unknown call '%s' at %s:%d",
-                               cpe->word, cpe->file, cpe->line);
-               SET_BIT(rs_start.rss_system, system_tab[i].call_nr - KERNEL_CALL);
-               first = FALSE;
-       }
-}
-
-PRIVATE void do_control(config_t *cpe)
-{
-       int nr_control = 0;
-
-       /* Process a list of 'control' labels. */
-       for (; cpe; cpe= cpe->next)
-       {
-               if (cpe->flags & CFG_SUBLIST)
-               {
-                       fatal("do_control: unexpected sublist at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (cpe->flags & CFG_STRING)
-               {
-                       fatal("do_control: unexpected string at %s:%d",
-                               cpe->file, cpe->line);
-               }
-               if (nr_control >= RS_NR_CONTROL)
-               {
-                       fatal(
-                       "do_control: RS_NR_CONTROL is too small (%d needed)",
-                               nr_control+1);
-               }
-
-               rs_start.rss_control[nr_control].l_addr = (char*) cpe->word;
-               rs_start.rss_control[nr_control].l_len = strlen(cpe->word);
-               rs_start.rss_nr_control = ++nr_control;
-       }
-}
-
-PRIVATE void do_service(config_t *cpe, config_t *config)
-{
-       config_t *cp;
-
-       /* At this point we expect one sublist that contains the varios
-        * resource allocations
-        */
-       if (!(cpe->flags & CFG_SUBLIST))
-       {
-               fatal("do_service: expected list at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       if (cpe->next != NULL)
-       {
-               cpe= cpe->next;
-               fatal("do_service: expected end of list at %s:%d",
-                       cpe->file, cpe->line);
-       }
-       cpe= cpe->list;
-
-       /* Process the list */
-       for (cp= cpe; cp; cp= cp->next)
-       {
-               if (!(cp->flags & CFG_SUBLIST))
-               {
-                       fatal("do_service: expected list at %s:%d",
-                               cp->file, cp->line);
-               }
-               cpe= cp->list;
-               if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
-               {
-                       fatal("do_service: expected word at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               if (strcmp(cpe->word, KW_CLASS) == 0)
-               {
-                       do_class(cpe->next, config);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_UID) == 0)
-               {
-                       do_uid(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_SIGMGR) == 0)
-               {
-                       do_sigmgr(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_SCHEDULER) == 0)
-               {
-                       do_scheduler(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_PRIORITY) == 0)
-               {
-                       do_priority(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_QUANTUM) == 0)
-               {
-                       do_quantum(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_CPU) == 0)
-               {
-                       do_cpu(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_IRQ) == 0)
-               {
-                       do_irq(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_IO) == 0)
-               {
-                       do_io(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_PCI) == 0)
-               {
-                       do_pci(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_SYSTEM) == 0)
-               {
-                       do_system(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_IPC) == 0)
-               {
-                       do_ipc(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_VM) == 0)
-               {
-                       do_vm(cpe->next);
-                       continue;
-               }
-               if (strcmp(cpe->word, KW_CONTROL) == 0)
-               {
-                       do_control(cpe->next);
-                       continue;
-               }
-       }
-}
-
-PRIVATE int do_config(char *label, char *filename)
-{
-       config_t *config, *cp, *cpe;
-
-       config= config_read(filename, 0, NULL);
-       if (config == NULL)
-       {
-               /* config file read failed. */
-               return 1;
-       }
-
-       /* Find an entry for our service */
-       for (cp= config; cp; cp= cp->next)
-       {
-               if (!(cp->flags & CFG_SUBLIST))
-               {
-                       fatal("do_config: expected list at %s:%d",
-                               cp->file, cp->line);
-               }
-               cpe= cp->list;
-               if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
-               {
-                       fatal("do_config: expected word at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               /* At this place we expect the word KW_SERVICE */
-               if (strcmp(cpe->word, KW_SERVICE) != 0)
-                       fatal("do_config: exected word '%S' at %s:%d",
-                               KW_SERVICE, cpe->file, cpe->line);
-
-               cpe= cpe->next;
-               if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
-               {
-                       fatal("do_config: expected word at %s:%d",
-                               cpe->file, cpe->line);
-               }
-
-               /* At this place we expect the name of the service. */
-               if (strcmp(cpe->word, label) == 0)
-                       break;
-       }
-       if (cp == NULL)
-       {
-               fprintf(stderr, "service: service '%s' not found in '%s'\n",
-                       label, filename);
-               exit(1);
-       }
-
-       cpe= cpe->next;
-
-       do_service(cpe, config);
-
-       /* config file read ok. */
-       return 0;
-}
-
 /* Main program. 
  */
 PUBLIC int main(int argc, char **argv)
@@ -1432,14 +418,16 @@ PUBLIC int main(int argc, char **argv)
   int result = EXIT_SUCCESS;
   int request;
   char *progname = NULL;
-  struct passwd *pw;
+  /* Arguments for RS to start a new service */
+  struct rs_config config;
+  u32_t rss_flags = 0;
 
   /* Verify and parse the command line arguments. All arguments are checked
    * here. If an error occurs, the problem is reported and exit(2) is called. 
    * all needed parameters to perform the request are extracted and stored
    * global variables. 
    */
-  request = parse_arguments(argc, argv);
+  request = parse_arguments(argc, argv, &rss_flags);
 
   /* Arguments seem fine. Try to perform the request. Only valid requests 
    * should end up here. The default is used for not yet supported requests. 
@@ -1460,78 +448,38 @@ PUBLIC int main(int argc, char **argv)
       command[strlen(req_path)] = ' ';
       strcpy(command+strlen(req_path)+1, req_args);
 
-      rs_start.rss_cmd= command;
-      rs_start.rss_cmdlen= strlen(command);
-      rs_start.rss_major= req_major;
-      rs_start.rss_dev_style= req_dev_style;
-      rs_start.rss_period= req_period;
-      rs_start.rss_script= req_script;
-      rs_start.devman_id= devman_id;
-      if(req_label) {
-        rs_start.rss_label.l_addr = req_label;
-        rs_start.rss_label.l_len = strlen(req_label);
-      } else {
-        rs_start.rss_label.l_addr = progname;
-        rs_start.rss_label.l_len = strlen(progname);
-      }
-      if (req_script)
-             rs_start.rss_scriptlen= strlen(req_script);
-      else
-             rs_start.rss_scriptlen= 0;
-
-      pw= getpwnam(SERVICE_LOGIN);
-      if (pw == NULL)
-       fatal("no passwd file entry for '%s'", SERVICE_LOGIN);
-      rs_start.rss_uid= pw->pw_uid;
-
-      rs_start.rss_sigmgr= DSRV_SM;
-      rs_start.rss_scheduler= DSRV_SCH;
-      rs_start.rss_priority= DSRV_Q;
-      rs_start.rss_quantum= DSRV_QT;
-      rs_start.rss_cpu = DSRV_CPU;
-
       if (req_config) {
-       int config_fail = 0;
        assert(progname);
-       if(custom_config_file) {
-         config_fail = do_config(progname, req_config);
-       } else {
-         char *specificconfig;
-         if(asprintf(&specificconfig, "%s/%s", _PATH_SYSTEM_CONF_DIR,
-               progname) < 0) {
-               errx(1, "no memory");
-         }
-
-         /* Try specific config filename first, 
-          * and only if it fails, the global system one.
-          */
-         config_fail =
-               do_config(progname, specificconfig) &&
-               do_config(progname, req_config);
-       }
-
-        if(config_fail) {
-                 fprintf(stderr, "config_read failed for %s\n", progname);
-                 exit(1);
-        }
+       memset(&config, 0, sizeof(config));
+       if(!parse_config(progname, custom_config_file, req_config, &config))
+               errx(1, "couldn't parse config");
       }
 
-      assert(rs_start.rss_priority < NR_SCHED_QUEUES);
-      assert(rs_start.rss_quantum > 0);
-
-      if (req_ipc)
-      {
-             rs_start.rss_ipc= req_ipc+1;      /* Skip initial space */
-             rs_start.rss_ipclen= strlen(rs_start.rss_ipc);
+      /* Set specifics */
+      config.rs_start.rss_cmd= command;
+      config.rs_start.rss_cmdlen= strlen(command);
+      config.rs_start.rss_major= req_major;
+      config.rs_start.rss_dev_style= req_dev_style;
+      config.rs_start.rss_period= req_period;
+      config.rs_start.rss_script= req_script;
+      config.rs_start.devman_id= devman_id;
+      config.rs_start.rss_flags |= rss_flags;
+      if(req_label) {
+        config.rs_start.rss_label.l_addr = req_label;
+        config.rs_start.rss_label.l_len = strlen(req_label);
+      } else {
+        config.rs_start.rss_label.l_addr = progname;
+        config.rs_start.rss_label.l_len = strlen(progname);
       }
+      if (req_script)
+             config.rs_start.rss_scriptlen= strlen(req_script);
       else
-      {
-             char *default_ipc = RSS_IPC_ALL_SYS;
-             rs_start.rss_ipc= default_ipc;
-             rs_start.rss_ipclen= strlen(default_ipc);
-      }
+             config.rs_start.rss_scriptlen= 0;
+
+      assert(config.rs_start.rss_priority < NR_SCHED_QUEUES);
+      assert(config.rs_start.rss_quantum > 0);
 
-      m.RS_CMD_ADDR = (char *) &rs_start;
+      m.RS_CMD_ADDR = (char *) &config.rs_start;
       break;
   case RS_DOWN:
   case RS_REFRESH:
diff --git a/commands/service/util.c b/commands/service/util.c
new file mode 100644 (file)
index 0000000..6a36a8d
--- /dev/null
@@ -0,0 +1,17 @@
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void fatal(char *fmt, ...)
+{
+       va_list ap;
+
+       fprintf(stderr, "fatal error: ");
+       va_start(ap, fmt);
+       vfprintf(stderr, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "\n");
+
+       exit(1);
+}
index 82f9cd9987741d779c219631fda002995473fb7e..7787a867a9c9a51f77f0c8414560ec18775e5bf7 100644 (file)
@@ -9,7 +9,9 @@
 _PROTOTYPE(char *itoa, (int _n));
 #ifndef __NBSD_LIBC
 _PROTOTYPE(char *getpass, (const char *_prompt));
+#ifdef __ACK__
 _PROTOTYPE(void swab, (char *_from, char *_to, int _count));
+#endif
 #endif /* !_NBSD_LIBC */
 
 /* Miscellaneous MINIX. */
index 31d5a382da3b95724132badf6e321317f5bb3f2e..22d8d492f7e9b246342854c761cdaa58f2cb3768 100644 (file)
@@ -2,6 +2,10 @@
 PROG=  atl2
 SRCS=  atl2.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
diff --git a/drivers/atl2/atl2.conf b/drivers/atl2/atl2.conf
new file mode 100644 (file)
index 0000000..4cfee56
--- /dev/null
@@ -0,0 +1,15 @@
+service atl2
+{
+       type net;
+       descr "Attansic/Atheros L2 FastEthernet";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+        ;
+        pci device      1969/2048;
+        ipc
+                SYSTEM pm rs tty ds vm
+                pci inet lwip
+        ;
+};
+
index 42051f8adf0cd5f95c966f4f98b32cac811193f5..9b9522ffc09161748b8e38e69bfbc0ad0b410d00 100644 (file)
@@ -4,6 +4,10 @@
 PROG=  dec21140A
 SRCS=  dec21140A.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
diff --git a/drivers/dec21140A/dec21140A.conf b/drivers/dec21140A/dec21140A.conf
new file mode 100644 (file)
index 0000000..dd11993
--- /dev/null
@@ -0,0 +1,17 @@
+
+service dec21140A
+{
+       type    net;
+       descr   "DEC Tulip 21140A in VirtualPC";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+                DEVIO           # 21
+        ;
+        pci device      1011/0009;
+        ipc
+                SYSTEM pm rs log tty ds vm
+                pci inet lwip
+                ;
+};
+
index 91c8b43a88ff4c59657efe9b0340b1f602659828..aff128209c305584502e581b0101977fecf4abc2 100644 (file)
@@ -4,6 +4,10 @@
 PROG=  e1000
 SRCS=  e1000.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
 LDADD+=        -lnetdriver -lsys -ltimers
 
diff --git a/drivers/e1000/e1000.conf b/drivers/e1000/e1000.conf
new file mode 100644 (file)
index 0000000..583f475
--- /dev/null
@@ -0,0 +1,20 @@
+service e1000
+{
+       type net;
+       descr "Intel PRO/1000 Gigabit";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+                DEVIO           # 21
+        ;
+        pci device      8086/100e;
+        pci device      8086/107c;
+        pci device      8086/10cd;
+        pci device      8086/10d3;
+        pci device      8086/10de;
+        pci device      8086/105e;
+        ipc
+                SYSTEM pm rs log tty ds vm
+                pci inet lwip ;
+};
+
index baa7dca9f7fd5fa44684ec46423d6faf7b54e5be..643c793906a7fabd09a7d559134ee811d11fe03d 100644 (file)
@@ -2,6 +2,10 @@
 PROG=  fxp
 SRCS=  fxp.c mii.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
 LDADD+=        -lnetdriver -lsys -ltimers
 
diff --git a/drivers/fxp/fxp.conf b/drivers/fxp/fxp.conf
new file mode 100644 (file)
index 0000000..8f129ff
--- /dev/null
@@ -0,0 +1,22 @@
+
+service fxp
+{
+       type net;
+       descr "Intel PRO/100";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+                DEVIO           # 21
+        ;
+        pci device      8086/1031;
+        pci device      8086/1032;
+        pci device      8086/103d;
+        pci device      8086/1064;
+        pci device      8086/1229;
+        pci device      8086/2449;
+        ipc
+                SYSTEM pm rs log tty ds vm
+                pci inet lwip amddev
+                ;
+};
+
index edadb8d5efb40df54d3db409a6f2d4e391b68b8b..46f8e2ac13c8f90764e7d3421414daa5101864ee 100644 (file)
@@ -2,6 +2,10 @@
 PROG=  lance
 SRCS=  lance.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS}
 LDADD+=        -lnetdriver -lsys
 
diff --git a/drivers/lance/lance.conf b/drivers/lance/lance.conf
new file mode 100644 (file)
index 0000000..a25361f
--- /dev/null
@@ -0,0 +1,14 @@
+
+service lance
+{
+       type net;
+       descr "AMD LANCE (also emulated by VMWare and VirtualBox)";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+                DEVIO           # 21
+        ;
+        pci device      1022/2000;
+        uid     0;
+};
+
index 51f54f33e1f92ab7271ece36736deeae321a7874..f694c35446e7076d722ae5e01fbf48b258759721 100644 (file)
@@ -2,6 +2,10 @@
 PROG=  rtl8139
 SRCS=  rtl8139.c liveupdate.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
 LDADD+=        -lnetdriver -lsys -ltimers
 
diff --git a/drivers/rtl8139/rtl8139.conf b/drivers/rtl8139/rtl8139.conf
new file mode 100644 (file)
index 0000000..bbab4eb
--- /dev/null
@@ -0,0 +1,32 @@
+service rtl8139
+{
+        type net;
+        descr "Realtek 8139 based card";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+                DEVIO           # 21
+        ;
+        pci device      10ec/8139;
+        pci device      02ac/1012;
+        pci device      1065/8139;
+        pci device      1113/1211;
+        pci device      1186/1300;
+        pci device      1186/1340;
+        pci device      11db/1234;
+        pci device      1259/a117;
+        pci device      1259/a11e;
+        pci device      126c/1211;
+        pci device      13d1/ab06;
+        pci device      1432/9130;
+        pci device      14ea/ab06;
+        pci device      14ea/ab07;
+        pci device      1500/1360;
+        pci device      1743/8139;
+        pci device      4033/1360;
+        ipc
+                SYSTEM pm rs log tty ds vm
+                pci inet lwip amddev
+                ;
+};
+
index ab4516ff167bad3386eacc41802d66831a07b4e8..4d238d5fcabe878559eb011c8032888d0b8b85bb 100644 (file)
@@ -2,6 +2,10 @@
 PROG=  rtl8169
 SRCS=  rtl8169.c
 
+FILES=$(PROG).conf
+FILESNAME=$(PROG)
+FILESDIR= /etc/system.conf.d
+
 DPADD+=        ${LIBNETDRIVER} ${LIBSYS} ${LIBTIMERS}
 LDADD+=        -lnetdriver -lsys -ltimers
 
diff --git a/drivers/rtl8169/rtl8169.conf b/drivers/rtl8169/rtl8169.conf
new file mode 100644 (file)
index 0000000..b97a642
--- /dev/null
@@ -0,0 +1,25 @@
+
+service rtl8169
+{
+        type net;
+        descr "Realtek 8169 based card";
+        system
+                UMAP            # 14
+                IRQCTL          # 19
+                DEVIO           # 21
+        ;
+        pci device      10ec/8129;
+        pci device      10ec/8167;
+        pci device      10ec/8169;
+        pci device      10ec/8168;
+        pci device      1186/4300;
+        pci device      1259/c107;
+        pci device      1385/8169;
+        pci device      16ec/0116;
+        pci device      1737/1032;
+        ipc
+                SYSTEM pm rs log tty ds vm
+                pci inet lwip amddev
+                ;
+};
+
index 008cb9b8eb65daffa2df7c79493bc780c68de4a4..693474a7141ccc558ae39d09d0f9512523139a6c 100644 (file)
@@ -1,6 +1,7 @@
 ETC=/etc/
 USR=/usr/
 USRETC=/usr/etc/
+DEFAULTS=/etc/defaults
 FILES1=group hostname.file inet.conf motd.install mtab profile \
        protocols rc services termcap ttytab utmp rc.cd binary_sizes \
        binary_sizes.big binary_sizes.xxl syslog.conf rc.daemons.dist \
@@ -9,6 +10,7 @@ FILES1=group hostname.file inet.conf motd.install mtab profile \
 
 PWFILES=master.passwd
 FILES3=daily dhcptags.conf rc 
+DEFAULTFILES=minix.rc.conf
 USRFILES=Makefile
 
 TOOL_PWD_MKDB= pwd_mkdb
@@ -23,6 +25,7 @@ install:: installpw   # installpw needed to bootstrap pw db
        @echo "Making hierarchy.."
        sh mtree.sh mtree/minix.tree
        @for f in $(FILES3); do if [ -f $(USRETC)/$$f ]; then :; else cp usr/$$f $(USRETC); chmod 755 $(USRETC)/$$f; fi; done
+       for f in $(DEFAULTFILES); do cp $$f $(DEFAULTS); chmod 644 $(DEFAULTS)/$$f; done
        @echo "Making devices.."
        p=`pwd` && cd /dev && sh $$p/../commands/MAKEDEV/MAKEDEV.sh null
        p=`pwd` && cd /dev && sh $$p/../commands/MAKEDEV/MAKEDEV.sh std  2>/dev/null
diff --git a/etc/minix.rc.conf b/etc/minix.rc.conf
new file mode 100644 (file)
index 0000000..ba40b5f
--- /dev/null
@@ -0,0 +1,11 @@
+# Minix-specific rc.conf default values
+
+# Where to find servers/drivers binaries
+PKG_SERVICE_DIR=/usr/pkg/minixservices
+SERVICES_DIRS="/usr/sbin $PKG_SERVICE_DIR"
+
+# Where to find system.conf files and system.conf.d directories
+# for servers/drivers
+SYSTEM_CONF_SUBDIR=system.conf.d
+PKG_SYSTEM_CONF_DIR=/usr/pkg/etc
+SYSTEM_CONF_DIRS="/etc $PKG_SYSTEM_CONF_DIR"
index 3f6f2c1f1b2da5df22f6ef43c5b296cb2be4c73f..b8a650273810fb3e6baa0064345b3fc24318b4da 100644 (file)
@@ -4,6 +4,7 @@
 755 root    operator /dev
 /dev/mouse -> /dev/kbdaux
 755 root    operator /etc
+755 root    operator /etc/defaults
 755 root    operator /etc/system.conf.d
 755 root    operator /boot
 755 root    operator /boot/image
index 257ced00d109782e4f338403418c7db65e663c2e..ef877d54378a956387626b9ae4fa7bcb254cbc71 100644 (file)
@@ -13,6 +13,10 @@ if [ -r /etc/defaults/rc.conf ]; then
        . /etc/defaults/rc.conf
 fi
 
+if [ -r /etc/defaults/minix.rc.conf ]; then
+       . /etc/defaults/minix.rc.conf
+fi
+
 # If this is not set to YES, the system will drop into single-user mode.
 # (Doesn't matter for Minix.)
 rc_configured=NO
index 4adfc145465b89dcf7b860f23816dd5b6984f27b..5e147631b129861950e6afec900cf35a4db58ac6 100644 (file)
@@ -285,66 +285,6 @@ service dpeth
        uid     0;
 };
 
-service lance
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-               DEVIO           # 21
-       ;
-       pci device      1022/2000;
-       uid     0;
-};
-
-service rtl8139
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-               DEVIO           # 21
-       ;
-       pci device      10ec/8139;
-       pci device      02ac/1012;
-       pci device      1065/8139;
-       pci device      1113/1211;
-       pci device      1186/1300;
-       pci device      1186/1340;
-       pci device      11db/1234;
-       pci device      1259/a117;
-       pci device      1259/a11e;
-       pci device      126c/1211;
-       pci device      13d1/ab06;
-       pci device      1432/9130;
-       pci device      14ea/ab06;
-       pci device      14ea/ab07;
-       pci device      1500/1360;
-       pci device      1743/8139;
-       pci device      4033/1360;
-       ipc
-               SYSTEM pm rs log tty ds vm
-               pci inet lwip amddev
-               ;
-};
-
-service fxp
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-               DEVIO           # 21
-       ;
-       pci device      8086/1031;
-       pci device      8086/1032;
-       pci device      8086/103d;
-       pci device      8086/1064;
-       pci device      8086/1229;
-       pci device      8086/2449;
-       ipc
-               SYSTEM pm rs log tty ds vm
-               pci inet lwip amddev
-               ;
-};
-
 service inet
 {
        uid 0;
@@ -552,28 +492,6 @@ service osscore
        uid     0;
 };
 
-service rtl8169
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-               DEVIO           # 21
-       ;
-       pci device      10ec/8129;
-       pci device      10ec/8167;
-       pci device      10ec/8169;
-       pci device      10ec/8168;
-       pci device      1186/4300;
-       pci device      1259/c107;
-       pci device      1385/8169;
-       pci device      16ec/0116;
-       pci device      1737/1032;
-       ipc
-               SYSTEM pm rs log tty ds vm
-               pci inet lwip amddev
-               ;
-};
-
 service filter
 {
        ipc
@@ -587,51 +505,6 @@ service filter
        ;
 };
 
-service e1000
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-               DEVIO           # 21
-       ;
-       pci device      8086/100e;
-       pci device      8086/107c;
-       pci device      8086/10cd;
-       pci device      8086/10d3;
-       pci device      8086/10de;
-       pci device      8086/105e;
-       ipc
-               SYSTEM pm rs log tty ds vm
-               pci inet lwip ;
-};
-
-service atl2
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-       ;
-       pci device      1969/2048;
-       ipc
-               SYSTEM pm rs tty ds vm
-               pci inet lwip
-       ;
-};
-
-service dec21140A
-{
-       system
-               UMAP            # 14
-               IRQCTL          # 19
-               DEVIO           # 21
-       ;
-       pci device      1011/0009;
-       ipc
-               SYSTEM pm rs log tty ds vm
-               pci inet lwip
-               ;
-};
-
 service hello
 {
         system
index dafd371cb2c27844158e460dd97df13a32b34a40..a985e22872cbe6231722ea647148caf0b361761c 100644 (file)
@@ -3,6 +3,14 @@
 RANDOM_FILE=/usr/adm/random.dat
 LOCAL_FILE=/usr/etc/rc.local
 
+# Get $SERVICES_DIRS
+. /etc/rc.conf
+
+# Directories to find services in
+if [ ! "$SERVICES_DIRS" ]
+then   SERVICES_DIRS=/usr/sbin
+fi
+
 case "$#:$1" in
 1:start|1:stop|1:down)
     action=$1
@@ -69,8 +77,18 @@ up()
     if disabled $service; then return; fi
 
     # Service is not disabled. Try to bring it up.
-    echo -n " $service"
-    service $opt up /usr/sbin/$service "$@" 
+    found=""
+    for dir in $SERVICES_DIRS
+    do bin=$dir/$service
+       if [ -x $bin -a -z "$found" ]
+       then    service $opt up $bin "$@" 
+               echo -n " $service"
+               found=yes
+       fi
+    done
+    if [ -z "$found" ]
+    then       echo " ($service not found in $SERVICES_DIRS)"
+    fi
 }
 
 get_eth_labels() {
index 6ee679cdbe60bbca327a8ba3cc361d23e285550b..16985c9a67eb0b3bb850ac759cb7d968516fdc36 100644 (file)
@@ -63,6 +63,7 @@
 #define _PATH_SERVICE  "/bin/service"
 #define _PATH_SYSTEM_CONF      "/etc/system.conf"
 #define _PATH_SYSTEM_CONF_DIR  "/etc/system.conf.d"
+#define _PATH_SYSTEM_CONF_PKG_DIR      "/usr/pkg/etc/system.conf.d"
 
 /* Provide trailing slash, since mostly used for building pathnames. */
 #define _PATH_DEV      "/dev/"
index 9d3cead17de6bd4d17d3ed3c87b5d298036532d5..65ea4325badb9c99a9754bb9d2564ccc73ba830a 100644 (file)
@@ -6,6 +6,7 @@
 
 #define _PATH_SYSTEM_CONF "/etc/system.conf"
 #define _PATH_SYSTEM_CONF_DIR "/etc/system.conf.d"
+#define _PATH_SYSTEM_CONF_PKG_DIR       "/usr/pkg/etc/system.conf.d"
 
 #define _PATH_DHCPCONF "/etc/dhcp.conf"
 #define _PATH_DHCPPID  "/usr/run/dhcpd.pid"