From: Thomas Walker Lynch
Date: Fri, 5 Aug 2022 14:14:27 +0000 (+0000)
Subject: user cantari structure
X-Git-Url: https://git.reasoningtechnology.com/style/rt_dark_doc.css?a=commitdiff_plain;h=808dc1947e97a3bb435b454c80b86c21821b65d5;p=subu
user cantari structure
---
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 3cfdbec..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 Reasoning Technology
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README b/README
deleted file mode 100644
index 7af191c..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-Subservient user implementation. Just getting started, not much here yet.
diff --git a/document/cant_access_bus.txt b/document/cant_access_bus.txt
deleted file mode 100644
index dfb250d..0000000
--- a/document/cant_access_bus.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
-after changing to the new user:
-
-> export NO_AT_BRIDGE=1
diff --git a/document/note.txt b/document/note.txt
deleted file mode 100644
index 3cdd7d7..0000000
--- a/document/note.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-
-this does not apply to the current scripts, but rather the setuid code
-
-subu-mk-0
-
- 1. We have to make the subu for step 2 so that we will have subu_uid and subu_gid
- to work with, but we delay this for as long as possible, as the program might
- first bail due to other errors.
-
- 2. Then we add user access via setfacl to masteru's home directory and to
- subu_land, so that we have permissions to make the home directory.
-
- 3. Then as subu we create the home directory. .. I wonder where the system
- gets the umask for this? Perhaps we should create the dir, and then change
- the ownership instead?
-
- 4. Still as subu, we add facls to our directory to give masteru access.
-
-finished, good part is that we never need to move back to root.
-
-setfacl -m u:subu:x masteru
-setfacl -m u:subu:x masteru/subu_land
-setfacl -m d:u:masteru:rwX,u:masteru:rwX subu
-
-
-using luseradd to make the subu is a circular problem because we need to setfacls
-to allow the creating of the home directory inside the masteru/subu_land, but
-to set facls we need the uid from luseradd. So..
- 1. luseradd without creation of a home directory. We can provide the path,
- but can't create it.
- 2. get the uid, and set the facls
- 3. create the home directory
-
-Step 3 is a bit of a problem, because subu's don't have write permission for
-subu_land/
-
-.. or maybe not, luseradd puts users in /home, but those users don't have
-write permissions there either, so I'll try and see what happens.
-
-given all the funky security stuff recently, I really need to call luseradd
-to get the user added. Wish there was a C programming interface. My gosh,
-python has one, and you can't if setuid root python programs.
diff --git a/document/real_uid.txt b/document/real_uid.txt
deleted file mode 100644
index b25e817..0000000
--- a/document/real_uid.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-Real uid is a poorly named term for the uid of the user who launched the
-process. The uid that the process has been set to is the effective uid. There
-is a third stored uid in a process's record. Hence the uid being used by the
-OS will be set to one of these.
-
-Our subu-mk-0 program wants to create a subservient user to a master user. The
-master user is known via the real uid. The effective user will be that of root,
-as the script needs root privilege to run adduser.
-
-sudo resets the real uid, and there is no reliable approch then to create a subu-mk-0
-program run by sudo. A setuid root program is needed. Only compiled executables can
-be setuid root on linux.
-
-There is an environment variable given to programs run by sudo, $SUDO_USER. Sudo sets
-it, so if called from sudo then that works. It could be set by another user, even
-if that user is root or not.
-
-I will make a setuid C program. Too bad, had written this in Python.
diff --git a/document/real_uid_bug.pdf b/document/real_uid_bug.pdf
deleted file mode 100644
index 2d4a83d..0000000
Binary files a/document/real_uid_bug.pdf and /dev/null differ
diff --git a/document/sound.txt b/document/sound.txt
deleted file mode 100644
index 0a02f87..0000000
--- a/document/sound.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-before changing users:
-
-user must be in group audio
-
-> sudo dnf install pulseaudio-utils
-> pactl load-module module-native-protocol-tcp
-
-after changing users:
-
-> export PULSE_SERVER=localhost
-
-According to
-https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/CLI/#default.pa
-the module load command goes in /etc/pulse/default.pa and the pactl command is not needed,
-but this did not work:
-
- /etc/pulse/default.pa
- load-module module-native-protocol-tcp
-
-this did not work
-seems this must be run by the login user, not even root can do it:
-
- pactl load-module module-native-protocol-tcp
-
-also requires restart of google-chrome etc.
-
-for now I will add this the .bashrc file for admin
diff --git a/document/src.txt b/document/src.txt
deleted file mode 100644
index 902157b..0000000
--- a/document/src.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-
- src-da a simple doubling size expanding array in C
- src-tranche splits source code into multiple files. A poor man's 'makeheaders'.
-src-dispatch runs a function or shell command as a separate process
- src-db sqlite schema and interface for subu
- src-0 The layer 0 commands for subu. Some are setuid root programs.
- src-py The application layer
-
-
diff --git a/document/subu-mk-0.txt b/document/subu-mk-0.txt
deleted file mode 100644
index c3146bf..0000000
--- a/document/subu-mk-0.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-I. If we allowed the subu_home directory to be put anywhere, this script could
- be used by masteru gain access to any directory on the system. Hence, we have
- to add some constraints:
-
- constraint 1) the subuhome directory must not already exist, not as a
- directory or as any other type of object.
-
- constraint 2) masteru must already have privledges to reach access $(masteru_home)/subuland
-
- constraint 3) subuhome may only be placed under the directory $(masteru_home)/subuland.
-
- convention 4) only subuhome directories may be placed in $(masteru_home)/subuland.
-
- -> without constraint 1), exploit 1
-
- Suppose that a wily masteru was able to move an inaccessible directory that
- he or she wanted access to and place it under $(masteru_home)/subuland.
- Typically such directories are not moveable by wiley users in the first
- place, but suppose the wily masteru found such a directory.
-
- Alternatively suppose the wily masteru made a directory under
- $(masteru_home)/subuland of his or her own, and placed an inaccessible file
- or subdirectory inside of it.
-
- Alternatively suppose that the wily masteru made $(masteru_home)/subuland a
- hard link or a symlink to a directory that contained a subdirectory that
- masteru did not have access to.
-
- The the wiley masteru could then create a subu by the same name as the
- directory he desired access to, and trick the foolish subu-mk-0 into giving
- him or her access.
-
- -> without constraint 2) exploit 2
-
- Then the masteru could place subu directories in places he can not access.
- The foolish subu-mk-0 program would then add 'x' acls to as to reach this
- place. The masteru could then change identity to the subu, (i.e. enter the
- container), and then reach that place he or she could not reach before.
-
- -> without constraint 3) exploit 3
-
- If masteru looses x privlege to a place, subu might keep it, and then
- exploit 2 would work despite the existence of constraint 2. It would be
- unusual that masteru not have x privledges to masteru_home. Furthmore, we
- decree that masteru has x privige to subuland. Hence, exploit 3 can be
- prevented by following this convention.
-
- -> without convention 4) exploit 4
-
-
-II. the ownership flaw
-
-subu will own the files and directories that it makes. The default acls are
-such that masteru will also have access to subu's file. This defines the master
-user / subservient user convention on the filesystem.
-
-However, because subu owns the files and directories, it can modify the
-acls. Thus a wily subu can lock the masteru out.
-
-Perhaps the master has a 'fix perms' script. However, there is no enshrined
-relationship in the system between the masteru and the subu, so the system won't
-know for sure the subu belongs to the masteru, and thus can not allow masteru to
-change the supposed subu's permissions to give back access to masteru.
-
-Perhaps we propose that instead masteru owns the files and directories of
-subuhome, and subu is given access privilege through acls and default acls.
-Indeed, then subu can't change the acls on these existing files. However, if
-subu is allowed to own processes, then those processes might create files owned
-by the subu, and the subu can lock the master out from access to these new
-files.
-
-How about a variation. Perhaps the subu shares the uid of the masteru, but has
-a different gid. The subuhome then has the sticky bit set on the group access,
-so all files created remain the same gid. subu process are masteru processes,
-however the gid of the process is that of the subu's. Masteru can then control
-both the files and the processes, but in absence of this control, the subu has
-control.
-
-Then we don't make a new user when we make a subu, we make a new group. We then
-have to add utilities for 'logging into the subu' which goes to a different home
-directory based on the group being logged into.
-
-III. other approaches
-
-Groups don't seem to offer much help, the owner is still the owner.
-
-A volume can be mounted without the subu being able to modify the facls. I
-don't know if the default facls still apply, but if so, then this would be a
-solution.
-
-bindfs can translate uids and gids. The same directory can appear in two
-places, in one place owned by the subu and in another owned by the masteru.
-This looks to be potentially a clean solution. It would also be recursive,
-i.e. a subu could have subus. I'll try this one.
-
-One possibility is for the subusers to appear in /home/ as normal users. Then
-masteru bindfs with translation into subuland. Everything in subuland appears
-to be owned by masteru. This is a transparent way to give masteru control over
-all the files.
-
-Then is the question of being able to control the processes being run by a subu.
-We will need an /etc/ file that pairs masters and subus.
-
-
diff --git a/document/subu.txt b/document/subu.txt
deleted file mode 100644
index d422784..0000000
--- a/document/subu.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-
-subu is short for subservient user.
-
-A subu is much like any other user. It has an entry in /etc/passwd, and a home
-directory. As for other users this home directory is most likely under /home.
-Direct login to the subu might be barred, though that is not necessarly the case.
-
-Each subu has two names. One is its 'subu_username'. The other is its
-'subuname'. The subu_username is autogenerated. When using our tools, one
-never needs to know the subu_username. However, the entry in /etc/passwd will be
-the generated name, and the home directory will have the generated name. The
-command 'subu-username subuname' will print the subu_username.
-
-Each subu belongs to a master user, known as masteru. A given masteru may have many
-subus. The masteru is a different user than any of the subu's that are
-subservient to it.
-
-Each masteru has a top level subdirectory called 'subuland'. In this sub
-directory the masteru will find all of its subu home directories. The masteru
-will then see all subu owned files in the subuland through the illusion that the
-masteru owns them rather than the corresponding subu. Thus the master may move
-files around using a regular file navigator.
-
-Actually the subus will not appear in subuland until masteru runs the command
-'subu-mount'. This is normally done when masteru logs in.
-
-The masteru may create and delete subus at will. The masteru may set default
-nice values, renice, or kill subu processes. The masteru may set limits for a
-subu. In fact, the masteru is a bit like root relative to its subus.
-
-There is a control panel that masteru may use. It has a matrix of rectangles,
-where in each rectangle, there is information about each subu's processes and
-disk usage.
-
-The masteru may set the subu for each launched process.
-
----
-subu-username
-
-prints the username
-returns an error code
-
----
-subu-number
-
-prints a new maximums subu number.
-returns an error code
-
-These numbers are used in synthesizing usernames. Used for testing, should not
-appear in any scripts.
-
----
-subu-mount
-
-mounts all of the subus for the given masteru
-returns an error code
-
----
-subu-mk-0
-
-primitve makes a new subu
-returns an error code
-
----
-subu-rm-0
-
-primitive removes a subu
-returns an error code
diff --git a/document/subu_as_group.txt b/document/subu_as_group.txt
deleted file mode 100644
index 46da5b9..0000000
--- a/document/subu_as_group.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-
-note the 'ownerhips flaw' in subu-mk-0.txt. Could groups help with this?
-
-Suppose that instead of creating the subu as a separate user, it is created as a group. Masteru then has a
-number of separate groups. To run a process as the subu, the uid is set to the masteru, and the gid is set
-to the subu. .. but then the process would be able to modify anything owned by masteru
-
-suppose subu belongs to masteru's group .. then all subus are the same and can write each other's data.
-
-suppose masteru belongs to subu's group .. subu is still its own unique user, so it can change group permissions
-on files it makes and lock masteru out.
-
-suppose there is a unique third party, the mediator. Both masteru and subu belong to its group. A
-processes running as subu can only create files in directories that have mediator group permissions. subu still
-owns the files and directories it creates, so ..
-
-suppose the group sticky bit is set. The subu must belong to the group to write anything in the directories.
-Anything it writes are owned by the group. Suppose masteru is also in the this group. Though a mean subu
-could not take away the group ownership, it could
-
-
-
diff --git a/document/todo.txt b/document/todo.txt
deleted file mode 100644
index b28b04f..0000000
--- a/document/todo.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/document/try.txt b/document/try.txt
deleted file mode 100644
index c157aee..0000000
--- a/document/try.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-
-sudo_leak_script - demonstrates script injection through the pompt environement variable
-SUDO_USER - shows that userland scripts can trick other scripts into believing they are running under sudo.
-print_env.py - prints getuid, geteuid, some other info, and the value of each environment variable
-libuser - try out libuser
diff --git a/document/usb.txt b/document/usb.txt
deleted file mode 100644
index 4e62275..0000000
--- a/document/usb.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-added file /etc/udev/rules/50-usb-scale.rules
-SUBSYSTEM=="usb" ,ATTR{idVendor}=="1d50" ,ATTR{idProduct}=="60fc" ,MODE="0666" ,OWNER="Thomas-Internet"
-
-SUBSYSTEM=="usb" \
-,ATTR{idVendor}=="1d50" \
-,ATTR{idProduct}=="60fc" \
-,MODE="0666" \
-,OWNER="Thomas-Internet"
-
-
-udevadm control --reload-rules
-udevadm control --reload-rules && udevadm trigger
-
-systemctl status systemd-udevd
-
-firefox can find the usb hardward key with these settings, google-chrome can not.
diff --git a/document/video.txt b/document/video.txt
deleted file mode 100644
index e60e4f0..0000000
--- a/document/video.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-user must be in group video
-
-I added 666 permissions to udev for the USB camera but doubt this
-is needed.
-
diff --git a/executable/subu b/executable/subu
deleted file mode 100755
index f601bb6..0000000
--- a/executable/subu
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/bash
-#
-
-# to make audio work will need to do this:
-# > sudo dnf install pulseaudio-utils
-# > pactl load-module module-native-protocol-tcp
-# To load a specific module to the PA server, you add it to /etc/pulse/default.pa:
-# I created the file because it was not there...
-
-#set -x
-
-subu=$1
-stem=$2
-
-
-if [ ! -x "/usr/local/bin/user-stem" ]; then
- echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
- exit 1
-fi
-
-if [ -z "$subu" ]; then
- echo "no subuser name supplied"
- exit 1
-fi
-
-machine="$(hostname)"
-xkey=$(xauth list | grep "$machine" | head -1 | awk '{print $3}')
-
-if [ -z "$xkey" ]; then
- echo "xauth key not found"
- exit 1
-fi
-
-# stem includes all characters up to the first '-'
-if [ -z "$stem" ]; then
- stem=$(/usr/local/bin/user-stem)
-fi
-
-subu_username="$stem-$subu"
-subu_user_directory=/home/"$stem"/"$subu"/user
-bashrc="$subu_user_directory/.bashrc"
-xauthority="$subu_user_directory/.Xauthority"
-
-read -r -d '' script0 <<-EOF
- cd "$subu_user_directory" \
- ;export DISPLAY=$DISPLAY \
- ;export NO_AT_BRIDGE=1 \
- ;export PULSE_SERVER=localhost \
- ;touch "$xauthority" \
- ;xauth add "$DISPLAY" . "$xkey" \
- ;gnome-terminal --title="$subu"
-EOF
-
-
-sudo su -l "$subu_username" -c "$script0"
-
-#just hangs
-#sudo -u "$subu_username" sh -c "$script0"
-
-#set +x
diff --git a/executable/subu_add b/executable/subu_add
deleted file mode 100755
index 74ec8f5..0000000
--- a/executable/subu_add
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-# must have commands rsync and user-stem
-# user-stem is in the system repo
-#
-# wish we could set the uids and gids so that backups would restore properly on other systems but it is too much trouble
-# to do in a shell script. Perhaps in the python code for the actual release.
-
-subu=$1
-stem=$2
-
-if [ ! -x "/usr/local/bin/user-stem" ]; then
- echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
- exit 1
-fi
-
-if [ -z "$subu" ]; then
- echo "no subuser name supplied"
- exit 1
-fi
-
-# stem includes all characters up to the first '-'
-if [ -z "$stem" ]; then
- stem=$(/usr/local/bin/user-stem)
-fi
-
-subu_username="$stem-$subu"
-admin_username="$stem-admin"
-
-subu_home="/home/$stem/$subu"
-subu_user="$subu_home"/user
-
-admin_root="/home/$stem/admin"
-subu_initial_files="$admin_root"/user/library/subu_initial_files
-
-sudo useradd --home-dir "$subu" "$subu_username"
-sudo usermod -aG "$subu_username" "$admin_username"
-
-if [[ ! -d "$subu_user" ]]; then
- sudo mkdir "$subu_user"
- chown "$subu_username":"$subu_username" "$subu_user"
-fi
-
-subu_initialize subu stem
-
diff --git a/executable/subu_del b/executable/subu_del
deleted file mode 100755
index a8a7efd..0000000
--- a/executable/subu_del
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/bin/bash
-# must have command user-stem
-# user-stem is in the system repo
-#
-# currently this is setup to be run by any user who has sudo - it doesn't have to be run by the user-admin account; though chances are it will be.
-#
-# userdel -r deletes both the /var/spool/mail/user and the user's home directory. We don't want to delete the old data just in case there
-# is something important there. However we can not leve the old /var/spool/mail/user file under /var/spool/mail in case another subu is
-# created later with the same name. Hence we will move the /var/spool/mail/user file into the users home directory. We will give ownership
-# of the old home directory to the admin.
-#
-# I have run into a problem that subu users do not inherit the MAIL variable, I wouldn't trust it anyway. I do not know if userdel -r
-# references the MAIL variable. I will hard code a local variable to /var/sppol/mail. This must be changed for systems that put the mail spool
-# file eleswhere.
-#
-#set -x
-
-subu=$1
-stem=$2
-
-if [ ! -x "/usr/local/bin/user-stem" ]; then
- echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
- exit 1
-fi
-
-if [ -z "$subu" ]; then
- echo "no subuser name supplied"
- exit 1
-fi
-
-# stem includes all characters up to the first '-'
-if [ -z "$stem" ]; then
- stem=$(/usr/local/bin/user-stem)
-fi
-
-subu_username="$stem-$subu"
-admin_username="$stem-admin"
-subu_home="/home/$stem/$subu"_root
-archive_suffix=";1"
-archive_home="$subu_home$archive_suffix"
-mail_source_dir="/var/spool/mail"
-mail_source_file="$mail_source_dir/$subu_username"
-mail_target_file="$subu_home/mail_spool"
-
-if [ -e "$archive_home" ]; then
- echo "there is already a saved directory for a deleted subu with this name, move this out of the way first: $archive_home"
- exit 1
-fi
-if [ ! -d "$mail_source_dir" ]; then
- echo "could not find mail spooler directory: $mail_source_dir"
- exit 1
-fi
-
-if [ -e "$mail_target_file" ]; then
- echo "there is already file system object where we planned to move the deleted user's mail spool, which is here: $subu_home/mail_spool"
- exit 1
-fi
-
-sudo killall --signal 5 --wait --user "$subu_username"
-sudo mv "$mail_source_file" "$mail_target_file"
-sudo chmod -R go-rwx "$subu_home"
-sudo chown -R "$admin_username":"$admin_username" "$subu_home"
-mv "$subu_home" "$archive_home"
-sudo groupdel -f "$subu_username"
-sudo userdel "$subu_username"
-
-#set +x
diff --git a/executable/subu_initialize b/executable/subu_initialize
deleted file mode 100755
index 7f18038..0000000
--- a/executable/subu_initialize
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-# symbolic links made this complicated
-#set -x
-
-subu=$1
-stem=$2
-
-if [ ! -x "/usr/local/bin/user-stem" ]; then
- echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
- exit 1
-fi
-
-if [ -z "$subu" ]; then
- echo "no subuser name supplied"
- exit 1
-fi
-
-# stem includes all characters up to the first '-'
-if [ -z "$stem" ]; then
- stem=$(/usr/local/bin/user-stem)
-fi
-
-subu_username="$stem-$subu"
-subu_home="/home/$stem/$subu"
-subu_initial_files="/home/$stem/subu_initial_files"
-
-# install always derefs sym links ... actually it didn't work at all here
-#shopt -s dotglob
-#sudo install -o "$subu_username" -g "$subu_username" -t "$subu_home" "$subu_initial_files"/*
-
-# free a brief moment, files that appear in the initial subu will have their subu_initial
-# ownership instead of being owned by the subu
-#find "$subu_initial_files" -mindepth 1 -exedir copy({}
-# -execdir cp -a {} "$subu_home" \; \
-# -execdir chown -h "$subu_username":"$subu_username" "$subu_home"/{} \;
-# cp --remove-destination -RP "$1" "$2"
-
-function copy {
- s0="$1"
- filename="${s0:2}"
- destination_directory="$2"
- username="$3"
-
- source_directory=$(pwd)
- source_path="$source_directory"/"$filename"
- destination_path="$destination_directory"/"$filename"
- echo "ln -fs" "$source_path" "$destination_path"
- #ln -f did work when the existing object was a file rather than anotehr link so ..
- rm -f "$destination_path"
- ln -s "$source_path" "$destination_path"
- chown -h "$username":"$username" "$destination_path"
-}
-export -f copy
-
-find "$subu_initial_files" -mindepth 1 -execdir \
- bash -c 'copy "$1" "$2" "$3"' _ {} "$subu_home" "$subu_username" \;
-
-
-#set +x
diff --git a/makefile b/makefile
deleted file mode 100755
index 01d6747..0000000
--- a/makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-
-# nice idea, but the modules have to be made in the correct order, perhaps run this to check the module list
-# MAKEABLE= $(shell find module tool -name 'makefile' | grep -v deprecated)
-
-CLEANABLE=\
- module/da\
- module/da/test\
- module/tranche\
- module/debug\
- module/dispatch\
- module/subu-0
-
-MAKEABLE=\
- module/da\
- module/da/test\
- module/tranche\
- module/debug\
- module/dispatch\
- module/subu-0
-
-
-.PHONY: all
-all:
- for dir in $(MAKEABLE); do make -C $$dir dist-clean dep lib exec share || true; done
-
-.PHONY: info
-info:
- @echo "MAKEABLE:" $(MAKEABLE)
-
-.PHONY: setup
-setup:
- for dir in $(MAKEABLE); do make -C $$dir setup || true; done
-
-.PHONY: dep
-dep:
- for dir in $(MAKEABLE); do make -C $$dir dep || true; done
-
-.PHONY: update
-update:
- for dir in $(MAKEABLE); do make -C $$dir lib exec share || true; done
-
-.PHONY: clean
-clean:
- for dir in $(CLEANABLE); do make -C $$dir clean || true; done
-
-.PHONY: dist-clean
-dist-clean : clean
- for dir in $(CLEANABLE); do make -C $$dir dist-clean || true; done
- for i in $(wildcard module/share/lib/*); do rm $$i; done
- for i in $(wildcard module/share/inc/*); do rm $$i; done
- for i in $(wildcard module/share/bin/*); do rm $$i; done
-
-
-
-
-
diff --git a/module/da/doc/Acc.txt b/module/da/doc/Acc.txt
deleted file mode 100644
index 24ae5ba..0000000
--- a/module/da/doc/Acc.txt
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-Memory accounting.
-
-----------------------------------------
-Objectives:
-
-1) to detect memory leaks
-2) to help identify the source of memory leaks
-3) to provide useful information during debug sessions
-
-Initially considered making a tool that would work with source code that was unaware of
-Acc. This is no longer an objective. Consequently it is acceptable that source code
-must be modified. Possible examples include having to use a special version of malloc
-and free, and/or having to add small amounts of overhead code.
-
-----------------------------------------
-Requirements:
-
-1. To be able to turn accounting off and thus to minimize its impact. It is acceptable
-that doing so requires a second compile.
-
-2. For specific groups of functions to be able to be tracked independently, or
-not at all.
-
-3. For specific callers to be tracked separately or not at all.
-
-----------------------------------------
-Requirements Use Case Examples:
-
-Requirement 2, Use Case 1: Say there is a dynamic array and a dynamic tree structures which both make
-use of malloc and free. Then malloc/free balance for the dynamic array is reported
-separately than that for the dymaic tree.
-
-Requirement 3, Use Case 1 A dyamic array called from user code should be accounted for, while
-a dynamic array used for the accounting code itself does not.
-
-Requirement 3, Use Case 2 Say that a dyamic array is used by a dynamic tree. This dynamic array should
-be tracked separately from other dynamic arrays. Perhaps it is tracked as part of the rest of
-the tree code, or perhaps it is tracked as part separately from both the rest of the array and tree.
-
-----------------------------------------
-Proposed 'Channel Architecture'
-
-1. Channels are created with an open call, and are retired with a close
-call. Channels might be structs, or integers, etc. (enum tags) (changed name from handles to
-channels to be suggestive of the integer impelementation)
-
- Acc handle;
- acc_open(handle);
-
- or perhaps
-
- Acc handle = acc_open();
-
- also then
-
- acc_close(handle);
-
-2. channel_NULL, means that no accounting should be done
-
-3. dynamic structures are given and keep a copy of the memory accounting channel
-they are initialized with. Integer (enum) handles are an advantage here as they are
-small. (add another field to the da struct for the accounting channel)
-
-Specifically, da_init (was da_alloc) would take a handle operand.
-
-So something like:
-
- Acc acc_channel = acc_open("Data Structure Martyrs");
- Da x;
- da_init(x, acc_channel);
- .. .. lots of code, possible many acc_report(channel) calls ..
- acc_report(acc_channel);
- acc_close(acc_channel);
-
-A dynamic array is initialized with da_init, and the handle is written to a
-field in the Da struct. da_init should accept a memory accounting channel
-number. Constituent acc_malloc and acc_free calls in the dynamic array are
-given the handle, copied in from the Da struct value.
-
- acc_malloc(size, channel);
- acc_free(pt, channel)
-
-4. acc_malloc keeps a list of pointers it allocates, say acc_malloc_list[channel]
-5. acc_free(pt) removes pt from the acc_malloc_list, if not found adds it to the acc_spurious_free list[channel]
-
-6. each channel is associated with a mode of accounting. There are currently three modes:
- 0) do nothing 1) count balance only 2) full pointer accounting Chances are for debugging
- the user will want mode 2. For non critical code it make sense to run in mode 1. For
- performance critical code, run in mode 0. Want a switch to turn it all off globally (no header hacks)
-
- The default is no accounting.
-
-Modes: enum with mode options, stored in array (not a da array)
--just tells how to run report, is not scope, channels are scope
-
-7. acc_report pretty prints the list of values on the outstanding malloc and spurious free lists,
-if not too many. If too many then it reports a count.
- Modes tell how to run: Option 1: just true or false Option 2: give me something reasonable (like above) 3: count 4: pointers
-
-8. the header file redefines malloc to something that prints to stderr a warning when called, but only does
-so one time (not every time it is called). same for free. #define malloc crash_and_burn
-
-----------------------------------------
-How the proposed architecture meets requirements
-
-1. requirement 1 is achieved by architecture 6. as all channels may be turned off.
-
-2. requirement 2 is achieved by giving all acc_alloc, and acc_free members of a group
-the same channel. In the case of Da this is achieved by putting the channel in the Da struct,
-and then all routines referencing the struct.
-
-3. requirement 3. consider the use case, that of a Da (dynamic array) and a Dt (dyamic tree).
- The dynamic tree uses a Da, and when it calls da_init it gives the Da a different channel
- than the channels used by others. If the Da is to be tracked along with the rest of the tree.
- Suppose the tree is created with dt_init(tree_channel), then internally the tree creates the
- arrays it uses as da_init(tree_channel) also. Then they track together.
diff --git a/module/da/doc/acc_usermanual.txt b/module/da/doc/acc_usermanual.txt
deleted file mode 100644
index 9824353..0000000
--- a/module/da/doc/acc_usermanual.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Explanation of process for using accounting code.
-
- First,
- AccChannel acc_live_channels; needs to be declared at global scope in the CLI file.
- acc_open(&acc_live_channels, mode); needs to be called in main.
- ---acc_NULL or acc_SELF only, decide whether to track memory allocation for channels themselves
-
- To begin an accounting channel, declare an Acc_channel and initialize it by passing a pointer to it into acc_open. You will also need to pass in a Mode.
-
--acc_NULL does not track
--acc_BALANCE will give you a count of outstanding mallocs and spurious frees when reported
--acc_FULL will give you a robust accounting with a list of up to 10 outstanding/spurious pointers, then it will default to a count instead and just give the first 10 addresses.
--acc_SELF is solely for the accounting software to account for its own memory allocation, therefore listing outstanding/spurious pointers to Acc_channels in the same format as acc_FULL.
-
- When initializing a Da, you must pass in a pointer to the Da, its element size, and a pointer to the (already initialized) Acc_channel on which it will be stored into da_init. Among its other initialization tasks, this function will call acc_malloc for the base pointer of the Da with the appropriate channel.
- When allocating memory for anything else in the program, you must pass the size of the memory to be allocated as well as the channel on which it is to be tracked to acc_malloc.
-
- To free a Da, pass a pointer to the Da into da_free. It will automatically call acc_free for the base pointer, set the size to 0 and set the channel to NULL.
- To free anything other else in the program, simply call acc_free, passing in the pointer and the channel the pointer is being tracked in. This will zero it out from the channel, call da_pts_nullify to clean up any zeroes at the end of the channel, and then free the pointer.
-
- To find out if there are any memory leaks in a particular channel, call acc_report with a pointer to the Acc_channel as the argument. Depending on the channel's mode, it will pretty print a current report of memory allocation and frees. If you call a report on acc_live_channels and it is set to Mode acc_SELF, it will report on the memory currently in use for the accounting system itself.
-
- When finished with a channel, call acc_close and pass in the channel pointer. This will free up the memory used by it and remove it from the acc_live_channels outstanding_malloc list if there is SELF tracking on. Any allocation information being tracked by this channel will be lost, so it is advised to call acc_report before deciding whether to free the channel.
diff --git a/module/da/doc/da_lib_doc.txt b/module/da/doc/da_lib_doc.txt
deleted file mode 100644
index a98f53c..0000000
--- a/module/da/doc/da_lib_doc.txt
+++ /dev/null
@@ -1,125 +0,0 @@
-Explanations of primary goals and step-by-step actions of each function in da.lib.c.
-
-Currently needs editing because descriptions based on old functions. So, some are not up to date or even no longer existent.
-
-/*
-void da_alloc - The primary goal of this function is to allocate the initial Da in memory and assign the appropriate pointers that correspond. It is much like an initializer in a class. It makes an array large enough to hold 4 elements of the element size passed in as an argument.
-- This function takes a Da pointer called dap and a size_t called element_size.
-- It dereferences the Da pointer and assigns the value of the argument element_size to the element_size size_t variable in the Da.
-- Then it assigns 4 times the value of the argument element_size to the size size_t variable in the Da, thereby making the size of the array to be created large enough to hold 4 elements.
-- Then it uses malloc to allocate an array in memory of this size and pointed to by dap and assigns the pointer to the first element in the array to the char pointer labeled base in the dap Da.
-- Then it assigns the same address to the end pointer. This is just to start off, as the end pointer will be advanced as elements are inserted.
-
-void da_free - The primary goal of this function is to "free" the space in memory where the Da whose pointer is passed in is located. It does not actually delete the data in that location, but frees the memory to be reused by removing the tie between the address and the pointer and removing the span of memory assigned to the Da by setting its size to zero.
-- This function takes a Da pointer called dap.
-- It calls the C function free and passes it the base pointer (which has been assigned the address of first element in the array) of the Da.
-- Then it assigns the size variable in the Da the value of 0.
-
-void da_rewind - The primary goal of this function is to start over in inserting elements in this array. It "rewinds" the end pointer to the base so that, while it does not actually erase the data at those locations in memory, it acts as if there is nothing in the array. New elements will be inserted starting at the base again, overwriting whatever old data was there.
-- This function takes a Da pointer called dap.
-- It takes the value of the base variable of dap and assigns it to the end variable of dap.
-
-bool da_empty - The main goal of this function is to test whether a Da is empty. It will return true if there are no elements in the array and false if there are. For example, it should return true for a brand new Da or for one that has been rewinded, but not for one whose end pointer has moved due to element insertion.
-- This function takes a Da pointer called dap.
-- If the end pointer of dap is the same as the base pointer of dap, the function will return true (as a bool).
-
-size_t da_length - The primary goal of this function is to report how many elements are currently store in a Da.
-- This function takes a Da pointer called dap.
-- It returns the result of an operation that divides the distance from the end pointer to the base pointer of dap by its element size.
-
-void da_rebase - The primary goal of this function is to redirect pointers that previous pointed into a Da to the new location of the array after it has been doubled.
-- This function takes a Da pointer called dap, a char pointer called old_base (presumably the old base pointer from an expanded array), and a void pointer called pta.
-- It initializes a char pointer to a pointer called pt with a value of the pointer to the pointer to the void pointer pta. This would be like having a 2D array pointer because it points to the first element in an array of pointers. The pta would be a pointer to some other thing that had been making reference to dap before it was expanded and needs to be re-pointed into the new position of dap in memory.
-- It initializes a size_t variable called offset with a value of the difference between the pointer to the array pointer pt and the old_base passed in.
-- Then it assigns the pointer to pt with the sum of the base pointer of dap (presumably the new base after an expansion) and the offset.
-
- char *da_expand - The primary goal of this function is to double the size of the array. It saves and "returns the old base so that existing pointers into the array can be moved to the new array" later. It doubles the size by allocating a new array with size of the variable new_size and copies the old data into it via memcpy with the old base, the end_offset it took from the old Da, and the corresponding element size. Then it frees the old pointer and reassigns all the variables and pointers to the newly allocated values.
-- This function takes a Da pointer called dap.
-- It initializes a size_t variable, declaring it to be named end_offset and assigning it the value of the difference between the pointer to the end of dap and the pointer to the base of dap, aka the current offset of the end pointer.
-- Then it initializesa char pointer called old base with value of the current address of the base of dap.
-- Then it initializes a size_t variable called new_size with the value of the size of dap multiplied by 2 (via left-shift 1, << 1).
-- Then it initializes a char pointer called new_base to a newly allocated array of the new size via the malloc C function.
-- It uses memcpy to copy the data from dap to the new Da by taking all the data withing the range from the old base to the end of the determined by the end offset and the element size of dap.
-- It calls the C function free to deallocate the old base pointer.
-- It changes the base pointer of dap to new_base and the end pointer of dap to where it is offset after the already inserted data.
-- It changes the size variable of dap to new_size.
-- It returns the old_base char pointer.
-
-**** No longer in code.
-bool da_endq -The primary goal of this function is to assure the pointer passed in has not "run off the end of the area currently allocated for the array," that is to say, the end of the data currently contained by the Da, the current address given by the end pointer.
-- This function takes a Da pointer called dap and a void pointer called pt.
-- It returns (bool) true if the char pointer passed in (pt) is greater than or equal to the end pointer of the Da.
-****
-
-bool da_boundq - The primary goal of this function is to assure that the end pointer has not "run off the end of the area allocated for the array," that is to say, the total area allocated for the container at full capacity.
-- This function takes a Da pointer called dap.
-- It returns true if the address referenced by the end pointer of dap is greater than the address reached by adding the size of dap to its base pointer, the address of its first element.
-
-char *da_index - The main goal of this function is to locate a specific element within a Da by creating a pointer that is offset from the base to that element number's worth of element_sizes of data. This way we can put and take items directly from the list without moving the end pointer.
-- This function takes a Da called dap and a size_t called i.
-- It initializes a size_t called offset as i times the element size of dap.
-- It initializes a pointer called pt as the base of dap plus offset.
-- It returns the pointer pt.
-
-void da_push_alloc
-- This function takes a Da called dap.
-- It initializes a size_t called element_off as the difference between the end and base pointers of dap.
-- It adds one dap element_size's worth to the address of the end pointer of dap.
-- It then expands if the end pointer has run off the end of the currently allocated space for dap.
-- It returns a pointer to the address element_off's worth past the base of dap.
-
-void da_push - The primary goal of this function is to push elements into the array. It doubles the array if necessary, copies the information from the source, and moves the end pointer accordingly.
-- This function takes a Da pointer called dap and a void pointer called element.
-- If the end pointer is past the allocated size for the array, it doubles the array with da_expand.
-- It copies the information at the address of element (of the size of the element size of Da) at the location of the end pointer.
-- It then moves the end pointer of dap one element_size worth farther in memory.
-
-bool da_pop - The primary goal of this function is to pop the end pointer of a Da back one element. It takes precaution to ensure it will only go to the base of the Da. It returns a flag to confirm that a pop was performed. And it copies the information from the "deleted" element of the Da into an element pointer, if one was passed in.
-- This function takes a Da pointer called dap and a void pointer called element.
-- It flags (true bool) if the end pointer of dap is farther than one element_size past the base of dap. This ensures that there is actually somewhere to pop from and we won't be popping out of the allocated range of the Da.
-- If true, it removes one dap element_size worth's from the address of dap's end pointer. Then if there is an element pointer, it copies one element_size worth of data starting at the new end pointer into the address of element.
-- It returns the flag bool value to confirm whether or not a pop was performed.
-
-void da_map - The primary goal of this function is to create closure for the Da. It takes the results of functions for all the elements of a Da and copies them to a closure pointer to keep them at global scope even after exiting the namespace the function is in.
-- This function takes a Da pointer called dap, a pointer to a void function which takes two void pointers as arguments, and a void pointer called closure.
-- The arguments of f are intended to be an element pointer and another arg pointer.
-- It initializes a char pointer called pt with the address of the base pointer of dap.
-- As long as pt does not equal the end pointer of dap, it passes pt and closure as arguments to f (which is intended to be da_free_element as passed in by da_free_elements). Then it adds a dap element_size worth to the pt address.
-
-static void da_free_element - The primary goal of this function is to free up space taken by a Da becuase these lists "are sometimes used as resource managers." It is one substep in the process, which is used by the da_map function during a closure procedure to free up the pointer.
-- This function takes two void pointers called pt and closure as arguments.
-- It frees the memory at the address of pt.
-
-void da_free_elements - The primary goal of this function is to free up space taken by a Da because these lists "are sometimes used as resource managers." It is the main call for this function, sending the dap through the da_free_element function for every element and then rewinding the dap. This frees up the memory without deleting the Da itself.
-- This function takes a Da called dap as an argument.
-- It sends the dap pointer, the function da_free_element and the closure pointer of NULL to da_map.
-- It then sends dap to da_rewind.
-
-char *da_fgets - The primary goal of this function is to put text from a file into a dap, line by line, but not endlines of EOF. It preserves the old base, because da_push function will expand the Da if need be, but if not, the base won't have changed. "Use feof(FILE *stream) to test for EOF;"
-- This function takes a Da called dap and a FILE called fd as arguments.
-- It initializes a char pointer called old_base with the address of the base of dap.
-- It initializes an int called c with the value returned by running fd through the fgets C function.
-- As long as c is neither an EOF (end of file) character nor an endline character, it pushes c onto the dap list. Then it copies the result of fgetc(fd) into c again and continues.
-- It initializes an int called terminator with the value 0.
-- It pushes the terminator onto the dap.
-- This function returns the char pointer old_base "so that external pointers can be rebased" in the future.
-
-void da_ints_print
-- This function takes
-
-
-void da_cat - The primary goal of this function is to concatenate the contents of one array onto another. It adds it right to the end of where the last started, doubling if need be. "If dap0 has had a terminatating zero added, that must be popped off before the call. Similarly if a terminating zero is desired, it should be pushed after the call."
-- This function takes two Da pointers called dap0 and dap1 as arguments.
-- It returns if the end pointer of dap 1 already points to the same address as the end pointer of dap0. This prevents redundant concatenation.
-- It initializes a size_t called dap0_size with the difference between the end and base of dap0, then does the same thing for dap1.
-- It adds the size of dap1 to the end pointer of dap0.
-- If the end pointer of dap0 has now run off the edge of dap0's allocated size, it expands/doubles dap0 to accomodate.
-- It copies the contents of dap1 into dap0 starting dap0_size away from the base of dap0 (where the old end pointer would've been).
-
-
-
-
-*/
-
-
-
diff --git a/module/da/doc/todo_glenda.txt b/module/da/doc/todo_glenda.txt
deleted file mode 100644
index 4c270ff..0000000
--- a/module/da/doc/todo_glenda.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-
-2019-04-19T09:34:21Z
-
-da_erase ; same as da_free, don't tell anyone
-
-da_integer_repeats ; all items in the array are equal
-da_integer_sum ; sum all elements
- da_integer_transpose ; matrix transpose
-da_integer_repeats_column ; all columns are equal
-
-da_every_column ; like every but for columns instead of elements
-da_every_row ; like every but for rows
-
-
-
-
-
-da_push_row ; push rows/vectors/das onto dama
-da_integer_repeats_row ; transpose and call repeats column
-
-
-transpose needs to output a DaMa, not a raw image matrix, though it can use one to get there if need be
-
-then add integer repeats row which will use transpose and column repeats to do its job
-
-then add da_push_row to add Das to DaMa
-
-then test starting with helper functions
-
-
-
-
-got through each row and push values onto columns or vice versa?
-how to construct new Da's
-how to fill - integers only?
-
-
---------------------
-
-here, change da_exists to return a pointer to the element, or a NULL pointer (NULL being false, doesn't exist)
-
-you will need the da_pts_exists version that returns a pointer so that you can search the malloc list to find freed pointers
-
-I also added da_pts_nullify, to set a pointer to zero, then to pop NULL pointers from the top of the stack. You will want that to set the malloc poniters to NULL when there is a match with a free pointer, so that the array will contract. using da_pts_nullify at the end, if there are no memory leaks the malloc array will be empty
diff --git a/module/da/include/acc.h b/module/da/include/acc.h
deleted file mode 100644
index cd90111..0000000
--- a/module/da/include/acc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ACC_LIB_H
-#define ACC_LIB_H
-
-#include
-#include
-#include
-#include
-
-#define malloc crash_and_burn_malloc
-#define free crash_and_burn_free
-
-typedef struct AccChannel_struct AccChannel;
-typedef struct Da_struct Da; // Da_struct defined in da.lib.h
-
-enum Mode_enum{acc_NULL = 0, acc_BALANCE = 1, acc_FULL = 2, acc_SELF = 3};//0,1,2,3
-typedef enum Mode_enum Mode;
-
-struct AccChannel_struct{
- Da *outstanding_malloc;
- Da *spurious_free;
- Mode mode;
-}; //name instances of channels with handles
-
-//function declarations for accounting
- AccChannel *acc_open(AccChannel *channel, Mode mode);//initializes channel structs
- void *acc_malloc(size_t size, AccChannel *channel);//works for things besides Das too
- void acc_free(void *pt, AccChannel *channel);//works for things besides Das too
- AccChannel *acc_report(AccChannel *channel);//reports on channels based on mode
- void acc_close(AccChannel *channel);//frees channel itself
-
- void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
- void crash_and_burn_free(void *);// sends error message in case of accidental regular free
-
-
-#endif
diff --git a/module/da/include/da.h b/module/da/include/da.h
deleted file mode 100644
index 3611064..0000000
--- a/module/da/include/da.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef DA_LIB_H
-#define DA_LIB_H
-#include
-#include
-#include
-#include
-
-typedef struct AccChannel_struct AccChannel; // AccChannel_struct defined in acc.lib.h
-typedef struct Da_struct Da;
-
-struct Da_struct{
- char *base;
- char *end; // one byte/one element off the end of the array
- size_t size; // size >= (end - base) + 1;
- size_t element_size;
- AccChannel *channel;//assign during init, set to NULL during free
-};
-
-// constructors / destructors
-//
- Da *da_init(Da *dap, size_t element_size, AccChannel *channel);//calls da_malloc for base pointer
- void da_free(Da *dap);
- void da_rewind(Da *dap);
- void da_rebase(Da *dap, char *old_base, void *pta);
- char *da_expand(Da *dap);
- bool da_boundq(Da *dap);
- void da_erase(Da *dap);
-
-// status / attributes
-//
- bool da_is_empty(Da *dap);
- bool da_equal(Da *da_0, Da *da_1);
- size_t da_length(Da *dap);
- bool da_length_equal(Da *dap0, Da *dap1);
-
-// accessing
-//
- char *da_index(Da *dap, size_t i);
- char *da_push(Da *dap, void *element);
- bool da_pop(Da *dap, void *element);
-
-// iteration, f is given a pointer to an element and a pointer to the closure
- bool da_endq(Da *dap, void *pt);
- bool da_right_bound(Da *dap, void *pt);
- void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
- bool da_exists(Da *dap, bool f(void *, void*), void *closure);
- bool da_all(Da *dap, bool f(void *, void*), void *closure);
-
-// elements are pointers
-// would be better if exists returned NULL or a pointer to the existing element-
- void *da_pts_exists(Da *dap, void *test_element);
- void da_pts_free_all(Da *dap); // calls free on all elements
- void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
-
-// elements are integers
- void da_ints_print(Da *dap, char *sep);
- bool da_integer_repeats(Da *dap);
- int da_integer_sum(Da *dap);
-
-// the array itself is a string
-// careful if you add a null terminator it will become part of the da_string, affects iteration etc.
- char *da_string_input(Da *dap, FILE *file);
- void da_string_push(Da *dap0, char *string);
- void da_cat(Da *dap_base, Da *dap_cat);
-
-// when the array holds pointers to C strings
- void da_strings_print(Da *dap, char *sep);
- bool da_strings_exists(Da *string_arrp, char *test_string);
- void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
- void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
-
-#endif
-
diff --git a/module/da/lib/libda.a b/module/da/lib/libda.a
deleted file mode 100644
index 137836b..0000000
Binary files a/module/da/lib/libda.a and /dev/null differ
diff --git a/module/da/makefile b/module/da/makefile
deleted file mode 100644
index 85a407e..0000000
--- a/module/da/makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-# da/
-
-SHELL=/bin/bash
-MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
-#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
--include makefile-flags
-
-.PHONY: all
-all: version
-
-.PHONY: dep
-dep:
- if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
- $(MAKE) $@
-
-.PHONY: lib
-lib:
- cp $(SRCDIR)/da.lib.h $(INCDIR)/da.h
- cp $(SRCDIR)/acc.lib.h $(INCDIR)/acc.h
- $(MAKE) $@
-
-.PHONY: exec
-exec:
- $(MAKE) $@
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/da/makefile-flags b/module/da/makefile-flags
deleted file mode 100644
index 308602e..0000000
--- a/module/da/makefile-flags
+++ /dev/null
@@ -1,30 +0,0 @@
-
-MODULE=da
-
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
-SRCDIR=src
-TESTDIR=test
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-cc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# compiler and flags
-C=gcc
-CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB
-LINKFLAGS=-L$(LIBDIR) -l$(MODULE)
-
-
-
diff --git a/module/da/src/acc.lib.c b/module/da/src/acc.lib.c
deleted file mode 100644
index 37ba2f3..0000000
--- a/module/da/src/acc.lib.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-dynamic memory accounting
-
-*/
-
-
-#include "da.lib.h"
-#include "acc.lib.h"
-
-#undef malloc
-#undef free
-
-//-----------------------------------------------------------------
-//function definitions for accounting
-
-AccChannel *acc_open(AccChannel *channel, Mode mode){//acc init
- Da os; Da sf;
- channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
- channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
- channel->mode = mode;
- return channel;
-}
-void *acc_malloc(size_t size, AccChannel *channel){
- void *an_allocation_pt = malloc(size);
- if( channel ) da_push((Da *)(channel->outstanding_malloc), &an_allocation_pt);//tried taking out reference but fixed nothing
- return (void *)an_allocation_pt;
-}
-void acc_free(void *pt, AccChannel *channel){
- if( channel ){
- void **i = (void **)(((Da *)(channel->outstanding_malloc))->base);
- bool present = false;
- while( i < (void **)(((Da *)(channel->outstanding_malloc))->end) ){
- if( *i == pt ){//this is just da_exists, make it return a pointer
- da_pts_nullify((Da *)(channel->outstanding_malloc), i);
- present = true;
- }
- i++;
- }
- if( present == false ) da_push((Da *)(channel->spurious_free), &pt);
- }
- free(pt);
-}
-static void count_balance(void *element, void *closure){
- int *counter = (int *)closure;
- if( element ) (*counter)++;
-}
-static void acc_rep_helper_BALANCE(AccChannel *channel){
- int count = 0;
- da_foreach((Da *)channel->outstanding_malloc, count_balance, &count);
- printf("There are %d outstanding allocations.\n", count);
- int count1 = 0;
- da_foreach((Da *)channel->spurious_free, count_balance, &count1);
- printf("There are %d spurious frees.\n", count);
-}
-static void print_pointer(void *element, void *closure){
- if( element ) printf("%d ", *(int *)element);
-}
-static void acc_rep_helper_FULL(AccChannel *channel){
- printf("There are %d outstanding mallocs.\n", (int)da_length((Da *)(channel->outstanding_malloc)));
- printf("There are %d spurious frees.\n", (int)da_length((Da *)(channel->spurious_free)));
- /*if( 0 < count && count < 10 ){
- printf("The outstanding allocated pointers are: ");
- da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
- printf(".\n");
- }
- if( 0 < count && count < 10 ){
- printf("The spuriously freed pointers are: ");
- da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
- printf(".\n");
- }*/
-}
-AccChannel *acc_report(AccChannel *channel){
- if( channel->mode == acc_NULL ){
- printf("Accounting mode is NULL.\n");
- return channel;
- }
- if( channel->mode == acc_BALANCE ){
- printf("Accounting mode is BALANCE.\n");
- if( da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) ){
- printf("This channel is in balance.\n");
- }
- else{
- printf("This channel is out of balance.\n");
- acc_rep_helper_BALANCE(channel);
- }
- return channel;
- }
- if( channel->mode == acc_FULL ){
- printf("Accounting mode is FULL.\n");
- if( false ){
- printf("This channel is in balance.\n");
- }
- else{
- printf("This channel is out of balance.\n");
- acc_rep_helper_FULL(channel);
- }
- return channel;
- }
- if( channel->mode == acc_SELF ){
- printf("Accounting mode is SELF.\n");
- if( true/*da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) */){
- printf("There are no open channels.\n");
- }
- else {
- printf("The accounting code is out of balance.\n");
- acc_rep_helper_FULL(channel);
- }
- return channel;
- }
-}
-void acc_close(AccChannel *channel){
- da_free((Da *)(channel->outstanding_malloc));
- da_free((Da *)(channel->spurious_free));
- return;
-}
-
-void *crash_and_burn_malloc(size_t size){}
-void crash_and_burn_free(void *pt){}
-
diff --git a/module/da/src/acc.lib.h b/module/da/src/acc.lib.h
deleted file mode 100644
index cd90111..0000000
--- a/module/da/src/acc.lib.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ACC_LIB_H
-#define ACC_LIB_H
-
-#include
-#include
-#include
-#include
-
-#define malloc crash_and_burn_malloc
-#define free crash_and_burn_free
-
-typedef struct AccChannel_struct AccChannel;
-typedef struct Da_struct Da; // Da_struct defined in da.lib.h
-
-enum Mode_enum{acc_NULL = 0, acc_BALANCE = 1, acc_FULL = 2, acc_SELF = 3};//0,1,2,3
-typedef enum Mode_enum Mode;
-
-struct AccChannel_struct{
- Da *outstanding_malloc;
- Da *spurious_free;
- Mode mode;
-}; //name instances of channels with handles
-
-//function declarations for accounting
- AccChannel *acc_open(AccChannel *channel, Mode mode);//initializes channel structs
- void *acc_malloc(size_t size, AccChannel *channel);//works for things besides Das too
- void acc_free(void *pt, AccChannel *channel);//works for things besides Das too
- AccChannel *acc_report(AccChannel *channel);//reports on channels based on mode
- void acc_close(AccChannel *channel);//frees channel itself
-
- void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
- void crash_and_burn_free(void *);// sends error message in case of accidental regular free
-
-
-#endif
diff --git a/module/da/src/acc.lib.o b/module/da/src/acc.lib.o
deleted file mode 100644
index c3a1382..0000000
Binary files a/module/da/src/acc.lib.o and /dev/null differ
diff --git a/module/da/src/da.lib.c b/module/da/src/da.lib.c
deleted file mode 100644
index 5bca280..0000000
--- a/module/da/src/da.lib.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
-Dynamic Array
-
-Cannot expand an empty array.
-
-*/
-#include
-#include
-#include
-
-#include "acc.lib.h"
-#include "da.lib.h"
-
-//--------------------------------------------------------------------------------
-// constructors / destructors
-
-Da *da_init(Da *dap, size_t element_size, AccChannel *channel){
- dap->element_size = element_size;
- dap->size = 4 * element_size;
- dap->base = acc_malloc(dap->size, channel);
- dap->end = dap->base;
- dap->channel = channel;
- return dap;
-}
-void da_free(Da *dap){
- acc_free(dap->base, dap->channel);
- dap->size = 0;
- dap->channel = NULL;
-}
-void da_rewind(Da *dap){
- dap->end = dap->base;
-}
-void da_rebase(Da *dap, char *old_base, void *pta){
- char **pt = (char **)pta;
- size_t offset = *pt - old_base;
- *pt = dap->base + offset;
-}
-
-// Doubles size of of da. Returns old base, so that existing pointers into the
-// array can be moved to the new array
-char *da_expand(Da *dap){
- char *old_base = dap->base;
- size_t end_offset = dap->end - old_base;
- size_t new_size = dap->size << 1;
- char *new_base = acc_malloc(new_size, (AccChannel *)(dap->channel));
- memcpy( new_base, old_base, end_offset + dap->element_size);
- acc_free(old_base, (AccChannel *)(dap->channel));
- dap->base = new_base;
- dap->end = new_base + end_offset;
- dap->size = new_size;
- return old_base;
-}
-
-// true when end has run off the allocated area
-bool da_boundq(Da *dap){
- return dap->end > (dap->base + dap->size);
-}
-
-// erases all the elements in the array
-// a push followed by an erase should work, but I don't think it does right now
-/*
-void da_erase(Da *dap){
- da_free(Da *dap);
-}
-*/
-
-//--------------------------------------------------------------------------------
-// status / attributes
-
-bool da_is_empty(Da *dap){
- return dap->end == dap->base;
-}
-
-bool da_equal(Da *da_0, Da *da_1){
- return !bcmp(da_0, da_1, sizeof(Da));
-}
-
-size_t da_length(Da *dap){
- return (dap->end - dap->base)/dap->element_size;
-}
-
-bool da_length_equal(Da *dap0, Da *dap1){
- return da_length(dap0) == da_length(dap1);
-}
-
-
-//--------------------------------------------------------------------------------
-// accessing
-
-char *da_index(Da *dap, size_t i){
- size_t offset = i * dap->element_size;
- char *pt = dap->base + offset;
- return pt;
-}
-
-// allocate space for a new element at the end of the array
-static char *da_push_alloc(Da *dap){
- size_t element_off = dap->end - dap->base;
- //printf("help help help I'm melting!");
- dap->end += dap->element_size;
- if( dap->end > dap->base + dap->size ) da_expand(dap);
- return dap->base + element_off;
-}
-char *da_push(Da *dap, void *element){
- char *element_pt = da_push_alloc(dap);
- memcpy(element_pt, element, dap->element_size);
- return element_pt;
-}
-
-bool da_pop(Da *dap, void *element){
- bool flag = dap->end >= dap->base + dap->element_size;
- if( flag ){
- dap->end -= dap->element_size;
- if(element) memcpy(element, dap->end, dap->element_size);
- }
- return flag;
-}
-
-//--------------------------------------------------------------------------------
-// iteration
-
-// true when pt has run off the end
-bool da_endq(Da *dap, void *pt){
- return (char *)pt >= dap->end;
-}
-
-// array is a row of elements, pt points at the rightmost element
-bool da_right_bound(Da *dap, void *pt){
- return ((char *)pt + dap->element_size) >= dap->end;
-}
-
-// passed in f(element_pt, arg_pt)
-// We have no language support closures, so we pass in an argument for it.
-// The closure may be set to NULL if it is not needed.
-void da_foreach(Da *dap, void f(void *, void *), void *closure){
- char *pt = dap->base;
- while( pt != dap->end ){
- f(pt, closure);
- pt += dap->element_size;
- }
-}
-
-//â, OR map
-//---> should return the element pointer, same for da_pts_exists
-static bool da_quantifier(bool complement, Da *dap, bool pred(void *, void*), void *closure){
- char *pt = dap->base;
- bool result = !complement;
- while( (complement? !result : result) && (pt != dap->end) ){
- result = pred(pt, closure);
- pt += dap->element_size;
- }
- return result;
-}
-bool da_exists(Da *dap, bool pred(void *, void*), void *closure){
- return da_quantifier(true, dap, pred, closure);
-}//return pointer to thing it found that exists
-bool da_exception(Da *dap, bool pred(void *, void*), void *closure){
- return da_quantifier(false, dap, pred, closure);
-}//make return pointer to exception and NULL (pointer) if no exception
-
-
-
-
-
-
-//--------------------------------------------------------------------------------
-// elements are pointers
-// elements are pointers
-//
-static bool da_pts_exists_0(void *element, void *test_element){ return element == test_element; }
-void *da_pts_exists(Da *dap, void *test_element){
- if( da_exists(dap, da_pts_exists_0, test_element) ) return test_element;
- else return NULL; //if da_exists returns pointer, gets bool and pointer in one
-}
-/*
-static da_pts_exists_0(void *element, void *pt){ return element == pt; }
-bool da_pts_exists(Da *dap, void *test_element){
- return da_exists(dap, da_pts_exists_0, test_element);
-}
-*/
-// elements were allocated, now they will all be freed
-static void da_pts_free_all_0(void *pt, void *closure){
- acc_free(*(char **)pt, closure);
- // FREE(*(char **)pt); // FREE does not care about the pointer type
-}
-void da_pts_free_all(Da *dap){
- da_foreach(dap, da_pts_free_all_0, dap->channel);
- // da_map(dap, da_pts_free_all_0, NULL);
- da_rewind(dap);
-}
-
-// elements are pointers
-// ept points at an element, we set *ept to NULL
-// we pop all NULLs off the top of the stack
-void da_pts_nullify(Da *dap, void **ept){
- if(ept >= (void **)(dap->base) && ept < (void **)(dap->end)){
- // if(ept >= dap->base && ept < dap->end){
- *ept = NULL;
- }
- while(
- dap->end > dap->base
- &&
- // *(void **)(dap->end - dap->element_size) == NULL
- // ){
- *(void **)(dap->end - dap->element_size) == NULL){
- da_pop(dap, NULL);
- }
-}
-
-
-
-//--------------------------------------------------------------------------------
-// da is an array of integers
-
-// would like to pass in the printf format to make a general print
-// but can't get *pt on the stack for the printf call .. hmmm
-void da_ints_print(Da *dap, char *sep){
- char *pt = dap->base; // char * because it points to a byte in the array
- if( pt < dap->end ){
- printf("%u", *(int *)pt);
- pt += dap->element_size;
- while( pt < dap->end ){
- printf("%s%u", sep, *(int *)pt);
- pt += dap->element_size;
- }}}
-
-bool da_integer_repeats(Da *dap){//all items in the array are equal
- int n = *(dap->base);
- char *pt = dap->base + dap->element_size;
- bool flag = true;
- while( flag && pt != dap->end ){
- flag = *pt == n;
- pt+=dap->element_size;
- }
- return flag;
-}
-
-int da_integer_sum(Da *dap){//sum all elements
- char *pt = dap->base;
- int sum = 0;
- while( pt != dap->end ){
- sum += *(pt);
- pt+=dap->element_size;
- }
- return sum;
-}
-
-
-
-
-//--------------------------------------------------------------------------------
-// da is an array of strings
-
-// for the case of an array of strings
-void da_strings_print(Da *dap, char *sep){
- char *pt = dap->base; // char * because it points to a byte in the array
- if( pt < dap->end ){
- fputs(*(char **)pt, stdout);
- pt += dap->element_size;
- while( pt < dap->end ){
- fputs(sep,stdout);
- fputs(*(char **)pt,stdout);
- pt += dap->element_size;
- }}}
-
-// da is an array of strings, true if the test string is in the array
-// might be better to iterate instead of using a map ...
-typedef struct {
- char *string;
- bool found;
-} da_strings_exists_closure;
-static void string_equal(void *sp, void *closure){
- char *string_element = *(char **)sp;
- da_strings_exists_closure *ss = (da_strings_exists_closure *)closure;
- if( ss->found ) return;
- ss->found = !strcmp(string_element, ss->string);
- return;
-}
-
-bool da_strings_exists(Da *string_arrp, char *test_string){
- da_strings_exists_closure sec;
- sec.string = test_string;
- sec.found = false;
- da_foreach(string_arrp, string_equal, &sec);
- return sec.found;
-}
-
-void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *)){
- if( da_strings_exists( string_arrp, proffered_string)){ // then throw it away, we don't need it
- if(destruct)destruct(proffered_string);
- return;
- }
- da_push(string_arrp, &proffered_string);
-}
-
-// union
-void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *)){
- char *pt = proffered_string_arrp->base;
- while( pt < proffered_string_arrp->end ){
- da_strings_set_insert(string_arrp, *(char **)pt, destruct);
- pt += proffered_string_arrp->element_size;
- }
- return;
-}
-
-
-//--------------------------------------------------------------------------------
-// the da itself is a string
-
-// Puts text from a line into buffer *dap. Does not push EOF or '\n' into the
-// buffer. Returns the old_base so that external pointers can be rebased.
-// It is possible that the the base hasn't changed. Use feof(FILE *stream) to
-// test for EOF;
-char *da_string_input(Da *dap, FILE *file){
- char *old_base = dap->base;
- int c = fgetc(file);
- while( c != EOF && c != '\n' ){
- da_push(dap, &c);
- c = fgetc(file);
- }
- int terminator = 0;
- da_push(dap, &terminator);
- return old_base;
-}
-
-void da_string_push(Da *dap0, char *string){
- if(!*string) return;
- size_t dap0_size = dap0->end - dap0->base;
- size_t string_size = strlen(string);
- dap0->end += string_size;
- while( dap0->end >= dap0->base + dap0->size ) da_expand(dap0);
- memcpy(dap0->base + dap0_size, string, string_size);
-}
-
-
-//--------------------------------------------------------------------------------
-// list operations
-
-// If dap0 has had a terminatating zero added, that must be popped off before
-// the call. Similarly if a terminating zero is desired, it should be pushed
-// after the call.
-
-// appends contents of dap1 onto dap0
-void da_cat(Da *dap0, Da *dap1){
- if(dap1->base == dap1->end) return;
- size_t dap0_size = dap0->end - dap0->base;
- size_t dap1_size = dap1->end - dap1->base; // size of the active portion
- dap0->end += dap1_size;
- while( dap0->end >= dap0->base + dap0->size ) da_expand(dap0);
- memcpy(dap0->base + dap0_size, dap1->base, dap1_size);
-}
-
-
diff --git a/module/da/src/da.lib.h b/module/da/src/da.lib.h
deleted file mode 100644
index 3611064..0000000
--- a/module/da/src/da.lib.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef DA_LIB_H
-#define DA_LIB_H
-#include
-#include
-#include
-#include
-
-typedef struct AccChannel_struct AccChannel; // AccChannel_struct defined in acc.lib.h
-typedef struct Da_struct Da;
-
-struct Da_struct{
- char *base;
- char *end; // one byte/one element off the end of the array
- size_t size; // size >= (end - base) + 1;
- size_t element_size;
- AccChannel *channel;//assign during init, set to NULL during free
-};
-
-// constructors / destructors
-//
- Da *da_init(Da *dap, size_t element_size, AccChannel *channel);//calls da_malloc for base pointer
- void da_free(Da *dap);
- void da_rewind(Da *dap);
- void da_rebase(Da *dap, char *old_base, void *pta);
- char *da_expand(Da *dap);
- bool da_boundq(Da *dap);
- void da_erase(Da *dap);
-
-// status / attributes
-//
- bool da_is_empty(Da *dap);
- bool da_equal(Da *da_0, Da *da_1);
- size_t da_length(Da *dap);
- bool da_length_equal(Da *dap0, Da *dap1);
-
-// accessing
-//
- char *da_index(Da *dap, size_t i);
- char *da_push(Da *dap, void *element);
- bool da_pop(Da *dap, void *element);
-
-// iteration, f is given a pointer to an element and a pointer to the closure
- bool da_endq(Da *dap, void *pt);
- bool da_right_bound(Da *dap, void *pt);
- void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
- bool da_exists(Da *dap, bool f(void *, void*), void *closure);
- bool da_all(Da *dap, bool f(void *, void*), void *closure);
-
-// elements are pointers
-// would be better if exists returned NULL or a pointer to the existing element-
- void *da_pts_exists(Da *dap, void *test_element);
- void da_pts_free_all(Da *dap); // calls free on all elements
- void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
-
-// elements are integers
- void da_ints_print(Da *dap, char *sep);
- bool da_integer_repeats(Da *dap);
- int da_integer_sum(Da *dap);
-
-// the array itself is a string
-// careful if you add a null terminator it will become part of the da_string, affects iteration etc.
- char *da_string_input(Da *dap, FILE *file);
- void da_string_push(Da *dap0, char *string);
- void da_cat(Da *dap_base, Da *dap_cat);
-
-// when the array holds pointers to C strings
- void da_strings_print(Da *dap, char *sep);
- bool da_strings_exists(Da *string_arrp, char *test_string);
- void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
- void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
-
-#endif
-
diff --git a/module/da/src/da.lib.o b/module/da/src/da.lib.o
deleted file mode 100644
index 8031e38..0000000
Binary files a/module/da/src/da.lib.o and /dev/null differ
diff --git a/module/da/src/da_mat.lib.c_nocompile b/module/da/src/da_mat.lib.c_nocompile
deleted file mode 100644
index fb7cef6..0000000
--- a/module/da/src/da_mat.lib.c_nocompile
+++ /dev/null
@@ -1,262 +0,0 @@
-
-//-----------------------------------------------------
-
-
-//-------------------------------------------------------
-
-// all things Da matrix
-// a DaMa (Doubling array Matrix) is a Da whose elements are Da's
-// forms a matrix if you treat what's pointed to by base pointers of the elements of the DaMa as the first column of elements and fill in each row with the contents of the Das
-// The "row major" nomenclature is used to remain consistent with database logic.
-/* Example:
-Da dar0; Da *dap0 = &dar0; da_alloc(dap0, sizeof(int));
-Da dar1; Da *dap1 = &dar1; da_alloc(dap1, sizeof(int));
-Da dama; Da *damp = &dama; da_alloc(damp, sizeof(Da));
-da_push(damp, dap0);
-da_push(damp, dap1);
-*/
-
-/*
-
-Da *da_mat_push_row_alloc(Da *damp){
- size_t row_off = (Da *)(damp->end) - (Da *)(damp->base);
- damp->end += damp->element_size;
- if( damp->end > damp->base + damp->size ) da_expand(damp);
- return (Da *)(damp->base) + row_off;
-}
-Da *da_mat_push_row(Da *damp, Da *dap){// Dama won't track changes to Das after pushing onto rows
- Da *row_pt = da_mat_push_row_alloc(damp);
- memcpy(row_pt, dap, damp->element_size);
- return row_pt;
-}
-
-void da_mat_push_column(Da *damp, Da *dap, void *fill){
- Da *tran = da_mat_transpose(damp, fill);
- da_mat_push_row(tran, dap);
- Da *new_dama = da_mat_transpose(tran, fill);
- //add protection against memory overwrite - expand if necessary
- memcpy(damp, new_dama, new_dama->size);
-}
-
-void da_mat_every_row(Da *damp, void f(void *, void *), void *closure){//like every but for rows instead of elements
- Da *dpt = (Da *)(damp->base);
- while( dpt != (Da *)damp->end ){
- f(dpt, closure);
- dpt++;
- }
-}
-
-// da_mat_every_column uses da_mat_longest and therefore da_mat_longer, written for the purpose of terminating the while loop in the appropriate place
-// will return dap1 if equal, cannot determine equality
-Da *da_mat_longer(Da *dap0, Da *dap1){
- if (da_length(dap0) > da_length(dap1)) return dap0;
- else return dap1;
-}
-// returns Da in DaMa with longest length
-Da *da_mat_longest(Da *damp){
- Da *dap = (Da *)(damp->base);
- Da *longest = (Da *)((damp->base) + sizeof(Da));
- while( dap < (Da *)(damp->end) ){
- longest = da_mat_longer(dap,longest);
- dap++;
- }
- return longest;
-}
-void da_mat_every_column(Da *damp, void f(void *, void *), void *closure){//like every but for columns instead of elements
- Da *dpt = (Da *)(damp->base);
- size_t rows = damp->size/damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- size_t j = 0;
- while( j < columns ){
- int *col = MALLOC(sizeof(rows*sizeof(int)));
- size_t i = 0;
- while( i < rows ) {
- if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
- *(col+i) = 0;
- else *(col+i) = *(dpt->base + j*(dpt->element_size));
- dpt++;
- i++;
- }
- f(col, closure);
- j++;
- }
-}
-
-Da *da_mat_transpose(Da *damp, void *fill){// all Das must have same element type, will sort to integer, char, or char * transpose function
- Da *dap = (Da *)(damp->base);
- Da tran; da_alloc(&tran, sizeof(damp->element_size));
- Da *transpose = &tran;
- if( dap->element_size == sizeof(int) ){
- int *filler = (int *)fill;
- transpose = da_mat_ints_transpose(damp, filler);
- }
- /*else if( dap->element_size == sizeof(char) ){
- char *filler = (char *)fill;
- transpose = da_character_transpose(damp, filler);
- }
- else if( dap->element_size == sizeof(char *) ){
- char **filler = (char **)fill;
- transpose = da_c_string_transpose(damp, filler);
- }*/
- //else error?
- return transpose;
-}
-
-
-//--------------------------------------------------------------------
-// DaMa is a matrix of integers (stored in Das as columns)
-
-// integer repeats across columns
-bool da_mat_all_rows_same_length(Da *damp){
- Da *dap = (Da *)(damp->base);
- Da *pt = dap;
- bool flag = true;
- while( flag && pt != (Da *)(damp->end) ){
- flag = da_length_equal(dap, pt);
- }
- return flag;
-}
-bool da_mat_ints_all_rows_repeat(Da *damp){// if rows are made of repeating integers, then all columns read the same thing
- Da *dpt = (Da *)(damp->base);
- bool flag = false;
- if( da_mat_all_rows_same_length((Da *)damp) ){// columns can't be equal if rows not all same length, will return false
- flag = true;
- while( flag && dpt != (Da *)(damp->end) ){
- flag = da_integer_repeats(dpt); // in "da is array of integers" section
- dpt++;
- }
- return flag;
- }
- else return flag;
-}
-bool da_mat_ints_all_columns_repeat(Da *damp){// rows are repeating in transpose = columns are repeating
- int x = 0; //have to pass in fill for transpose, this nullifies effect same_length test
- Da *test_da = da_mat_transpose(damp, &x);
- return da_mat_ints_all_rows_repeat(test_da);
-}
-bool da_mat_ints_repeats_matrix(Da *damp){// all elements in matrix are same
- bool flag1 = da_mat_ints_all_rows_repeat(damp);
- bool flag2 = da_mat_ints_all_columns_repeat(damp);
- return flag1 && flag2;
-}
-
-// to transpose directly from one DaMa to another
-Da *da_mat_ints_transpose(Da *damp, int *fill){
- size_t rows = damp->size/damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- Da *matrix = damp;
- Da tran;
- da_alloc(&tran, sizeof(Da));
- Da *transpose = &tran;
-
- Da *dpt = (Da *)(matrix->base);
- int i = 0, j = 0;
- while( j < columns ){
- Da new_row; da_alloc(&new_row, sizeof(int));
- int *ept = fill;
- while( i < rows ){
- if( !da_endq(dpt, (dpt->base + j*(dpt->element_size))) ){
- *ept = *(dpt->base + j*(dpt->element_size));
- }
- da_push(&new_row, ept);
- dpt++;
- i++;
- }
- da_mat_push_row(transpose, &new_row);
- j++;
- }
- return transpose;
-}
-
-//to create raw matrix image in memory, no longer a Da struct
-int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill){
- size_t rows = damp->size / damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- int *matrix = MALLOC(sizeof(rows*columns));//[rows][columns]
- int i = 0;
- Da *dpt = (Da *)(damp->base);
- while( i < rows )
- {
- int *ept = (int *)(dpt->base);
- int j = 0;
- while( j < columns )
- {//matrix[i][j]
- if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
- *(matrix + (i*columns + j)*sizeof(int)) = fill;
- else *(matrix + (i*columns + j)*sizeof(int)) = *(ept);
- ept++;
- j++;
- }
- dpt++;
- i++;
- }
- return matrix;
-}
-int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill){
- size_t rows = damp->size/damp->element_size;
- size_t columns = da_length(da_mat_longest(damp));
- int *matrix = da_mat_ints_to_raw_image_matrix(damp, fill);//[rows][columns]
- int *transpose = MALLOC(sizeof(columns*rows));
- int i, j;
- for(i=0;ibase;
- char *ept = dpt->base;
- while( dpt != damp->end ){
- while( ept != dpt->end ){
- f(ept, closure);
- ept+=dpt->element_size;
- }
- dpt++;
- }
-*/
-
-
-//------------------------------------
-
-//first pass at array of Das, exists, etc turned into this
-
-typedef struct{
- Da *da;
- bool found;
-} da_present_closure;
-
-void da_present(Da **dar, int dar_size, void *closure){
- Da **pt = dar;
- da_present_closure *dpc = (da_present_closure *)closure;
- Da *test_element = dpc->da;
- int i = 0;
- while (!dpc->found && i < dar_size){
- dpc->found = da_equal(*pt, test_element);
- pt++;
- i++;
- }
- return;
-}
-
-
-void da_mat_map(Da **dar, int dar_size, void f(void *, void *), void *closure){
- Da **pt = dar;
- int i = 0;
- while( i < dar_size ){
- f(*pt, closure);
- pt++;
- i++;
- }
- return;
-}
diff --git a/module/da/src/da_mat.lib.h_nocompile b/module/da/src/da_mat.lib.h_nocompile
deleted file mode 100644
index c3bc5f8..0000000
--- a/module/da/src/da_mat.lib.h_nocompile
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-// matrix
-// There is a top level master da array. Its elements are da arrays, these are said to be rows
- void da_mat_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
-
- Da *da_mat_push_row_alloc(Da *damp);
- Da *da_mat_push_row(Da *damp, Da *dap);
- void da_mat_push_column(Da *damp, Da *dap, void *fill);
-
- void da_mat_every_row(Da *damp, void f(void *, void *), void *closure);
- Da *da_mat_longer(Da *dap0, Da *dap1);
- Da *da_mat_longest(Da *damp);
- void da_mat_every_column(Da *damp, void f(void *, void *), void *closure);
-
- Da *da_mat_transpose(Da *damp, void *fill);
-
- bool da_mat_all_rows_same_length(Da *damp);
- bool da_mat_ints_all_rows_repeat(Da *damp);
- bool da_mat_ints_all_columns_repeat(Da *damp);
- bool da_mat_ints_repeats_matrix(Da *damp);
-
- Da *da_mat_ints_transpose(Da *damp, int *fill);
- int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill);
- int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill);
-*/
diff --git a/module/da/src/struct_forward_example.c b/module/da/src/struct_forward_example.c
deleted file mode 100644
index d8fec98..0000000
--- a/module/da/src/struct_forward_example.c
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-typedef struct AccChannel_struct AccChannel;
-typedef struct Da_struct Da;
-
-typedef long long int size_t;
-
-struct AccChannel_struct{
- struct Da *outstanding_malloc;
- Da *spurious_free;
- // enum Mode mode;
-}; //name instances of channels with handles
-
-struct Da_struct{
- char *base;
- char *end; // one byte/one element off the end of the array
- size_t size; // size >= (end - base) + 1;
- size_t element_size;
- AccChannel *channel;//assign during init, set to NULL during free
-};
-
-
-int main(){
- Da x;
- AccChannel y;
- return 5;
-}
diff --git a/module/da/src/update_Acc_channel.sed b/module/da/src/update_Acc_channel.sed
deleted file mode 100644
index 9861d73..0000000
--- a/module/da/src/update_Acc_channel.sed
+++ /dev/null
@@ -1 +0,0 @@
-s/Acc_channel/AccChannel/g
diff --git a/module/da/src/update_da_lib_names.sed b/module/da/src/update_da_lib_names.sed
deleted file mode 100644
index 6fcf87f..0000000
--- a/module/da/src/update_da_lib_names.sed
+++ /dev/null
@@ -1,21 +0,0 @@
-s/da_start_accounting/acc_start/g
-s/da_malloc_counted/acc_malloc/g
-s/da_free_counted/acc_free/g
-s/da_result_accounting/acc_result/g
-s/da_free_elements/da_pts_free_all/g
-s/da_matrix_map/da_mat_map/g
-s/da_push_row_alloc/da_mat_push_row_alloc/g
-s/da_push_column/da_mat_push_column/g
-s/da_push_row/da_mat_push_row/g
-s/da_every_row/da_mat_every_row/g
-s/da_longer/da_mat_longer/g
-s/da_longest/da_mat_longest/g
-s/da_every_column/da_mat_every_column/g
-s/da_matrix_transpose/da_mat_transpose/g
-s/da_all_rows_same_length/da_mat_all_rows_same_length/g
-s/da_integer_all_rows_repeat/da_mat_ints_all_rows_repeat/g
-s/da_integer_all_columns_repeat/da_mat_ints_all_columns_repeat/g
-s/da_integer_repeats_matrix/da_mat_ints_repeats_matrix/g
-s/da_integer_transpose/da_mat_ints_transpose/g
-s/da_integer_to_raw_image_matrix/da_mat_ints_to_raw_image_matrix/g
-s/da_integer_to_raw_image_transpose/da_mat_ints_to_raw_image_transpose/g
\ No newline at end of file
diff --git a/module/da/src/update_project_da_lib_names.sed b/module/da/src/update_project_da_lib_names.sed
deleted file mode 100644
index 692744f..0000000
--- a/module/da/src/update_project_da_lib_names.sed
+++ /dev/null
@@ -1,2 +0,0 @@
-s/da_alloc/da_init/g
-s/da_map/da_foreach/g
diff --git a/module/da/test/exec/test_da b/module/da/test/exec/test_da
deleted file mode 100755
index def8c1c..0000000
Binary files a/module/da/test/exec/test_da and /dev/null differ
diff --git a/module/da/test/lib/libtest.a b/module/da/test/lib/libtest.a
deleted file mode 100644
index 6eb3633..0000000
Binary files a/module/da/test/lib/libtest.a and /dev/null differ
diff --git a/module/da/test/lib/test.dat b/module/da/test/lib/test.dat
deleted file mode 100644
index 6b4b5bd..0000000
--- a/module/da/test/lib/test.dat
+++ /dev/null
@@ -1,3 +0,0 @@
-this is a test
-ends without a newline
-(setq mode-require-final-newline nil)
\ No newline at end of file
diff --git a/module/da/test/makefile b/module/da/test/makefile
deleted file mode 100644
index ab92883..0000000
--- a/module/da/test/makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-# da/test
-
-SHELL=/bin/bash
-MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
--include makefile-flags
-
-.PHONY: all
-all: version
-
-.PHONY: dep
-dep:
- if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
- $(MAKE) $@
-
-.PHONY: lib
-lib:
- $(MAKE) $@
-
-.PHONY: exec
-exec:
- $(MAKE) $@
-
-.PHONY: share
-share:
- @echo "module/da/test nothing to share"
-
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/da/test/makefile-flags b/module/da/test/makefile-flags
deleted file mode 100644
index 4270f9d..0000000
--- a/module/da/test/makefile-flags
+++ /dev/null
@@ -1,29 +0,0 @@
-
-MODULE=test
-
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=../share
-SRCDIR=src
-TESTDIR=
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-cc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# compiler and flags
-C=gcc
-CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB
-#CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -Werror
-LINKFLAGS= -Llib -L../lib -ltest -lda
-
diff --git a/module/da/test/results/results_2019-04-19T09:41:00Z b/module/da/test/results/results_2019-04-19T09:41:00Z
deleted file mode 100644
index 2649648..0000000
--- a/module/da/test/results/results_2019-04-19T09:41:00Z
+++ /dev/null
@@ -1,78 +0,0 @@
-Hello Emacs
-
-2019-04-19T09:46:09Z
-glendawest045@phoenix§~/subu/module/da§
-> make dist-clean dep lib
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
-for i in tmp/da.lib.o tmp/makefile-cc.deps; do rm $i || true; done
-for i in ; do [ -e $i ] && rm $i || true; done
-rm include/da.h || true
-rm lib/libda.a || true
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-cp src/da.lib.h include/da.h
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Isrc -Iinclude -I/home/glendawest045/subu/module/share/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB -o tmp/da.lib.o -c src/da.lib.c
-ar rcs lib/libda.a tmp/da.lib.o
-
-2019-04-19T09:46:27Z
-glendawest045@phoenix§~/subu/module/da§
-> cd test/
-
-2019-04-19T09:47:29Z
-glendawest045@phoenix§~/subu/module/da/test§
-> make dist-clean lib exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
-for i in tmp/test_da.cli.o tmp/makefile-cc.deps tmp/test_da.lib.o; do rm $i || true; done
-for i in exec/test_da; do [ -e $i ] && rm $i || true; done
-rm include/test.h || true
-rm: cannot remove 'include/test.h': No such file or directory
-rm lib/libtest.a || true
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
-ar rcs lib/libtest.a tmp/test_da.lib.o
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-make[3]: *** No rule to make target 'exec/test_da', needed by 'sub_exec'. Stop.
-make[2]: *** [makefile:31: sub_exec] Error 2
-make[1]: *** [/home/glendawest045/subu/tool/lib/makefile-cc:164: exec] Error 2
-make: *** [makefile:23: exec] Error 2
-
-2019-04-19T09:47:43Z
-glendawest045@phoenix§~/subu/module/da/test§
-> make dist-clean dep lib exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
-for i in tmp/test_da.lib.o; do rm $i || true; done
-for i in exec/test_da; do [ -e $i ] && rm $i || true; done
-rm include/test.h || true
-rm: cannot remove 'include/test.h': No such file or directory
-rm lib/libtest.a || true
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
-ar rcs lib/libtest.a tmp/test_da.lib.o
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
-gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
-
-2019-04-19T09:48:09Z
-glendawest045@phoenix§~/subu/module/da/test§
-> cd exec/
-
-2019-04-19T09:48:12Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
-> ./test_da
-test_da_push_alloc_0 failed
-failed 1 of 21 tests
-
-2019-04-19T09:48:14Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
->
\ No newline at end of file
diff --git a/module/da/test/results/results_2019-04-23T14:20:14Z_passed b/module/da/test/results/results_2019-04-23T14:20:14Z_passed
deleted file mode 100644
index a82fc93..0000000
--- a/module/da/test/results/results_2019-04-23T14:20:14Z_passed
+++ /dev/null
@@ -1,25 +0,0 @@
-Hello Emacs
-
-
-2019-04-23T14:20:14Z
-glendawest045@phoenix§~/subu/module/da/test§
-> make lib exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-make[1]: Nothing to be done for 'lib'.
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-make[3]: Nothing to be done for 'sub_exec'.
-
-2019-04-23T14:20:40Z
-glendawest045@phoenix§~/subu/module/da/test§
-> cd exec/
-
-2019-04-23T14:20:45Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
-> ./test_da
-passed all 21 tests
-
-2019-04-23T14:20:47Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
->
\ No newline at end of file
diff --git a/module/da/test/results/results_2019-04-27T21:08:59Z_failed b/module/da/test/results/results_2019-04-27T21:08:59Z_failed
deleted file mode 100644
index dd38722..0000000
--- a/module/da/test/results/results_2019-04-27T21:08:59Z_failed
+++ /dev/null
@@ -1,60 +0,0 @@
-Hello Emacs
-
-2019-04-27T21:08:59Z
-glendawest045@phoenix§~§
-> cd subu/module/da/
-
-2019-04-27T21:09:12Z
-glendawest045@phoenix§~/subu/module/da§
-> make dist-clean
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
-for i in tmp/da.lib.o tmp/makefile-cc.deps; do rm $i || true; done
-for i in ; do [ -e $i ] && rm $i || true; done
-rm include/da.h || true
-rm lib/libda.a || true
-
-2019-04-27T21:09:18Z
-glendawest045@phoenix§~/subu/module/da§
-> make dep lib
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-cp src/da.lib.h include/da.h
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Isrc -Iinclude -I/home/glendawest045/subu/module/share/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB -o tmp/da.lib.o -c src/da.lib.c
-ar rcs lib/libda.a tmp/da.lib.o
-
-2019-04-27T21:09:28Z
-glendawest045@phoenix§~/subu/module/da§
-> cd test/
-
-2019-04-27T21:09:31Z
-glendawest045@phoenix§~/subu/module/da/test§
-> make dep lib exec
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
-ar rcs lib/libtest.a tmp/test_da.lib.o
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
-gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
-
-2019-04-27T21:09:39Z
-glendawest045@phoenix§~/subu/module/da/test§
-> cd exec/
-
-2019-04-27T21:09:43Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
-> ./test_da
-da_result_heap_counter failed
-failed 1 of 26 tests
-
-2019-04-27T21:09:48Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
->
\ No newline at end of file
diff --git a/module/da/test/results/results_2019-04-30T14:37:28Z_passed b/module/da/test/results/results_2019-04-30T14:37:28Z_passed
deleted file mode 100644
index 0bbf894..0000000
--- a/module/da/test/results/results_2019-04-30T14:37:28Z_passed
+++ /dev/null
@@ -1,55 +0,0 @@
-Hello Emacs
-
-2019-04-30T14:37:28Z
-glendawest045@phoenix§~/subu/module/da§
-> make dist-clean
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
-for i in tmp/da.lib.o tmp/makefile-cc.deps; do rm $i || true; done
-for i in ; do [ -e $i ] && rm $i || true; done
-rm include/da.h || true
-rm lib/libda.a || true
-
-2019-04-30T14:37:37Z
-glendawest045@phoenix§~/subu/module/da§
-> make dep lib
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-cp src/da.lib.h include/da.h
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Isrc -Iinclude -I/home/glendawest045/subu/module/share/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB -o tmp/da.lib.o -c src/da.lib.c
-ar rcs lib/libda.a tmp/da.lib.o
-
-2019-04-30T14:37:46Z
-glendawest045@phoenix§~/subu/module/da§
-> cd test/
-
-2019-04-30T14:37:50Z
-glendawest045@phoenix§~/subu/module/da/test§
-> make dep lib exec
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
-ar rcs lib/libtest.a tmp/test_da.lib.o
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
-gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
-
-2019-04-30T14:37:52Z
-glendawest045@phoenix§~/subu/module/da/test§
-> cd exec/
-
-2019-04-30T14:37:54Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
-> ./test_da
-passed all 26 tests
-
-2019-04-30T14:37:57Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
->
\ No newline at end of file
diff --git a/module/da/test/results/results_2019-05-03T18:06:21Z_passed b/module/da/test/results/results_2019-05-03T18:06:21Z_passed
deleted file mode 100644
index 20c6e8c..0000000
--- a/module/da/test/results/results_2019-05-03T18:06:21Z_passed
+++ /dev/null
@@ -1,82 +0,0 @@
-Hello Emacs
-
-2019-05-03T18:06:21Z
-glendawest045@phoenix§~/subu/module/da§
-> make all
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc version
-makefile version 6.0
-gcc -v
-Using built-in specs.
-COLLECT_GCC=gcc
-COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
-OFFLOAD_TARGET_NAMES=nvptx-none
-OFFLOAD_TARGET_DEFAULT=1
-Target: x86_64-linux-gnu
-Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-6ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
-Thread model: posix
-gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)
-g++ -v
-Using built-in specs.
-COLLECT_GCC=g++
-COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
-OFFLOAD_TARGET_NAMES=nvptx-none
-OFFLOAD_TARGET_DEFAULT=1
-Target: x86_64-linux-gnu
-Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-6ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
-Thread model: posix
-gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)
-make -v
-GNU Make 4.2.1
-Built for x86_64-pc-linux-gnu
-Copyright (C) 1988-2016 Free Software Foundation, Inc.
-License GPLv3+: GNU GPL version 3 or later
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law.
-
-2019-05-03T18:06:24Z
-glendawest045@phoenix§~/subu/module/da§
-> make dep lib exec
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-cp src/da.lib.h include/da.h
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-make[1]: Nothing to be done for 'lib'.
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-make[3]: Nothing to be done for 'sub_exec'.
-
-2019-05-03T18:06:45Z
-glendawest045@phoenix§~/subu/module/da§
-> cd test/
-
-2019-05-03T18:06:49Z
-glendawest045@phoenix§~/subu/module/da/test§
-> make dep lib exec
-if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
-C compiler only deps
-deps for C linking
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
-ar rcs lib/libtest.a tmp/test_da.lib.o
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
-make sub_exec
-/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
-gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
-gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
-
-2019-05-03T18:06:55Z
-glendawest045@phoenix§~/subu/module/da/test§
-> cd exec/
-
-2019-05-03T18:06:59Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
-> ./test_da
-passed all 26 tests
-
-2019-05-03T18:07:01Z
-glendawest045@phoenix§~/subu/module/da/test/exec§
->
\ No newline at end of file
diff --git a/module/da/test/src/test_da.cli.c b/module/da/test/src/test_da.cli.c
deleted file mode 100644
index 4b14d8e..0000000
--- a/module/da/test/src/test_da.cli.c
+++ /dev/null
@@ -1,103 +0,0 @@
-
-#include
-#include
-#include "test_da.lib.h"
-#include
-#include
-
-//AccChannel acc_live_channels;
-
-int main(){
- //acc_open(&acc_live_channels, acc_SELF);
- // enumeration of tests
- typedef bool (*test_fun)();
- test_fun tests[] =
- {
- test_da_push_0,
- test_da_expand_0,
- test_da_string_input_0,
- test_da_pop_0,
- test_da_cat_0,
- test_da_cat_1,
- test_da_rewind_0,
- test_da_index_0,
- test_da_free_elements_0,
- test_da_strings_exists_0,
- test_da_rebase_0,
- test_da_boundq_0,
- test_da_foreach_0,
- //test_da_present_0,
- test_da_exists_0,
- test_da_exists_1,
- //test_da_all_0,
- test_da_init_0,
- test_da_free_0,
- test_da_is_empty_0,
- test_da_length_0,
- // test_da_push_row_0,
- // test_da_erase_0,
- // test_da_longer_0,
- // test_da_longest_0,
- test_da_accounting_0,
- NULL};
- char *test_names[] =
- {
- "test_da_push_0",
- "test_da_expand_0",
- "test_da_string_input_0",
- "test_da_pop_0",
- "test_da_cat_0",
- "test_da_cat_1",
- "test_da_rewind_0",
- "test_da_index_0",
- "test_da_free_elements_0",
- "test_da_strings_exists_0",
- "test_da_rebase_0",
- "test_da_boundq_0",
- "test_da_foreach_0",
- //"test_da_present_0",
- "test_da_exists_0",
- "test_da_exists_1",
- "test_da_all_0",
- "test_da_init_0",
- "test_da_free_0",
- "test_da_is_empty_0",
- "test_da_length_0",
- //"test_da_push_row_0",
- //"test_da_erase_0",
- //"test_da_longer_0",
- //"test_da_longest_0",
- "test_da_accounting_0",
- NULL};
- // call tests
- bool da_0_passed = true;
- unsigned int passed = 0;
- unsigned int failed = 0;
- test_fun *tfp = tests;
- char **tnp = test_names;
- while(*tfp){
- if( !(*tfp)() ){
- failed++;
- if(*tnp)
- printf("%s failed\n", *tnp);
- else
- fprintf(stderr, "internal error, no test_names[] entry for test\n");
- }else
- passed++;
- tfp++;
- tnp++;
- }
- //acc_report(&acc_live_channels);
- // summarize results
- if( passed == 0 && failed == 0)
- printf("no tests ran\n");
- else if( passed == 0 )
- printf("failed all %u tests\n", failed);
- else if( failed == 0 )
- printf("passed all %u tests\n", passed);
- else
- printf("failed %u of %u tests\n", failed, passed + failed);
-
- if( passed == 0 || failed != 0 ) return 1;
- return 0;
-}
diff --git a/module/da/test/src/test_da.lib.c b/module/da/test/src/test_da.lib.c
deleted file mode 100644
index 7857883..0000000
--- a/module/da/test/src/test_da.lib.c
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
-Tests for Da.
-
-*/
-
-#include
-#include
-#include
-#include
-#include
-
-#include "test_da.lib.h"
-
-
-// tests push
-bool test_da_push_0(){
- //AccChannel c;
- //AccChannel *channel = acc_open(&c, acc_SELF);
- Da da;
- da_init(&da, sizeof(int), NULL); // leaves room for 4 ints
- int i = 0;
- int *pt = (int *)da.base;
- // will double, 4 -> 8, then double 8 -> 16
- while( i < 10 ){
- da_push(&da, &i);
- i++;
- pt++;
- }
-
- bool flag0 = da.size == sizeof(int) * 16;
- bool flag1 = 10 == (da.end - da.base) / sizeof(int);
- bool flag2 = true;
- pt = (int *)da.base;
- i = 0;
- while( i < 10 ){
- flag2 = flag2 && *pt == i && !da_endq(&da, pt);
- i++;
- pt++;
- }
- bool flag3 = da_endq(&da, pt);
- da_free(&da);
- //acc_report(channel);
- //acc_close(channel);
- return flag0 && flag1 && flag2 && flag3;
-}
-
-// tests manual expansion
-bool test_da_expand_0(){
- Da da;
- Da *dap = da_init(&da, sizeof(int), NULL); // leaves room for 4 ints
- int i = 0;
- int *pt = (int *)da.base;
- // will double, 4 -> 8, then double 8 -> 16
- while( i < 10 ){
- da.end += da.element_size;
- if( da_boundq(&da) ){
- char *old_base = da_expand(&da);
- da_rebase(&da, old_base, &pt);
- }
- *pt = i;
- i++;
- pt++;
- }
-
- bool flag0 = da.size == sizeof(int) * 16;
- bool flag1 = 10 == (da.end - da.base) / sizeof(int);
- bool flag2 = true;
- pt = (int *)da.base;
- i = 0;
- while( i < 10 ){
- flag2 = flag2 && *pt == i && !da_endq(&da, pt);
- i++;
- pt++;
- }
- bool flag3 = da_endq(&da, pt);
- da_free(dap);
- return flag0 && flag1 && flag2 && flag3;
-}
-
-// da_fgets via da_string_input
-bool test_da_string_input_0(){
-
- char *data_file_name = "../lib/test.dat";
- FILE *file = fopen(data_file_name,"r");
- if(!file){
- fprintf(stderr,"test_da_2, could not open data file %s for reading\n", data_file_name);
- return false;
- }
-
- Da da;
- da_init(&da, sizeof(char), NULL);
-
- da_string_input(&da, file);
- bool flag0 = !strcmp(da.base, "this is a test");
-
- char *old_base;
- da_pop(&da, NULL); // pop the prior null terminator
- char *s1 = da.end;
- old_base = da_string_input(&da,file);
- da_rebase(&da, old_base, &s1);
- bool flag1 = !strcmp(s1, "ends without a newline");
-
- da_pop(&da, NULL); // pop the prior null terminator
- char *s2 = da.end;
- old_base = da_string_input(&da,file);
- da_rebase(&da, old_base, &s2);
- bool flag2 = !strcmp(s2, "(setq mode-require-final-newline nil)");
-
- bool flag3 = !strcmp(da.base, "this is a testends without a newline(setq mode-require-final-newline nil)");
-
- fclose(file);
- da_free(&da);
- return flag0 && flag1 && flag2 && flag3;
-}
-
-// da_pop
-bool test_da_pop_0(){
-
- Da da;
- da_init(&da, sizeof(int), NULL);
-
- int i = 5;
- da_push(&da, &i);
- i++;
- da_push(&da, &i);
- i++;
- da_push(&da, &i);
-
- int j;
- bool flag0 = da_pop(&da, &j) && j == 7;
- bool flag1 = da_pop(&da, &j) && j == 6;
- bool flag2 = da_pop(&da, NULL);
- bool flag3 = !da_pop(&da, &j);
- da_free(&da);
- return flag0 && flag1 && flag2 && flag3;
-}
-
-// da_cat
-bool test_da_cat_0(){
-
- Da da0, da1;
- da_init(&da0, sizeof(int), NULL);
- da_init(&da1, sizeof(int), NULL);
-
- int i = 5;
- while(i < 8){
- da_push(&da0, &i);
- i++;
- }
- while(i < 11){
- da_push(&da1, &i);
- i++;
- }
-
- da_cat(&da0, &da1);
-
- bool flag[6];
- int j;
- int k = 0;
- while(k < 6){
- flag[k] = da_pop(&da0, &j) && (j == 10 - k);
- k++;
- }
-
- bool result = flag[0];
- k = 1;
- while(result && k < 6){
- result = flag[k];
- k++;
- }
- da_free(&da0);
- da_free(&da1);
- return result;
-}
-
-//Glenda: this was already tested much better above, where each element was actually tested, not just one, but it was a good one to test for practice
-bool test_da_cat_1(){
- Da dar0;
- Da dar1;
- da_init(&dar0, sizeof(int), NULL);
- da_init(&dar1, sizeof(int), NULL);
- int n = 2;
- {
- int m = 0;
- while(m < 4){
- da_push(&dar0, &n);
- n+=2;
- m++;
- }
- }
- size_t off0 = dar0.end - dar0.base;
- bool flag1 = dar0.base != dar0.end;
- for (int m=0; m<4; m++){
- da_push(&dar1, &n);
- n+=2;
- }
- size_t off1 = dar1.end - dar1.base;
- bool flag2 = dar1.base != dar1.end;
- da_cat(&dar0, &dar1);
- bool flag3 = dar0.end == dar0.base + off0 +off1;
- bool flag4 = *(dar0.base + (5*dar0.element_size)) == *(dar1.base + dar1.element_size);
- da_free(&dar0);
- da_free(&dar1);
- return flag1 && flag2 && flag3 && flag4;
-}
-
-
-//Glenda's tests
-//tested output for success and artificial failure
-
-//tests da_rewind
-bool test_da_rewind_0(){
- int i = 10;
- Da dar;
- da_init(&dar, sizeof(int), NULL);
- while(i < 18){
- da_push(&dar, &i);
- ++i;
- }
- bool flag1 = dar.end != dar.base;
- da_rewind(&dar);
- int n = *(dar.end);
- bool flag2 = dar.end == dar.base;
- bool flag3 = n == 10;
- bool flag4 = (*(dar.end + (7 * sizeof(int))) = 17);
- bool result = flag1 && flag2 && flag3 && flag4;
-
- da_free(&dar);
- return result;
-}
-
-//tests da_index
-bool test_da_index_0(){
- Da dar;
- Da *dar_pt = &dar;
- da_init(dar_pt, sizeof(int), NULL);
-
-
- bool flag[4];
- {//push to dar and test da_index
- char *a[4];
- size_t i = 0;
- int n = 10;
- int *n_pt = &n;
- while(i < 4){
- da_push(dar_pt, n_pt);
- a[i] = da_index(dar_pt, i);
- flag[i] = a[i] == dar.base + (i*dar.element_size);
- i++;
- n++;
- }
- }
- bool result = flag[0] && flag[1] && flag[2] && flag[3];
- da_free(dar_pt);
- return result;
-}
-
-//tests da_free_elements - still getting core dump on function call
-//cannot test sub-functions bc da_free_element needs to be static
-bool test_da_free_elements_0(){
- Da dar;
- Da *dar_pt = &dar;
- da_init(dar_pt, sizeof(int*), NULL);
-
- int i = 3;
- int *i_pt = &i;
- while(i < 7){
- da_push(dar_pt, &i_pt);
- ++i;
- }
-
- //da_free_elements(dar_pt);
- bool result = true;
- da_free(dar_pt);
- return result;
-}
-
-//tests da_strings_exist
-bool test_da_strings_exists_0(){
- Da dar;
- Da *dar_pt = &dar;
- da_init(dar_pt, sizeof(char *), NULL);
-
- //fill dar with strings
- char *string0 = "nope";
- char **string0_pt = &string0;
- da_push(dar_pt, string0_pt);
- char *string1 = "okay";
- char **string1_pt = &string1;
- da_push(dar_pt, string1_pt);
- char *string2 = "welp";
- char **string2_pt = &string2;
- da_push(dar_pt, string2_pt);
- char *string3 = "sure";
- char **string3_pt = &string3;
- da_push(dar_pt, string3_pt);
-
- bool result;
- {//test dar for each string
- result = da_strings_exists(dar_pt, string0);
- if (result == true)
- result = da_strings_exists(dar_pt, string1);
- if (result == true)
- result = da_strings_exists(dar_pt, string2);
- if (result == true)
- result = da_strings_exists(dar_pt, string3);
- }
- da_free(dar_pt);
- return result;
-}
-
-
-//tests rebase
-bool test_da_rebase_0(){
- Da dar;
- da_init(&dar,sizeof(char), NULL);
-
- char **el_pt = (char **)acc_malloc(4*(sizeof(char*)), NULL);
- {//push "temp" into dar, leave with pointer to last element
- int i = 0;
- char arr[4] = {'t','e','m','p'};
- while(i<4){
- char c = *(arr+i);
- *el_pt = da_push(&dar, &c);
- el_pt++;
- i++;
- }
- el_pt--;
- }
-
- //check that push worked, that element pointer is in right place, and that expand works
- bool flag1 = dar.base != dar.end;
- bool flag2 = *el_pt == dar.end - dar.element_size;
-
- char *obase = dar.base;
- char *old_base = da_expand(&dar);
- bool flag3 = obase == old_base;
-
- bool flag4[4];
- {//check that each pointer is properly rebased
- int i = 0;
- while(i<4 && *el_pt >= old_base){
- size_t old_offset = *el_pt - old_base;
- da_rebase(&dar, old_base, el_pt);
- size_t new_offset = *el_pt - dar.base;
- flag4[i] = old_offset == new_offset;
- el_pt--;
- i++;
- }
- el_pt++;
- }
-
- bool result = flag4[0];
- {//now check that all pointers are properly rebased
- int i = 1;
- while(result && i < 4){
- result = flag4[i];
- i++;
- }
- }
- da_free(&dar);
- acc_free(el_pt, NULL);
- return flag1 && flag2 && flag3 && result;
-}
-
-/* {//problems with FREE and MALLOC
- char *a = MALLOC(10);
- strcpy(a, "zsdf");
- Da da;
- Da *da_pt = &da;
- da_init(da_pt, sizeof(char *));
- da_push(da_pt, a);
- ...
- FREE(*(char *)da_index(da_pt, 0));
- da_free(da_pt);
-} */
-
-//tests da_boundq
-bool test_da_boundq_0(){
- Da dar;
- da_init(&dar,sizeof(char), NULL);
-
- bool flag[5];
- {//pushes onto dar and tests no runoff
- char arr[4] = {'r','e','s','t'};
- int i = 0;
- char c;
- while(i<4){
- c = arr[i];
- da_push(&dar, &c);
- flag[i] = (dar.end != dar.base) && !da_boundq(&dar);
- i++;
- }
-
- }
-
- //makes end pointer run off allocated area, tests boundq detects runoff
- dar.end++; // = dar.base + dar.size;
- flag[4] = da_boundq(&dar);
-
- bool result = true;
- {//check all test results
- int i = 0;
- while (result && i < 5){
- result = flag[i];
- i++;
- }
- }
- da_free(&dar);
- return result;
-}
-
-//tests foreach
-static void test_da_foreach_0_helper(void *pt, void *closure){
- int *n = (int *)closure;
- *n += *(int *)pt;
-}
-bool test_da_foreach_0(){
- Da dar;
- da_init(&dar, sizeof(int), NULL);
-
- {//pushes onto dar
- int arr[4] = {5,6,7,8};
- int i = 0;
- while(i<4){
- da_push(&dar, arr+i);
- i++;
- }
- }
-
- int n = 0;
- int *closure = &n;
-
- da_foreach(&dar, test_da_foreach_0_helper, (int *)closure);
- //rename to da_foreach
- bool result = n == (5+6+7+8);
- da_free(&dar);
- return result;
-}
-
-/*
-//tests da_present
-bool test_da_present_0(){
- int dar_size = 0;
- Da **dar = acc_malloc(3 * sizeof(Da *), NULL);
-
- Da dap_0;
- Da *dap_0_pt = &dap_0;
- da_init(dap_0_pt,sizeof(int), NULL);
-
- Da dap_1;
- Da *dap_1_pt = &dap_1;
- da_init(dap_1_pt,sizeof(char), NULL);
-
- dar[dar_size] = dap_0_pt; dar_size++;
- dar[dar_size] = dap_1_pt; dar_size++;
- Da dap_2;
- Da *dap_2_pt = &dap_2;
- da_init(dap_2_pt,sizeof(char *), NULL);
- dar[dar_size] = dap_2_pt; dar_size++;
-
- Da ;
- Da *matrix = ;
- da_init(dar, sizeof(Dap *));
-
- typedef struct{
- Da *da;
- bool found;
-} da_present_closure;
-
- bool flag[4];
- da_present_closure dpc;
- dpc.da = dap_0_pt;
- dpc.found = false;
-
- //test da_equal
- flag[0] = da_equal(dap_0_pt, dpc.da);
-
- //test da_present
- da_present(dar, dar_size, &dpc);
- flag[1] = dpc.found;
- dpc.found = false;
- da_present(dar, dar_size, &dpc);
- flag[2] = dpc.found;
- dpc.found = false;
- da_present(dar, dar_size, &dpc);
- flag[3] = dpc.found;
- dpc.found = false;
-
- bool result = flag[0] && flag[1] && flag[2] && flag[3];
- da_free(dap_0_pt); da_free(dap_1_pt); da_free(dap_2_pt);
- acc_free(dar, NULL);
- return result;
-}
-*/
-
-//tests for da_exists and all
-
-static bool test_exists_helper(void *pt, void *closure){
- bool result = *(int*)pt == *(int *)closure;
- return result;
-}
-
-//tests da_exists
-bool test_da_exists_0(){
- Da dar;
- Da *dar_pt = &dar;
- da_init(dar_pt, sizeof(int), NULL);
-
- int n[5] = {5,6,7,8,9};
-
- {//pushes ints 5-8 onto dar
- int j = 0;
- while (j < 5){
- if (j != 3){
- int *n_pt = n+j;
- da_push(dar_pt, n_pt);
- }
- j++;
- }
- }
-
- bool flag[5];
- {//tests da_exists
- int j = 0;
- while(j < 5){
- int *n_pt = n+j;
- flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
- j++;
- }
- }
-
- bool result_1 = flag[0] && flag[1] && flag[2] && !flag[3] && flag[4];
-
- {//add 8
- int *n_pt = n+3;
- da_push(dar_pt, n_pt);
- }
-
- {//tests da_exists
- int j = 0;
- while(j < 5){
- int *n_pt = n+j;
- flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
- j++;
- }
- }
-
- bool result_2 = flag[0] && flag[1] && flag[2] && flag[3] && flag[4];
- da_free(dar_pt);
- return result_1 && result_2;
-}
-bool test_da_exists_1(){//tests that expansion doesn't change results
- Da dar;
- Da *dar_pt = &dar;
- da_init(dar_pt, sizeof(int), NULL);
-
- int n[8] = {20,21,22,23,24,25,26,27};
-
- {//pushes 20-27 onto dar except 23 and 26
- int j = 0;
- while (j < 8){
- if (j != 3 && j != 6){
- int *n_pt = n+j;
- da_push(dar_pt, n_pt);
- }
- j++;
- }
- }
-
- bool flag[8];
- {//tests da_exists
- int j = 0;
- while(j < 8){
- int *n_pt = n+j;
- flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
- j++;
- }
- }
-
- bool result_1 =
- flag[0] && flag[1] && flag[2] && !flag[3] && flag[4] && flag[5]
- && !flag[6] && flag[7];
-
- {//add 23 and 26
- int *n_pt = n+3;
- da_push(dar_pt, n_pt);
- n_pt = n+6;
- da_push(dar_pt, n_pt);
- }
-
- {//tests da_exists
- int j = 0;
- while(j < 8){
- int *n_pt = n+j;
- flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
- j++;
- }
- }
-
- bool result_2 =
- flag[0] && flag[1] && flag[2] && flag[3] && flag[4] && flag[5]
- && flag[6] && flag[7];
- da_free(dar_pt);
- return result_1 && result_2;
-}
-
-
-/*
-//tests da_all
-bool test_da_all_0(){
- Da dar;
- Da *dar_pt = &dar;
- da_init(dar_pt, sizeof(int), NULL);
-
- int n = 5;
- int *n_pt = &n;
- //push 5 onto dar 4 times
- da_push(dar_pt, n_pt);
- da_push(dar_pt, n_pt);
- da_push(dar_pt, n_pt);
- da_push(dar_pt, n_pt);
-
- //tests da_all is true
- bool flag1 = da_all(dar_pt, test_exists_helper, n_pt);
-
- da_pop(dar_pt, NULL);
- n = 6;
- //tests da_all is false
- bool flag2 = !da_all(dar_pt, test_exists_helper, n_pt);
- da_free(dar_pt);
-
- return flag1 && flag2;
-}
-*/
-
-
-//tests da_init
-bool test_da_init_0(){
- Da da0; Da *da0_pt = &da0; da_init(da0_pt, sizeof(char), NULL);
- Da da1; Da *da1_pt = &da1; da_init(da1_pt, sizeof(int), NULL);
- Da da2; Da *da2_pt = &da2; da_init(da2_pt, sizeof(char *), NULL);
- bool flag[6];
-
- //check that da is allocated as array of 4 chars
- flag[0] = da0_pt->element_size == 1;
- flag[1] = da0_pt->size == 4;
-
- //check that da is allocated as array of 4 ints
- flag[2] = da1_pt->element_size == 4;
- flag[3] = da1_pt->size == 16;
-
- //check that da is allocated as array of 4 char *s
- flag[4] = da2_pt->element_size == 8;
- flag[5] = da2_pt->size == 32;
-
- bool result =
- flag[0] && flag[1] && flag[2] && flag[3] && flag[4] && flag[5];
-
- da_free(da0_pt);
- da_free(da1_pt);
- da_free(da2_pt);
- return result;
-}
-
-//tests da_free
-bool test_da_free_0(){
- Da da;
- Da *da_pt = &da;
- da_init(da_pt, sizeof(int), NULL);
-
- //store location of da
- Da *keep = da_pt;
- Da *save = da_pt;
-
- //acc_free da
- da_free(da_pt);
-
- //re-allocate memory to dew da of chars
- da_init(keep, sizeof(char), NULL);
-
- //test that same memory is properly re-allocated
- bool flag1 = keep == save;
- bool flag2 = keep->element_size == 1;
- da_free(keep);
- return flag1 && flag2;
-}
-
-//tests da_is_empty
-bool test_da_is_empty_0(){
- int i = 6;
- Da da;
- Da *da_pt = &da;
- da_init(da_pt, sizeof(int), NULL);
- bool flag0 = da_is_empty(da_pt);
- while(i < 11){
- da_push(da_pt, &i);
- ++i;
- }
- bool flag1 = !da_is_empty(da_pt);
- da_rewind(da_pt);
- bool flag2 = da_is_empty(da_pt);
- da_free(da_pt);
- return flag0 && flag1 && flag2;
-}
-
-//tests da_length
-bool test_da_length_0(){
- int i = 1;
- Da da;
- Da *da_pt = &da;
- da_init(da_pt, sizeof(int), NULL);
-
- //test da_length, even pushing past expansions
- bool result = true;
- while(result && i < 15){
- da_push(da_pt, &i);
- size_t length = da_length(da_pt);
- result = length == i;
- ++i;
- }
- da_free(da_pt);
- return result;
-}
-
-/*
-//------------------------------------------------
-// Matrix function tests
-
-//tests da_push_row
-bool test_da_push_row_0(){
- Da dama; da_init(&dama, sizeof(Da), NULL); Da *damp = &dama;
- Da row0; da_init(&row0, sizeof(int), NULL); da_push_row(damp, &row0);
- Da row1; da_init(&row1, sizeof(int), NULL); da_push_row(damp, &row1);
- Da row2; da_init(&row2, sizeof(int), NULL); da_push_row(damp, &row2);
-
- bool flag0 = da_equal(&row0, (Da *)(damp->base));
- bool flag1 = da_equal(&row1, (Da *)(damp->base + damp->element_size));
- bool flag2 = da_equal(&row2, (Da *)(damp->base + 2*(damp->element_size)));
- int n = 5;
- while( n < 8 ){
- da_push(&row0, &n);
- n++;
- }
- // bool flag3 = da_equal(&row0, (Da *)(damp->base));
- // Dama won't track changes to Das after pushing onto rows
- da_free_elements(damp);
- da_erase(damp);
- return flag0 && flag1 && flag2;// && flag3;
-}
-
-//tests da_erase
-bool test_da_erase_0(){
- Da dama; da_init(&dama, sizeof(Da), NULL); Da *damp = &dama;
- Da row0; da_init(&row0, sizeof(int), NULL); da_push_row(damp, &row0);
- Da row1; da_init(&row1, sizeof(int), NULL); da_push_row(damp, &row1);
- Da row2; da_init(&row2, sizeof(int), NULL); da_push_row(damp, &row2);
-
- //store location of da
- Da *keep = damp;
- Da *save = damp;
-
- //free da
- da_free_elements(damp);
- da_erase(damp);
-
- //re-allocate memory to dew da of chars
- da_init(keep, sizeof(char), NULL);
-
- //test that same memory is properly re-allocated
- bool flag1 = keep == save;
- bool flag2 = keep->element_size == 1;
- da_free_elements(keep);
- da_free(keep);
- return flag1 && flag2;
-}
-
-//tests da_longer
-bool test_da_longer_0(){
- Da dama; Da *damp = &dama; da_init(damp, sizeof(Da), NULL);
-
- Da row0; Da *r0 = &row0; da_init(r0, sizeof(int), NULL);
- {//fills first row with 4 integers
- int i = 10;
- while(i<14){
- da_push(r0, &i);
- i++;
- }
- }
- da_push_row(damp, r0);
-
- Da row1; Da *r1 = &row1; da_init(r1, sizeof(int), NULL);
- {//fills second row with 4 different integers
- int i = 20;
- while(i<24){
- da_push(r1, &i);
- i++;
- }
- }
- da_push_row(damp, r1);
-
- Da row2; Da *r2 = &row2; da_init(r2, sizeof(int), NULL);
- {//fills third row with 6 integers
- int i = 30;
- while(i<36){
- da_push(r2, &i);
- i++;
- }
- }
- da_push_row(damp, r2);
-
- //plain test for which is Da is longer
- Da *test1 = da_longer(r0, r1);
- Da *test2 = da_longer(r0, r2);
-
- //tests from dama which row is longer
- Da *dr0 = (Da *)(damp->base);
- Da *dr1 = (Da *)((damp->base)+sizeof(Da *));
- Da *dr2 = (Da *)((damp->base)+(2*sizeof(Da *)));
- Da *test3 = da_longer(dr0, dr1);
- Da *test4 = da_longer(dr2, dr0);
-
- bool flag1 = test1 == r1;
- bool flag2 = test2 == r2;
- bool flag3 = test3 == dr1;
- bool flag4 = test4 == dr2;
-
- da_free_elements(damp);
- da_erase(damp);
- return flag1 && flag2 && flag3 && flag4;
-}
-
-//tests da_longest
-bool test_da_longest_0(){
-
- Da dama; Da *damp = &dama; da_init(damp, sizeof(Da), NULL);
-
- Da row0; Da *r0 = &row0; da_init(r0, sizeof(int), NULL);
- {//fills first row with 4 integers
- int i = 10;
- while(i<14){
- da_push(r0, &i);
- i++;
- }
- }
- da_push_row(damp, r0);
-
- Da row1; Da *r1 = &row1; da_init(r1, sizeof(int), NULL);
- {//fills second row with 4 different integers
- int i = 20;
- while(i<24){
- da_push(r1, &i);
- i++;
- }
- }
- da_push_row(damp, r1);
-
- Da row2; Da *r2 = &row2; da_init(r2, sizeof(int), NULL);
- {//fills third row with 6 integers
- int i = 30;
- while(i<36){
- da_push(r2, &i);
- i++;
- }
- }
- da_push_row(damp, r2);
-
- Da *dr0 = (Da *)(damp->base);
- Da *dr1 = (Da *)((damp->base)+sizeof(Da));
- Da *dr2 = (Da *)((damp->base)+(2*sizeof(Da)));
- Da *test = da_longest(damp);
-
- bool flag = test == dr2;
- da_free_elements(damp);
- da_erase(damp);
- return flag;
-}
-*/
-
-bool test_da_accounting_0(){
- AccChannel acc0;
- AccChannel *acc0_pt = acc_open(&acc0, acc_FULL);
-
- //Da da0;
- //Da *dap = (Da *)da_init(&da0, sizeof(int), NULL); //trying to use acc0_pt results in even more immediate seg fault
-
- printf("Outstanding Malloc: %d\n", (int)(acc0_pt->outstanding_malloc));
- printf("Spurious Free: %d\n", (int)(acc0_pt->spurious_free));
- acc_report(acc0_pt);
-
- // da_free(dap);
-
- acc_close(acc0_pt);
- bool result = true;
- return result;
-}
-
-
-
-/*need to update list
- Functions
--da_init
--da_free
--da_rewind
--da_is_empty
--da_length
--da_rebase
--da_expand
--da_boundq
--da_index
--da_strings_exists_0
--da_push
--da_pop
-da_endq
--da_foreach
-da_free_elements
-da_ints_print
-da_integer_repeats
-da_strings_print
--da_strings_exists
-da_strings_set_insert
-da_strings_set_union
--da_string_input
-da_string_push
--da_cat
--da_exists
--da_all
-
-//matrix
--da_erase
-da_push_row_alloc
--da_push_row
-da_push_column
-
-da_every_row
--da_longer
--da_longest
-da_every_column
-
-da_matrix_transpose
-
-da_length_equal
-da_all_rows_same_length
-da_integer_all_rows_repeat
-da_integer_all_columns_repeat
-da_integer_repeats_matrix
-
-da_integer_transpose
-da_integer_to_raw_image_matrix
-da_integer_to_raw_image_transpose
-
-*/
-
-/*
- Tests
-test_da_push_0
-test_da_expand_0
-test_da_string_input_0
-test_da_pop_0
-test_da_cat_0
-test_da_cat_1
-test_da_rewind_0
-test_da_index_0
-test_da_free_elements_0
-test_da_strings_exists_0
-test_da_rebase_0
-test_da_boundq_0
-test_da_foreach_0
-test_da_present_0
-test_da_exists_0
-test_da_exists_1
-test_da_all_0
-test_da_init_0
-test_da_free_0
-test_da_is_empty_0
-test_da_length_0
-
-//matrix
-da_push_row_0
-da_erase_0
-test_da_longer_0
-test_da_longest_0
-
-*/
diff --git a/module/da/test/src/test_da.lib.h b/module/da/test/src/test_da.lib.h
deleted file mode 100644
index 9872c4f..0000000
--- a/module/da/test/src/test_da.lib.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef TEST_DA_LIB_H
-#define TEST_DA_LIB_H
-
-bool test_da_push_0();
-bool test_da_expand_0();
-bool test_da_string_input_0();
-bool test_da_pop_0();
-bool test_da_cat_0();
-bool test_da_cat_1();
-bool test_da_rewind_0();
-bool test_da_index_0();
-bool test_da_free_elements_0();
-bool test_da_strings_exists_0();
-bool test_da_rebase_0();
-bool test_da_boundq_0();
-bool test_da_foreach_0();
-bool test_da_present_0();
-bool test_da_exists_0();
-bool test_da_exists_1();
-//bool test_da_all_0();
-bool test_da_init_0();
-bool test_da_free_0();
-bool test_da_is_empty_0();
-bool test_da_length_0();
-//bool test_da_push_row_0();
-//bool test_da_erase_0();
-//bool test_da_longer_0();
-//bool test_da_longest_0();
-bool test_da_accounting_0();
-
-#endif
diff --git a/module/da/test/src/test_da.lib.h.gch b/module/da/test/src/test_da.lib.h.gch
deleted file mode 100644
index f5782f9..0000000
Binary files a/module/da/test/src/test_da.lib.h.gch and /dev/null differ
diff --git a/module/da/test/try/passed.transcript b/module/da/test/try/passed.transcript
deleted file mode 100644
index d75d376..0000000
--- a/module/da/test/try/passed.transcript
+++ /dev/null
@@ -1,5 +0,0 @@
-2019-03-31T20:08:48Z
-morpheus@manorhouse§~/subu_land/subu/module/da/test/exec§
-> ./test_da
-passed all 5 tests
-
diff --git a/module/debug/makefile b/module/debug/makefile
deleted file mode 100644
index a19b90e..0000000
--- a/module/debug/makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-# db
-
-SHELL=/bin/bash
-MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
--include makefile-flags
-
-.PHONY: all
-all: version
-
-.PHONY: dep
-dep:
- if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
- $(MAKE) $@
-
-.PHONY: lib
-lib:
- cp $(SRCDIR)/debug.lib.h $(INCDIR)/debug.h
- $(MAKE) $@
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/debug/makefile-flags b/module/debug/makefile-flags
deleted file mode 100644
index 4dfd9bf..0000000
--- a/module/debug/makefile-flags
+++ /dev/null
@@ -1,30 +0,0 @@
-
-MODULE=debug
-
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
-SRCDIR=src
-TESTDIR=test
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-cc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# compiler and flags
-C=gcc
-CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
-LINKFLAGS=-L$(LIBDIR) -l$(MODULE)
-
-
-
diff --git a/module/debug/src/debug.lib.c b/module/debug/src/debug.lib.c
deleted file mode 100644
index 01ba20d..0000000
--- a/module/debug/src/debug.lib.c
+++ /dev/null
@@ -1,14 +0,0 @@
-
-#include "debug.lib.h"
-
-#include
-#include
-
-int debug_printf(const char *format, ...){
- va_list args;
- va_start(args,format);
- int ret = vfprintf(stdout, format, args);
- fflush(stdout);
- va_end(args);
- return ret;
-}
diff --git a/module/debug/src/debug.lib.h b/module/debug/src/debug.lib.h
deleted file mode 100644
index f1be3d8..0000000
--- a/module/debug/src/debug.lib.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef DB_LIB_H
-#define DB_LIB_H
-
-int debug_printf(const char *format, ...);
-
-#endif
diff --git a/module/dispatch/dispatch.lib.c b/module/dispatch/dispatch.lib.c
deleted file mode 100644
index de7011f..0000000
--- a/module/dispatch/dispatch.lib.c
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-#include "dispatch.h"
-
-// we need the declaration for uid_t etc.
-// without this #define execvpe is undefined
-#define _GNU_SOURCE
-
-#include
-#include
-#include
-#include
-
-void dispatch_f_mess(char *fname, int err, char *dispatchee){
- if(err == 0) return;
- fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
- if(err > ERR_DISPATCH){
- fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
- return;
- }
- switch(err){
- case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
- fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
- break;
- case ERR_DISPATCH_F_FORK:
- case ERR_DISPATCH_F_SETEUID:
- case ERR_DISPATCH_F_SETEGID:
- fputc(' ', stderr);
- perror(dispatchee);
- break;
- case ERR_DISPATCH_NULL_EXECUTABLE:
- fprintf(stderr, " executable was not specified");
- break;
- case ERR_DISPATCH_EXEC:
- // exec is running in another process when it fails, so we can't see the errno value it set
- fprintf(stderr, " exec of \"%s\" failed", dispatchee);
- break;
- default:
- fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
- }
- fputc('\n', stderr);
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a function
-int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
- #ifdef DEBUG
- debug_printf("%s %s\n", "dispatch_f", fname);
- #endif
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
- if( pid == 0 ){ // we are the child
- int status = (*f)(f_arg); // we require that f return a zero or positive value
- if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
- exit(status);
- }else{ // we are the parent
- int err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a function with a given euid/egid
-// of course this will only work if our euid is root in the first place
-int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
- #ifdef DEBUG
- debug_printf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
- #endif
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK;
- if( pid == 0 ){ // we are the child
- int status;
- if( seteuid(euid) == -1 )
- status = ERR_DISPATCH_F_SETEUID;
- else if( setegid(egid) == -1 )
- status = ERR_DISPATCH_F_SETEGID;
- else{
- status = (*f)(f_arg);
- if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
- exit(status);
- }
- }else{ // we are the parent
- uint err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a executable
-int dispatch_exec(char **argv, char **envp){
- char *command;
- {
- if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
- #ifdef DEBUG
- debug_printf("dispatch_exec:");
- char **apt = argv;
- while( *apt ){
- debug_printf(" %s",*apt);
- apt++;
- }
- debug_printf("\n");
- #endif
- command = argv[0];
- }
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
- if( pid == 0 ){ // we are the child
- execvpe(command, argv, envp); // exec will only return if it has an error
- #ifdef DEBUG
- debug_printf("dispatch_exec: exec returned, perror message:");
- perror("dispatch_exec"); // our only chance to print this message, as this is the child process
- #endif
- fflush(stdout);
- exit(ERR_DISPATCH_EXEC);
- }else{ // we are the parent
- int err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
diff --git a/module/dispatch/dispatch.lib.h b/module/dispatch/dispatch.lib.h
deleted file mode 100644
index 5e0994f..0000000
--- a/module/dispatch/dispatch.lib.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- Runs a command or function as its own process.
-
- The return status integer from command or function must be greater than ERR_DISPATCH.
- In the case of dispatch_exec, we only have a promise from the user to not dispatch
- non compliant commands.
-
-*/
-#ifndef DISPATCH_LIB_H
-#define DISPATCH_LIB_H
-#include
-#include
-
-#define ERR_DISPATCH -1024
-#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
-#define ERR_DISPATCH_F_FORK -1025
-#define ERR_DISPATCH_F_SETEUID -1026
-#define ERR_DISPATCH_F_SETEGID -1027
-#define ERR_DISPATCH_NULL_EXECUTABLE -1028
-#define ERR_DISPATCH_EXEC -1029
-
-// currently both dispatcher and dispatchee strings are statically allocated
-struct dispatch_ctx{
- char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
- char *dispatchee; // name of the function being dispatched
- int err; // error code as listed below, or status returned from dispatchee
-};
-void dispatch_f_mess(char *fname, int err, char *dispatchee);
-int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
-int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
-int dispatch_exec(char **argv, char **envp);
diff --git a/module/dispatch/makefile b/module/dispatch/makefile
deleted file mode 100644
index add0ff2..0000000
--- a/module/dispatch/makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-# src-dispatch/makefile
-
-SHELL=/bin/bash
-MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
--include makefile-flags
-
-
-.PHONY: all
-all: version
-
-.PHONY: info
-info:
- @echo "TRCDIR: " $(TRCDIR)
- $(MAKE) $@
-
-.PHONY: setup
-setup:
- [ ! -e $(TRCDIR) ] && mkdir $(TRCDIR) || true
- $(MAKE) $@
-
-.PHONY: dep
-dep:
- if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
- @trcsources=$(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc);\
- if [ ! -z "$$trcsources" ]; then\
- trctargets=$$(tranche-target $$trcsources -sep " " -tdir $(SRCDIR) );\
- $(ECHO) $$trcsources;\
- tranche-make $$trcsources -tdir $(SRCDIR) -mfile $(DEPFILE);\
- $(MAKE) $$trctargets;\
- fi
- $(MAKE) $@
-
-.PHONY: lib
-lib:
- cp $(SRCDIR)/dispatch.lib.h $(INCDIR)/dispatch.h
- $(MAKE) $@
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/dispatch/makefile-flags b/module/dispatch/makefile-flags
deleted file mode 100644
index a50b71c..0000000
--- a/module/dispatch/makefile-flags
+++ /dev/null
@@ -1,31 +0,0 @@
-
-MODULE=dispatch
-
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=../share
-SRCDIR=tmp
-TESTDIR=test
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRCDIR=trc
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-trc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# compiler and flags
-C=gcc
-CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
-LINKFLAGS=-L$(LIBDIR) -L(SHAREDIR)/lib -ldebug
-
-
-
diff --git a/module/dispatch/tranche b/module/dispatch/tranche
deleted file mode 100755
index ad95624..0000000
Binary files a/module/dispatch/tranche and /dev/null differ
diff --git a/module/dispatch/trc/dispatch.trc.c b/module/dispatch/trc/dispatch.trc.c
deleted file mode 100644
index f08602c..0000000
--- a/module/dispatch/trc/dispatch.trc.c
+++ /dev/null
@@ -1,171 +0,0 @@
-#tranche dispatch.lib.c
-
-#tranche dispatch.lib.h
- /*
- Runs a command or function as its own process.
-
- The return status integer from command or function must be greater than ERR_DISPATCH.
- In the case of dispatch_exec, we only have a promise from the user to not dispatch
- non compliant commands.
-
- */
- #ifndef DISPATCH_LIB_H
- #define DISPATCH_LIB_H
- #include
- #include
-
- #define ERR_DISPATCH -1024
- #define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
- #define ERR_DISPATCH_F_FORK -1025
- #define ERR_DISPATCH_F_SETEUID -1026
- #define ERR_DISPATCH_F_SETEGID -1027
- #define ERR_DISPATCH_NULL_EXECUTABLE -1028
- #define ERR_DISPATCH_EXEC -1029
-
- // currently both dispatcher and dispatchee strings are statically allocated
- struct dispatch_ctx{
- char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
- char *dispatchee; // name of the function being dispatched
- int err; // error code as listed below, or status returned from dispatchee
- };
-#tranche-end
-
-
-// we need the declaration for uid_t etc.
-// without this #define execvpe is undefined
-#define _GNU_SOURCE
-
-#include
-#include
-#include
-#include
-#include
-#include "dispatch.lib.h"
-
-#tranche dispatch.lib.h
-void dispatch_f_mess(char *fname, int err, char *dispatchee);
-#tranche-end
-void dispatch_f_mess(char *fname, int err, char *dispatchee){
- if(err == 0) return;
- fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
- if(err > ERR_DISPATCH){
- fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
- return;
- }
- switch(err){
- case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
- fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
- break;
- case ERR_DISPATCH_F_FORK:
- case ERR_DISPATCH_F_SETEUID:
- case ERR_DISPATCH_F_SETEGID:
- fputc(' ', stderr);
- perror(dispatchee);
- break;
- case ERR_DISPATCH_NULL_EXECUTABLE:
- fprintf(stderr, " executable was not specified");
- break;
- case ERR_DISPATCH_EXEC:
- // exec is running in another process when it fails, so we can't see the errno value it set
- fprintf(stderr, " exec of \"%s\" failed", dispatchee);
- break;
- default:
- fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
- }
- fputc('\n', stderr);
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a function
-#tranche dispatch.lib.h
-int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
-#tranche-end
-int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
- #ifdef DEBUG
- debug_printf("%s %s\n", "dispatch_f", fname);
- #endif
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
- if( pid == 0 ){ // we are the child
- int status = (*f)(f_arg); // we require that f return a zero or positive value
- if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
- exit(status);
- }else{ // we are the parent
- int err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a function with a given euid/egid
-// of course this will only work if our euid is root in the first place
-#tranche dispatch.lib.h
-int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
-#tranche-end
-int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
- #ifdef DEBUG
- debug_printf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
- #endif
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK;
- if( pid == 0 ){ // we are the child
- int status;
- if( seteuid(euid) == -1 )
- status = ERR_DISPATCH_F_SETEUID;
- else if( setegid(egid) == -1 )
- status = ERR_DISPATCH_F_SETEGID;
- else{
- status = (*f)(f_arg);
- if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
- exit(status);
- }
- }else{ // we are the parent
- uint err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-//--------------------------------------------------------------------------------
-// interface call point, dispatch a executable
-#tranche dispatch.lib.h
-int dispatch_exec(char **argv, char **envp);
-#tranche-end
-int dispatch_exec(char **argv, char **envp){
- char *command;
- {
- if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
- #ifdef DEBUG
- debug_printf("dispatch_exec:");
- char **apt = argv;
- while( *apt ){
- debug_printf(" %s",*apt);
- apt++;
- }
- debug_printf("\n");
- #endif
- command = argv[0];
- }
- pid_t pid = fork();
- if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
- if( pid == 0 ){ // we are the child
- execvpe(command, argv, envp); // exec will only return if it has an error
- #ifdef DEBUG
- debug_printf("dispatch_exec: exec returned, perror message:");
- perror("dispatch_exec"); // our only chance to print this message, as this is the child process
- #endif
- fflush(stdout);
- exit(ERR_DISPATCH_EXEC);
- }else{ // we are the parent
- int err;
- waitpid(pid, &err, 0);
- return err;
- }
-}
-
-#tranche dispatch.lib.h
-#endif
-#tranche-end
-
-#tranche-end
diff --git a/module/share/include/da.h b/module/share/include/da.h
deleted file mode 100644
index 9043cda..0000000
--- a/module/share/include/da.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef DA_LIB_H
-#define DA_LIB_H
-#include
-#include
-#include
-
-typedef struct {
- char *base;
- char *end; // one byte/one element off the end of the array
- size_t size; // size >= (end - base) + 1;
- size_t element_size;
-} Da;
-
-//#include "da_na.lib.h"
-
-#define RETURN(dap, r) \
- { da_free_elements(dap); return r; }
-
-
-void da_alloc(Da *dap, size_t element_size);
-void da_free(Da *dap);
-void da_rewind(Da *dap);
-bool da_empty(Da *dap);
-size_t da_length(Da *dap);
-void da_rebase(Da *dap, char *old_base, void *pta);
-char *da_expand(Da *dap);
-bool da_boundq(Da *dap);
-
-char *da_index(Da *dap, size_t i);
-char *da_push_alloc(Da *dap);
-char *da_push(Da *dap, void *element);
-bool da_pop(Da *dap, void *element);
-
-bool da_endq(Da *dap, void *pt);
-void da_map(Da *dap, void f(void *, void *), void *closure);
-
-void da_free_elements(Da *dap);
-
-void da_ints_print(Da *dap, char *sep);
-bool da_integer_repeats(Da *dap);
-int da_integer_sum(Da *dap);
-
-
-void da_strings_print(Da *dap, char *sep);
-
-bool da_strings_exists(Da *string_arrp, char *test_string);
-void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
-void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
-
-
-char *da_string_input(Da *dap, FILE *file);
-void da_string_push(Da *dap0, char *string);
-
-void da_cat(Da *dap_base, Da *dap_cat);
-
-void da_present(Da **dar, int dar_size, void *closure);
-bool da_equal(Da *da_el, Da *test_el);
-void da_matrix_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
-
-bool da_exists(Da *dap, bool f(void *, void*), void *closure);
-bool da_all(Da *dap, bool f(void *, void*), void *closure);
-
-//matrix functions
-void da_erase(Da *damp);
-Da *da_push_row_alloc(Da *damp);
-Da *da_push_row(Da *damp, Da *dap);
-void da_push_column(Da *damp, Da *dap, void *fill);
-
-void da_every_row(Da *damp, void f(void *, void *), void *closure);
-Da *da_longer(Da *dap0, Da *dap1);
-Da *da_longest(Da *damp);
-void da_every_column(Da *damp, void f(void *, void *), void *closure);
-
-Da *da_matrix_transpose(Da *damp, void *fill);
-
-bool da_length_equal(Da *dap0, Da *dap1);
-bool da_all_rows_same_length(Da *damp);
-bool da_integer_all_rows_repeat(Da *damp);
-bool da_integer_all_columns_repeat(Da *damp);
-bool da_integer_repeats_matrix(Da *damp);
-
-Da *da_integer_transpose(Da *damp, int *fill);
-int *da_integer_to_raw_image_matrix(Da *damp, int fill);
-int *da_integer_to_raw_image_transpose(Da *damp, int fill);
-
-
-/*
-Accounting for all the pointers for which we allocated memory on the heap.
-
-Replacement for malloc and free that allows us to check if all the memory we allocated was freed, and if all the memory we tried to free was actually allocated by keeping registers of pointers in Da structs.
- */
-
-#define MALLOC da_malloc_counted
-#define FREE da_free_counted
-#define ACCOUNT da_start_accounting()
-#define BALANCE da_result_accounting()
-#define CLOSE_ACC da_na_free(&heap_acc); da_na_free(&extra_frees)
-
-//These variables must be declared at global scope in file that will use them.
-extern Da heap_acc; extern Da extra_frees; extern bool accounting;
-
-void da_start_accounting();
-void *da_malloc_counted(size_t mem_size);
-void da_free_counted(void *pt);
-bool da_result_accounting(void);
-
-char *da_na_expand(Da *dap);
-char *da_na_push_alloc(Da *dap);
-char *da_na_push(Da *dap, void *element);
-void da_na_free(Da *dap);
-
-
-#endif
-
diff --git a/module/share/include/debug.h b/module/share/include/debug.h
deleted file mode 100644
index f1be3d8..0000000
--- a/module/share/include/debug.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef DB_LIB_H
-#define DB_LIB_H
-
-int debug_printf(const char *format, ...);
-
-#endif
diff --git a/module/share/include/dispatch.h b/module/share/include/dispatch.h
deleted file mode 100644
index 8b99d43..0000000
--- a/module/share/include/dispatch.h
+++ /dev/null
@@ -1,32 +0,0 @@
- /*
- Runs a command or function as its own process.
-
- The return status integer from command or function must be greater than ERR_DISPATCH.
- In the case of dispatch_exec, we only have a promise from the user to not dispatch
- non compliant commands.
-
- */
- #ifndef DISPATCH_LIB_H
- #define DISPATCH_LIB_H
- #include
- #include
-
- #define ERR_DISPATCH -1024
- #define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
- #define ERR_DISPATCH_F_FORK -1025
- #define ERR_DISPATCH_F_SETEUID -1026
- #define ERR_DISPATCH_F_SETEGID -1027
- #define ERR_DISPATCH_NULL_EXECUTABLE -1028
- #define ERR_DISPATCH_EXEC -1029
-
- // currently both dispatcher and dispatchee strings are statically allocated
- struct dispatch_ctx{
- char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
- char *dispatchee; // name of the function being dispatched
- int err; // error code as listed below, or status returned from dispatchee
- };
-void dispatch_f_mess(char *fname, int err, char *dispatchee);
-int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
-int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
-int dispatch_exec(char **argv, char **envp);
-#endif
diff --git a/module/share/include/subu.h b/module/share/include/subu.h
deleted file mode 100644
index 5a82782..0000000
--- a/module/share/include/subu.h
+++ /dev/null
@@ -1,63 +0,0 @@
- typedef unsigned int uint;
- /*
- Fedora 29's sss_cache is checking the inherited uid instead of the effective
- uid, so setuid root scripts will fail when calling sss_cache.
-
- Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root
- program subu-mk-0.
- */
- #define BUG_SSS_CACHE_RUID 1
- // extern char *DB_File;
- extern char DB_File[];
- extern uint Subuhome_Perms;
- extern uint First_Max_Subunumber;
- extern char Subuland_Extension[];
- /*
- The db file is maintained in SQLite
-
- Because linux user names are limited length, subu user names are of a compact
- form: _s. A separate table translates the numbers into the subu names.
-
- Each of these returns SQLITE_OK upon success
- */
- #include
- #include
- int db_begin(sqlite3 *db);
- int db_commit(sqlite3 *db);
- int db_rollback(sqlite3 *db);
- int subudb_schema(sqlite3 *db);
- int subudb_number_get(sqlite3 *db, int *n);
- int subudb_number_set(sqlite3 *db, int n);
- int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
- int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username);
- typedef struct{
- char *subuname; // the name that masteru chose for his or her subu
- char *subu_username; // the adduser name we gave it, typically of the s
- } subudb_subu_element;
- int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subus);
- int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
- #include
- #include
- #include
- char *useradd_mess(int err);
- char *userdel_mess(int err);
- #define SUBU_ERR_ARG_CNT 1
- #define SUBU_ERR_SETUID_ROOT 2
- #define SUBU_ERR_MALLOC 3
- #define SUBU_ERR_MKDIR_SUBUHOME 4
- #define SUBU_ERR_RMDIR_SUBUHOME 5
- #define SUBU_ERR_SUBUNAME_MALFORMED 6
- #define SUBU_ERR_HOMELESS 7
- #define SUBU_ERR_DB_FILE 8
- #define SUBU_ERR_SUBUHOME_EXISTS 9
- #define SUBU_ERR_BUG_SSS 10
- #define SUBU_ERR_FAILED_USERADD 11
- #define SUBU_ERR_FAILED_USERDEL 12
- #define SUBU_ERR_SUBU_NOT_FOUND 13
- #define SUBU_ERR_N 14
- #define SUBU_ERR_BIND 15
- void subu_err(char *fname, int err, char *mess);
- int subu_mk_0(char **mess, sqlite3 *db, char *subuname);
- int subu_rm_0(char **mess, sqlite3 *db, char *subuname);
- int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome);
- int subu_bind_all(char **mess, sqlite3 *db);
diff --git a/module/share/include/tranche.h b/module/share/include/tranche.h
deleted file mode 100644
index 4c1d2f3..0000000
--- a/module/share/include/tranche.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef TRANCHE_LIB_H
-#define TRANCHE_LIB_H
-
-#define TRANCHE_ERR_ARGC 1
-#define TRANCHE_ERR_SRC_OPEN 2
-#define TRANCHE_ERR_DEP_OPEN 4
-
-int tranche_send(FILE *src, Da *arg_fds);
-int tranche_target(FILE *src, Da *targets);
-
-
-#endif
diff --git a/module/share/lib b/module/share/lib
deleted file mode 100644
index eb95acc..0000000
Binary files a/module/share/lib and /dev/null differ
diff --git a/module/subu-0/deprecated/0_makefile b/module/subu-0/deprecated/0_makefile
deleted file mode 100644
index f0708ef..0000000
--- a/module/subu-0/deprecated/0_makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-# src/0_makefile
-
-SHELL=/bin/bash
-
--include 0_makefile_flags
-
-SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh
-MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc
-
-SOURCES=$(wildcard *.c)
-HFILES=$(wildcard *.h)
-
-all: version deps lib execs
-
-version:
- $(MAKE) $@
- @echo "SUID_TOOL: " $(SUID_TOOL)
-
-deps:
- makeheaders $(SOURCES) $(HFILES)
- sed -i '/^ *int *main *(.*)/d' *.h
- $(MAKE) $@
-
-execs:
- $(MAKE) $@
- @echo "-> $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all"
- cat $(SUID_TOOL)
- @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ]
- sudo $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all
-
-clean:
- $(MAKE) $@
- for i in $(HFILES); do rm $$i; done
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/subu-0/deprecated/0_makefile-flags b/module/subu-0/deprecated/0_makefile-flags
deleted file mode 100644
index d4df01f..0000000
--- a/module/subu-0/deprecated/0_makefile-flags
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# directories used by this makefile, these could all be set to dot for
-# the simplest source directory structure
-
-#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared
-#$(PWD) is the directory that make was called from, this is already build in
-#set to dot to use the same directory as the source code
-#leave blank to ommit
-DEPRDIR=1_deprecated
-DOCDIR=1_doc
-EXECSDIR=1_execs
-HDIR=1_headers
-LIBDIR=1_lib
-TESTDIR=1_tests
-TMPDIR=1_tmp
-TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools)
-TRYDIR=1_try
-
-
-# compiler and flags
-CC=gcc
-CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB
-#CFLAGS=-std=gnu11 -fPIC -I. -Werror
-LINKFLAGS=-L1_lib -lsubu -lsqlite3
-
-LIBFILE=$(LIBDIR)/libsubu.a
-
diff --git a/module/subu-0/deprecated/1_tmp/da.lib.h b/module/subu-0/deprecated/1_tmp/da.lib.h
deleted file mode 100644
index 4702189..0000000
--- a/module/subu-0/deprecated/1_tmp/da.lib.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-#include
-void daps_map(char **base,char **end_pt,void f(void *));
-#define RETURN(rc) \
- { daps_map(mrs, mrs_end, free); return rc; }
-void daps_alloc(char ***base,size_t *s);
-#define MK_MRS \
- char **mrs; \
- char **mrs_end; \
- size_t mrs_size; \
- daps_alloc(&mrs, &mrs_size);\
- mrs_end = mrs;
-void daps_push(char ***base,char ***pt,size_t *s,char *item);
-bool daps_bound(char **base,char **pt,size_t s);
-void daps_expand(char ***base,char ***pt,size_t *s);
-void da_map(void *base,void *end_pt,void f(void *),size_t item_size);
-void da_push(void **base,void **pt,size_t *s,void *item,size_t item_size);
-bool da_bound(void *base,void *pt,size_t s);
-void da_expand(void **base,void **pt,size_t *s);
-void da_alloc(void **base,size_t *s,size_t item_size);
-#define INTERFACE 0
diff --git a/module/subu-0/deprecated/1_tmp/dbprintf.lib.h b/module/subu-0/deprecated/1_tmp/dbprintf.lib.h
deleted file mode 100644
index 3056cf6..0000000
--- a/module/subu-0/deprecated/1_tmp/dbprintf.lib.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-int dbprintf(const char *format,...);
diff --git a/module/subu-0/deprecated/1_tmp/dispatch.lib.h b/module/subu-0/deprecated/1_tmp/dispatch.lib.h
deleted file mode 100644
index 07e2271..0000000
--- a/module/subu-0/deprecated/1_tmp/dispatch.lib.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-#include
-int dispatch_exec(char **argv,char **envp);
-typedef unsigned int uint;
-int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid);
-int dbprintf(const char *format,...);
-int dispatch_f(char *fname,int(*f)(void *arg),void *f_arg);
-void dispatch_f_mess(char *fname,int err,char *dispatchee);
-#define ERR_DISPATCH_EXEC -1029
-#define ERR_DISPATCH_NULL_EXECUTABLE -1028
-#define ERR_DISPATCH_F_SETEGID -1027
-#define ERR_DISPATCH_F_SETEUID -1026
-#define ERR_DISPATCH_F_FORK -1025
-#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
-#define ERR_DISPATCH -1024
-typedef struct dispatch_ctx dispatch_ctx;
-struct dispatch_ctx {
- char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
- char *dispatchee; // name of the function being dispatched
- int err; // error code as listed below, or status returned from dispatchee
-};
-#define INTERFACE 0
diff --git a/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h b/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h
deleted file mode 100644
index 7e52675..0000000
--- a/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-#include
-#include
-int subu_bind_all(char **mess,sqlite3 *db);
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subu-bind.cli.h b/module/subu-0/deprecated/1_tmp/subu-bind.cli.h
deleted file mode 100644
index af12d61..0000000
--- a/module/subu-0/deprecated/1_tmp/subu-bind.cli.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-#include
-#include
-int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome);
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subu-common.lib.h b/module/subu-0/deprecated/1_tmp/subu-common.lib.h
deleted file mode 100644
index cfdc520..0000000
--- a/module/subu-0/deprecated/1_tmp/subu-common.lib.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-extern char Subuland_Extension[];
-typedef unsigned int uint;
-extern uint First_Max_Subunumber;
-extern uint Subuhome_Perms;
-extern char DB_File[];
-#define BUG_SSS_CACHE_RUID 1
-#define INTERFACE 0
diff --git a/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h b/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h
deleted file mode 100644
index 487b509..0000000
--- a/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-#include
-#include
-void subu_err(char *fname,int err,char *mess);
-int subu_mk_0(char **mess,sqlite3 *db,char *subuname);
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h b/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h
deleted file mode 100644
index 070bfe8..0000000
--- a/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-#include
-#include
-void subu_err(char *fname,int err,char *mess);
-int subu_rm_0(char **mess,sqlite3 *db,char *subuname);
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subu.lib.h b/module/subu-0/deprecated/1_tmp/subu.lib.h
deleted file mode 100644
index 69c5da7..0000000
--- a/module/subu-0/deprecated/1_tmp/subu.lib.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-typedef unsigned int uint;
-#include
-typedef struct subudb_subu_element subudb_subu_element;
-int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt);
-struct subudb_subu_element {
- char *subuname;
- char *subu_username;
-};
-#include
-#include
-int subu_bind_all(char **mess,sqlite3 *db);
-int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome);
-int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
-int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username);
-int subu_rm_0(char **mess,sqlite3 *db,char *subuname);
-int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
-#include
-#include
-int dispatch_exec(char **argv,char **envp);
-#define BUG_SSS_CACHE_RUID 1
-void dispatch_f_mess(char *fname,int err,char *dispatchee);
-#define ERR_DISPATCH -1024
-int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid);
-#include
-void daps_map(char **base,char **end_pt,void f(void *));
-#define RETURN(rc) \
- { daps_map(mrs, mrs_end, free); return rc; }
-void daps_push(char ***base,char ***pt,size_t *s,char *item);
-int dbprintf(const char *format,...);
-void daps_alloc(char ***base,size_t *s);
-#define MK_MRS \
- char **mrs; \
- char **mrs_end; \
- size_t mrs_size; \
- daps_alloc(&mrs, &mrs_size);\
- mrs_end = mrs;
-int subu_mk_0(char **mess,sqlite3 *db,char *subuname);
-extern char Subuland_Extension[];
-int db_commit(sqlite3 *db);
-int db_rollback(sqlite3 *db);
-int subudb_number_set(sqlite3 *db,int n);
-int subudb_number_get(sqlite3 *db,int *n);
-int db_begin(sqlite3 *db);
-extern uint Subuhome_Perms;
-extern char DB_File[];
-void subu_err(char *fname,int err,char *mess);
-#define SUBU_ERR_BIND 15
-#define SUBU_ERR_N 14
-#define SUBU_ERR_SUBU_NOT_FOUND 13
-#define SUBU_ERR_FAILED_USERDEL 12
-#define SUBU_ERR_FAILED_USERADD 11
-#define SUBU_ERR_BUG_SSS 10
-#define SUBU_ERR_SUBUHOME_EXISTS 9
-#define SUBU_ERR_DB_FILE 8
-#define SUBU_ERR_HOMELESS 7
-#define SUBU_ERR_SUBUNAME_MALFORMED 6
-#define SUBU_ERR_RMDIR_SUBUHOME 5
-#define SUBU_ERR_MKDIR_SUBUHOME 4
-#define SUBU_ERR_MALLOC 3
-#define SUBU_ERR_SETUID_ROOT 2
-#define SUBU_ERR_ARG_CNT 1
-char *userdel_mess(int err);
-char *useradd_mess(int err);
-#define INTERFACE 0
diff --git a/module/subu-0/deprecated/1_tmp/subudb-init.cli.h b/module/subu-0/deprecated/1_tmp/subudb-init.cli.h
deleted file mode 100644
index 4435103..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb-init.cli.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-int db_commit(sqlite3 *db);
-int db_rollback(sqlite3 *db);
-int subudb_schema(sqlite3 *db);
-int db_begin(sqlite3 *db);
-#include
-#include
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
diff --git a/module/subu-0/deprecated/1_tmp/subudb-number.cli.h b/module/subu-0/deprecated/1_tmp/subudb-number.cli.h
deleted file mode 100644
index c130fbb..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb-number.cli.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-int subudb_number_get(sqlite3 *db,int *n);
-int subudb_number_set(sqlite3 *db,int n);
-#include
-#include
-#define SUBU_ERR_N 14
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h b/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h
deleted file mode 100644
index 4f335be..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username);
-#include
-#include
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h b/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h
deleted file mode 100644
index 243b3a9..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
-#include
-#include
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
diff --git a/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h b/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h
deleted file mode 100644
index 595427f..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
-#include
-#include
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
diff --git a/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h b/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h
deleted file mode 100644
index 16310b7..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-typedef struct subudb_subu_element subudb_subu_element;
-int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt);
-struct subudb_subu_element {
- char *subuname;
- char *subu_username;
-};
-#include
-#include
-#define SUBU_ERR_DB_FILE 8
-extern char DB_File[];
-#define SUBU_ERR_ARG_CNT 1
diff --git a/module/subu-0/deprecated/1_tmp/subudb.lib.h b/module/subu-0/deprecated/1_tmp/subudb.lib.h
deleted file mode 100644
index be73823..0000000
--- a/module/subu-0/deprecated/1_tmp/subudb.lib.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-#include
-int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
-#include
-#include
-void da_expand(void **base,void **pt,size_t *s);
-bool da_bound(void *base,void *pt,size_t s);
-typedef struct subudb_subu_element subudb_subu_element;
-int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt);
-void subu_element_free(subudb_subu_element *base,subudb_subu_element *end_pt);
-void da_alloc(void **base,size_t *s,size_t item_size);
-struct subudb_subu_element {
- char *subuname;
- char *subu_username;
-};
-int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username);
-int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
-int subudb_number_set(sqlite3 *db,int n);
-int subudb_number_get(sqlite3 *db,int *n);
-typedef unsigned int uint;
-extern uint First_Max_Subunumber;
-int subudb_schema(sqlite3 *db);
-int db_rollback(sqlite3 *db);
-int db_commit(sqlite3 *db);
-int db_begin(sqlite3 *db);
-#define INTERFACE 0
diff --git a/module/subu-0/doc/todo.txt b/module/subu-0/doc/todo.txt
deleted file mode 100644
index 3631ba1..0000000
--- a/module/subu-0/doc/todo.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-2019-02-05T23:14:40Z
- error can cause subu-mk-0 to leave the creating of a subu in an intermediate
- state. Rather than bailing on some of the errors we need to clean up instead.
- Perhaps the yet to be written subu-rm program will be resilent enough to do
- more general cleanup.
-
-2019-02-23T18:56:31Z
- need to modify subu-init to take a configuration file name argument instead of
- using a global variabel value. might want to add arguments to other subu
- commands also
-
-2019-03-11T13:48:03Z
- in subu.lib.c append cascading rmdir failure mess to useradd failure mess
-
-2019-03-11T13:48:03Z
- want to add subu-type to masteru_subu(), I imagine there will be static,
- permanent, and temporary subu types.
-
-2019-03-12T18:35:06Z
- the masteru subu relation should contain the uid of the masteru as
- well as the backup type for the subu: git, rdiff, rsync, none.
- and the persisitance fo the subu: indefinite, session.
- seems that operations need to be logged, in case the db is lost
- the transcript can be played back. It should also be possible
- to co-opt an existing user as a subu, though, would require
- sudo privs.
-
- need to add messages for subu errors I've added to the end of
- the list in subu.lib.c
-
-2019-03-14T10:43:50Z
-
- should mod all to he subudb routines to return a message, probably
- strdup(sqlite_errmsg(db)), then the callers to these routines can just pass
- mess in rather than making up new ones for each situation. The error code
- probably already carries the contexts specific message. Or perhaps add
- a string cat function for message strings, that would run through a stream
- and free the originals.
-
-2019-04-02T19:24:03Z
- Really need to add a transcript to help recover if there are any problems.
diff --git a/module/subu-0/exec/subu-bind b/module/subu-0/exec/subu-bind
deleted file mode 100755
index 6e4b6fd..0000000
Binary files a/module/subu-0/exec/subu-bind and /dev/null differ
diff --git a/module/subu-0/exec/subu-bind-all b/module/subu-0/exec/subu-bind-all
deleted file mode 100755
index 5d29017..0000000
Binary files a/module/subu-0/exec/subu-bind-all and /dev/null differ
diff --git a/module/subu-0/exec/subu-mk-0 b/module/subu-0/exec/subu-mk-0
deleted file mode 100755
index 0889e0e..0000000
Binary files a/module/subu-0/exec/subu-mk-0 and /dev/null differ
diff --git a/module/subu-0/exec/subu-rm-0 b/module/subu-0/exec/subu-rm-0
deleted file mode 100755
index f68421d..0000000
Binary files a/module/subu-0/exec/subu-rm-0 and /dev/null differ
diff --git a/module/subu-0/exec/subudb-init b/module/subu-0/exec/subudb-init
deleted file mode 100755
index 6d26441..0000000
Binary files a/module/subu-0/exec/subudb-init and /dev/null differ
diff --git a/module/subu-0/exec/subudb-number b/module/subu-0/exec/subudb-number
deleted file mode 100755
index dd78319..0000000
Binary files a/module/subu-0/exec/subudb-number and /dev/null differ
diff --git a/module/subu-0/exec/subudb-rel-get b/module/subu-0/exec/subudb-rel-get
deleted file mode 100755
index 7093dab..0000000
Binary files a/module/subu-0/exec/subudb-rel-get and /dev/null differ
diff --git a/module/subu-0/exec/subudb-rel-put b/module/subu-0/exec/subudb-rel-put
deleted file mode 100755
index 4ddb70f..0000000
Binary files a/module/subu-0/exec/subudb-rel-put and /dev/null differ
diff --git a/module/subu-0/exec/subudb-rel-rm b/module/subu-0/exec/subudb-rel-rm
deleted file mode 100755
index 4284dcb..0000000
Binary files a/module/subu-0/exec/subudb-rel-rm and /dev/null differ
diff --git a/module/subu-0/exec/subudb-subus b/module/subu-0/exec/subudb-subus
deleted file mode 100755
index 8a2a01b..0000000
Binary files a/module/subu-0/exec/subudb-subus and /dev/null differ
diff --git a/module/subu-0/include/subu.h b/module/subu-0/include/subu.h
deleted file mode 100644
index 5a82782..0000000
--- a/module/subu-0/include/subu.h
+++ /dev/null
@@ -1,63 +0,0 @@
- typedef unsigned int uint;
- /*
- Fedora 29's sss_cache is checking the inherited uid instead of the effective
- uid, so setuid root scripts will fail when calling sss_cache.
-
- Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root
- program subu-mk-0.
- */
- #define BUG_SSS_CACHE_RUID 1
- // extern char *DB_File;
- extern char DB_File[];
- extern uint Subuhome_Perms;
- extern uint First_Max_Subunumber;
- extern char Subuland_Extension[];
- /*
- The db file is maintained in SQLite
-
- Because linux user names are limited length, subu user names are of a compact
- form: _s. A separate table translates the numbers into the subu names.
-
- Each of these returns SQLITE_OK upon success
- */
- #include
- #include
- int db_begin(sqlite3 *db);
- int db_commit(sqlite3 *db);
- int db_rollback(sqlite3 *db);
- int subudb_schema(sqlite3 *db);
- int subudb_number_get(sqlite3 *db, int *n);
- int subudb_number_set(sqlite3 *db, int n);
- int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
- int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username);
- typedef struct{
- char *subuname; // the name that masteru chose for his or her subu
- char *subu_username; // the adduser name we gave it, typically of the s
- } subudb_subu_element;
- int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subus);
- int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
- #include
- #include
- #include
- char *useradd_mess(int err);
- char *userdel_mess(int err);
- #define SUBU_ERR_ARG_CNT 1
- #define SUBU_ERR_SETUID_ROOT 2
- #define SUBU_ERR_MALLOC 3
- #define SUBU_ERR_MKDIR_SUBUHOME 4
- #define SUBU_ERR_RMDIR_SUBUHOME 5
- #define SUBU_ERR_SUBUNAME_MALFORMED 6
- #define SUBU_ERR_HOMELESS 7
- #define SUBU_ERR_DB_FILE 8
- #define SUBU_ERR_SUBUHOME_EXISTS 9
- #define SUBU_ERR_BUG_SSS 10
- #define SUBU_ERR_FAILED_USERADD 11
- #define SUBU_ERR_FAILED_USERDEL 12
- #define SUBU_ERR_SUBU_NOT_FOUND 13
- #define SUBU_ERR_N 14
- #define SUBU_ERR_BIND 15
- void subu_err(char *fname, int err, char *mess);
- int subu_mk_0(char **mess, sqlite3 *db, char *subuname);
- int subu_rm_0(char **mess, sqlite3 *db, char *subuname);
- int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome);
- int subu_bind_all(char **mess, sqlite3 *db);
diff --git a/module/subu-0/makefile b/module/subu-0/makefile
deleted file mode 100644
index c12df9c..0000000
--- a/module/subu-0/makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-# src-dispatch/makefile
-
-SHELL=/bin/bash
-MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
--include makefile-flags
-
-.PHONY: all
-all: version
-
-.PHONY: info
-info:
- @echo "TRCDIR: " $(TRCDIR)
- @echo "SHAREDIR: " $(SHAREDIR)
- $(MAKE) $@
-
-.PHONY: setup
-setup:
- [ ! -e $(TRCDIR) ] && mkdir $(TRCDIR) || true
- $(MAKE) $@
-
-.PHONY: dep
-dep:
- if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
- trcsources=($(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc));\
- if [ ! -z "$$trcsources" ]; then\
- trctargets=$$(tranche-target $${trcsources[@]} -sep " " -tdir $(SRCDIR) );\
- $(ECHO) "trcsources: " $${trcsources[@]};\
- $(ECHO) "trctargets: " $$trctargets;\
- tranche-make $${trcsources[@]} -tdir $(SRCDIR) -mfile $(DEPFILE);\
- $(MAKE) $$trctargets;\
- fi
- $(MAKE) $@
-
-.PHONY: exec
-exec:
- $(MAKE) $@
-
-.PHONY: lib
-lib:
- cp $(SRCDIR)/common.lib.h $(INCDIR)/subu.h
- cat $(SRCDIR)/subudb.lib.h >> $(INCDIR)/subu.h
- cat $(SRCDIR)/subu.lib.h >> $(INCDIR)/subu.h
- $(MAKE) $@
-
-%::
- @echo default target
- $(MAKE) $@
-
-
-
-
diff --git a/module/subu-0/makefile-flags b/module/subu-0/makefile-flags
deleted file mode 100644
index ae748ac..0000000
--- a/module/subu-0/makefile-flags
+++ /dev/null
@@ -1,28 +0,0 @@
-
-MODULE=subu-0
-
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
-SRCDIR=tmp
-TESTDIR=test
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRCDIR=trc
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-trc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# compiler and flags
-C=gcc
-CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
-LINKFLAGS=-L$(LIBDIR) -L$(SHAREDIR)/lib/ -l$(MODULE) -lda -ldispatch -ldebug -lsqlite3
diff --git a/module/subu-0/trc/common.trc.c b/module/subu-0/trc/common.trc.c
deleted file mode 100644
index fec4853..0000000
--- a/module/subu-0/trc/common.trc.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#tranche common.lib.c
-#include "common.lib.h"
-
-#tranche common.lib.h
- typedef unsigned int uint;
- /*
- Fedora 29's sss_cache is checking the inherited uid instead of the effective
- uid, so setuid root scripts will fail when calling sss_cache.
-
- Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root
- program subu-mk-0.
- */
- #define BUG_SSS_CACHE_RUID 1
-#tranche-end
-
-#tranche common.lib.h
- // extern char *DB_File;
- extern char DB_File[];
- extern uint Subuhome_Perms;
- extern uint First_Max_Subunumber;
- extern char Subuland_Extension[];
-#tranche-end
-// char *DB_File = "/etc/subudb";
-char DB_File[] = "subudb";
-uint Subuhome_Perms = 0700;
-uint First_Max_Subunumber = 114;
-char Subuland_Extension[] = "/subuland/";
-
-#tranche-end
diff --git a/module/subu-0/trc/subu-bind-all.trc.c b/module/subu-0/trc/subu-bind-all.trc.c
deleted file mode 100644
index 66dfe19..0000000
--- a/module/subu-0/trc/subu-bind-all.trc.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#tranche subu-bind-all.cli.c
-/*
-mount all the subu user directories into master's subuland
-uses unmount to undo this
-
-*/
-#include
-#include
-#include "common.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
- if( argc != 1){
- fprintf(stderr, "%s does not take arguments\n",argv[0]);
- return SUBU_ERR_ARG_CNT;
- }
-
- int rc;
- sqlite3 *db;
- rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
- return SUBU_ERR_DB_FILE;
- }
-
- char *mess;
- rc = subu_bind_all(&mess, db);
- if(rc != 0){
- fprintf(stderr, "subu-bind: %s\n", mess);
- return rc;
- }
- return 0;
-}
-#tranche-end
diff --git a/module/subu-0/trc/subu-bind.trc.c b/module/subu-0/trc/subu-bind.trc.c
deleted file mode 100644
index 93ce926..0000000
--- a/module/subu-0/trc/subu-bind.trc.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#tranche subu-bind.cli.c
-/*
-mount a subu user directory into master's subuland
-uses unmount to undo this
-
-*/
-#include
-#include
-#include
-#include "common.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
-
- if( argc != 4){
- fprintf(stderr, "usage: %s masteru subu_username subuhome\n",argv[0]);
- return SUBU_ERR_ARG_CNT;
- }
-
- int rc;
- char *mess;
- rc = subu_bind(&mess, argv[1], argv[2], argv[3]);
- if(rc != 0){
- fprintf(stderr, "subu-bind: %s\n", mess);
- return rc;
- }
- return 0;
-}
-#tranche-end
diff --git a/module/subu-0/trc/subu-mk-0.trc.c b/module/subu-0/trc/subu-mk-0.trc.c
deleted file mode 100644
index 0ae869b..0000000
--- a/module/subu-0/trc/subu-mk-0.trc.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#tranche subu-mk-0.cli.c
-/*
- subu-mk-0 command
-
-*/
-#include
-#include
-#include
-#include "common.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
- char *command = argv[0];
- if( argc != 2 ){
- fprintf(stderr, "usage: %s subu", command);
- return SUBU_ERR_ARG_CNT;
- }
- char *subuname = argv[1];
-
- int rc;
- sqlite3 *db;
- rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "error when opening db, %s\n", DB_File);
- fprintf(stderr, "sqlite3 says: %s\n", sqlite3_errmsg(db));
- sqlite3_close(db);
- return SUBU_ERR_DB_FILE;
- }
-
- char *mess;
- rc = subu_mk_0(&mess, db, subuname);
- if( rc ){
- subu_err("subu_mk_0", rc, mess);
- free(mess);
- sqlite3_close(db);
- return rc;
- }
-
- rc = sqlite3_close(db);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- return 0;
-
-}
-#tranche-end
diff --git a/module/subu-0/trc/subu-rm-0.trc.c b/module/subu-0/trc/subu-rm-0.trc.c
deleted file mode 100644
index f7fa21b..0000000
--- a/module/subu-0/trc/subu-rm-0.trc.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#tranche subu-rm-0.cli.c
-/*
- subu-mk-0 command
-
-*/
-#include
-#include
-#include "common.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
- char *command = argv[0];
- if( argc != 2 ){
- fprintf(stderr, "usage: %s subu", command);
- return SUBU_ERR_ARG_CNT;
- }
- char *subuname = argv[1];
-
- sqlite3 *db;
- {
- int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File);
- return SUBU_ERR_DB_FILE;
- }}
-
- {
- char *mess=0;
- int ret = subu_rm_0(&mess, db, subuname);
- subu_err("subu_rm_0", ret, mess);
- free(mess);
- return ret;
- }
-}
-#tranche-end
diff --git a/module/subu-0/trc/subu.trc.c b/module/subu-0/trc/subu.trc.c
deleted file mode 100644
index 6ce4625..0000000
--- a/module/subu-0/trc/subu.trc.c
+++ /dev/null
@@ -1,742 +0,0 @@
-#tranche subu.lib.c
-/*
- sqllite3 is used to maintain the db file, which is currently compiled
- in as /etc/subu.db, (or just subu.db for testing).
-
- masteru is the user who ran this script. The masteru name comes from getuid
- and /etc/passwd.
-
- subu is a subservient user. The subuname is passed in as an argument.
-
- subu-mk-0 synthesizes a new user user name s, calls useradd to creat
- the new uswer account, and enters the relationship between masteru, subu, and
- s in the db file. It is this relation in the db file that
- associates the subuname with the s user.
-
- subu-rm-0 uses userdel to delete the related s user account. It
- then removes the relaton from the db file.
-
- subu-mk-0 and subu-rm-0 are setuid root scripts.
-
-*/
-#include
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-// without this #define we get the warning: implicit declaration of function âseteuidâ/âsetegidâ
-#define _GNU_SOURCE
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#tranche subu.lib.h
- #include
- #include
- #include
-#tranche-end
-
-//--------------------------------------------------------------------------------
-// dispatched command errors .. should add mkdir and rmdir ...
-//
-#tranche subu.lib.h
- char *useradd_mess(int err);
-#tranche-end
-char *useradd_mess(int err){
- if(err <= 0) return NULL;
- char *mess;
- switch(err){
- case 1: mess = "can't update password file"; break;
- case 2: mess = "invalid command syntax"; break;
- case 3: mess = "invalid argument to option"; break;
- case 4: mess = "UID already in use (and no -o)"; break;
- case 5: mess = "undefined"; break;
- case 6: mess = "specified group doesn't exist"; break;
- case 7:
- case 8: mess = "undefined"; break;
- case 9: mess = "username already in use"; break;
- case 10: mess = "can't update group file:"; break;
- case 11: mess = "undefined"; break;
- case 12: mess = "can't create home directory"; break;
- case 13: mess = "undefined"; break;
- case 14: mess = "can't update SELinux user mapping"; break;
- default: mess = "undefined"; break;
- }
- return strdup(mess);
-}
-#tranche subu.lib.h
- char *userdel_mess(int err);
-#tranche-end
-char *userdel_mess(int err){
- if(err <= 0) return NULL;
- char *mess;
- switch(err){
- case 1: mess = "can't update password file"; break;
- case 2: mess = "invalid command syntax"; break;
- case 3:
- case 4:
- case 5: mess = "undefined"; break;
- case 6: mess = "specified user doesn't exist"; break;
- case 7:
- case 8:
- case 9: mess = "undefined"; break;
- case 10: mess = "can't update group file:"; break;
- case 11: mess = "undefined"; break;
- case 12: mess = "can't remove home directory"; break;
- default: mess = "undefined"; break;
- }
- return strdup(mess);
-}
-
-
-//--------------------------------------------------------------------------------
-//
-#tranche subu.lib.h
- #define SUBU_ERR_ARG_CNT 1
- #define SUBU_ERR_SETUID_ROOT 2
- #define SUBU_ERR_MALLOC 3
- #define SUBU_ERR_MKDIR_SUBUHOME 4
- #define SUBU_ERR_RMDIR_SUBUHOME 5
- #define SUBU_ERR_SUBUNAME_MALFORMED 6
- #define SUBU_ERR_HOMELESS 7
- #define SUBU_ERR_DB_FILE 8
- #define SUBU_ERR_SUBUHOME_EXISTS 9
- #define SUBU_ERR_BUG_SSS 10
- #define SUBU_ERR_FAILED_USERADD 11
- #define SUBU_ERR_FAILED_USERDEL 12
- #define SUBU_ERR_SUBU_NOT_FOUND 13
- #define SUBU_ERR_N 14
- #define SUBU_ERR_BIND 15
-#tranche-end
-#tranche subu.lib.h
- void subu_err(char *fname, int err, char *mess);
-#tranche-end
-void subu_err(char *fname, int err, char *mess){
- if(!mess) mess = "";
- switch(err){
- case 0: return;
- case SUBU_ERR_ARG_CNT:
- if(mess[0])
- fprintf(stderr, "Incorrect number of arguments, %s", mess);
- else
- fprintf(stderr, "Incorrect number of arguments.", mess);
- break;
- case SUBU_ERR_SETUID_ROOT:
- fprintf(stderr, "This program must be run setuid root from a user account.");
- break;
- case SUBU_ERR_MALLOC:
- perror(fname);
- break;
- case SUBU_ERR_DB_FILE:
- fprintf(stderr, "error on %s", DB_File); // DB_File is in common
- fprintf(stderr, ": %s", mess);
- break;
- case SUBU_ERR_HOMELESS:
- fprintf(stderr,"Masteru, \"%s\", has no home directory", mess);
- break;
- case SUBU_ERR_SUBUNAME_MALFORMED:
- fprintf(stderr, "subuname, \"%s\" is not in [ _.-a-zA-Z0-9]*", mess);
- break;
- case SUBU_ERR_SUBUHOME_EXISTS:
- fprintf(stderr, "a file system object already exists at subuhome, \"%s\"\n", mess);
- break;
- case SUBU_ERR_MKDIR_SUBUHOME:
- fprintf(stderr, "masteru could not make subuhome, \"%s\"", mess);
- break;
- case SUBU_ERR_BUG_SSS:
- perror(fname);
- break;
- case SUBU_ERR_FAILED_USERADD:
- fprintf(stderr, "%s useradd failed\n", mess);
- break;
- default:
- fprintf(stderr, "unknown error code %d\n", err);
- }
- fputc('\n', stderr);
-}
-
-
-//--------------------------------------------------------------------------------
-// a well formed subuname
-// returns the length of the subuname, or -1
-//
-static int allowed_subuname(char **mess, char *subuname, size_t *subuname_len){
- char *ch = subuname;
- size_t i = 0;
- while(
- *ch
- &&
- ( *ch >= 'a' && *ch <= 'z'
- ||
- *ch >= 'A' && *ch <= 'Z'
- ||
- *ch >= '0' && *ch <= '9'
- ||
- *ch == '-'
- ||
- *ch == '_'
- ||
- *ch == '.'
- ||
- *ch == ' '
- )
- ){
- ch++;
- i++;
- }
- if( !*ch ){
- *subuname_len = i;
- return 0;
- }else{
- if(mess) *mess = strdup(subuname);
- return SUBU_ERR_SUBUNAME_MALFORMED;
- }
-}
-
-//--------------------------------------------------------------------------------
-// dispatched functions
-//
-static int masteru_mkdir_subuhome(void *arg){
- char *subuhome = (char *) arg;
- if( mkdir( subuhome, Subuhome_Perms ) == -1 ){ // find subuhome perms in common
- perror("masteru_mkdir_subuhome");
- return SUBU_ERR_MKDIR_SUBUHOME;
- }
- return 0;
-}
-static int masteru_rmdir_subuhome(void *arg){
- char *subuhome = (char *) arg;
- if( rmdir( subuhome ) == -1 ){ // find subuhome perms in common
- perror("masteru_rmdir_subuhome");
- return SUBU_ERR_RMDIR_SUBUHOME;
- }
- return 0;
-}
-
-//--------------------------------------------------------------------------------
-// build strings
-//
-static int mk_subu_username(char **mess, sqlite3 *db, char **subu_username){
- int rc,n;
- db_begin(db);
- if(
- (rc = subudb_number_get(db, &n))
- ||
- (rc = subudb_number_set(db, ++n))
- ){
- db_rollback(db);
- return SUBU_ERR_DB_FILE;
- }
- db_commit(db);
-
- size_t len = 0;
- FILE* name_stream = open_memstream(subu_username, &len);
- fprintf(name_stream, "s%d", n);
- fclose(name_stream);
- return 0;
-}
-
-// man page says that getpwuid strings may not be freed, I don't know how long until they
-// are overwritten, so I just make my own copies that can be freed
-static int uid_to_name_and_home(uid_t uid, char **name, char **home ){
- struct passwd *pw_record_pt = getpwuid(uid); // reading /etc/passwd
- *name = strdup(pw_record_pt->pw_name);
- *home = strdup(pw_record_pt->pw_dir);
- if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS;
- return 0;
-}
-
-static int username_to_home(char *name, char **home ){
- struct passwd *pw_record_pt = getpwnam(name); // reading /etc/passwd
- *home = strdup(pw_record_pt->pw_dir);
- if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS;
- return 0;
-}
-
-static int mk_subuland(char *masteru_home, char **subuland){
- size_t masteru_home_len = strlen(masteru_home);
- char *Subuland_Extension = "/subuland/";
- size_t Subuland_Extension_len = strlen(Subuland_Extension);
- *subuland = (char *)malloc( masteru_home_len + Subuland_Extension_len + 1 );
- if(!*subuland) SUBU_ERR_MALLOC;
- strcpy(*subuland, masteru_home);
- strcpy(*subuland + masteru_home_len, Subuland_Extension);
- return 0;
-}
-
-static int mk_subuhome(char *subuland, char *subuname, char **subuhome){
- size_t subuland_len = strlen(subuland);
- size_t subuhome_len = subuland_len + strlen(subuname); // subuland has a trailing '/'
- *subuhome = (char *)malloc(subuhome_len + 1);
- if(!*subuhome) return SUBU_ERR_MALLOC;
- strcpy (*subuhome, subuland);
- strcpy (*subuhome + subuland_len, subuname);
- return 0;
-}
-
-
-
-//===============================================================================
-#tranche subu.lib.h
- int subu_mk_0(char **mess, sqlite3 *db, char *subuname);
-#tranche-end
-int subu_mk_0(char **mess, sqlite3 *db, char *subuname){
-
- int rc;
- if(mess)*mess = 0;
- Da resources;
- da_alloc(&resources, sizeof(char *));
-
- //--------------------------------------------------------------------------------
- size_t subuname_len;
- rc = allowed_subuname(mess, subuname, &subuname_len);
- if(rc) return rc;
- #ifdef DEBUG
- debug_printf("subuname is well formed\n");
- #endif
-
- //--------------------------------------------------------------------------------
- uid_t masteru_uid;
- gid_t masteru_gid;
- uid_t set_euid;
- gid_t set_egid;
- {
- masteru_uid = getuid();
- masteru_gid = getgid();
- set_euid = geteuid();
- set_egid = getegid();
- #ifdef DEBUG
- debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid);
- #endif
- if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT;
- }
-
- //--------------------------------------------------------------------------------
- char *masteru_name = 0;
- char *masteru_home = 0;
- char *subu_username = 0;
- char *subuland = 0;
- char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir
- da_push(&resources, masteru_name);
- da_push(&resources, masteru_home);
- da_push(&resources, subu_username);
- da_push(&resources, subuland);
- da_push(&resources, subuhome);
- rc =
- uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
- ||
- mk_subu_username(mess, db, &subu_username)
- ||
- mk_subuland(masteru_home, &subuland)
- ||
- mk_subuhome(subuland, subuname, &subuhome)
- ;
- if(rc) RETURN(&resources, rc);
- #ifdef DEBUG
- debug_printf("subu_username, subuland, subuhome: \"%s\"\"%s\"\"%s\"\n", subu_username, subuland, subuhome);
- #endif
-
- //--------------------------------------------------------------------------------
- // By having masteru create the subuhome, we know that masteru has rights to
- // to access this directory. This will be the mount point for bindfs
- {
- struct stat st;
- if( stat(subuhome, &st) != -1 ){
- if(mess)*mess = strdup(subuhome);
- RETURN(&resources, SUBU_ERR_SUBUHOME_EXISTS);
- }
- int dispatch_err = dispatch_f_euid_egid
- (
- "masteru_mkdir_subuhome",
- masteru_mkdir_subuhome,
- (void *)subuhome,
- masteru_uid,
- masteru_gid
- );
- if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_MKDIR_SUBUHOME ){
- #ifdef DEBUG
- dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_mkdir_subuhome");
- #endif
- if(mess)*mess = strdup(subuhome);
- RETURN(&resources, SUBU_ERR_MKDIR_SUBUHOME);
- }
- }
- #ifdef DEBUG
- debug_printf("made directory \"%s\"\n", subuhome);
- #endif
-
- //--------------------------------------------------------------------------------
- // Make the subservient user account, i.e. the subu
- {
- #ifdef DEBUG
- debug_printf("making subu \"%s\" as user \"%s\"\n", subuname, subu_username);
- #endif
- #if BUG_SSS_CACHE_RUID
- #ifdef DEBUG
- debug_printf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n");
- #endif
- if( setuid(0) == -1 ) RETURN(&resources, SUBU_ERR_BUG_SSS);
- #endif
- char *command = "/usr/sbin/useradd";
- char *argv[3];
- argv[0] = command;
- argv[1] = subu_username;
- argv[2] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- int dispatch_err = dispatch_exec(argv, envp);
- if( dispatch_err != 0 ){
- #ifdef DEBUG
- dispatch_f_mess("dispatch_exec", dispatch_err, command);
- #endif
- // go back and remove the directory we made in subuland
- int dispatch_err_rmdir = dispatch_f_euid_egid
- (
- "masteru_rmdir_subuhome",
- masteru_rmdir_subuhome,
- (void *)subuhome,
- masteru_uid,
- masteru_gid
- );
- #ifdef DEBUG
- dispatch_f_mess("dispatch_f_euid_egid", dispatch_err_rmdir, "masteru_rmdir_subuhome");
- #endif
- if(mess)*mess = useradd_mess(dispatch_err);
- RETURN(&resources, SUBU_ERR_FAILED_USERADD);
- }
- #ifdef DEBUG
- debug_printf("added user \"%s\"\n", subu_username);
- #endif
- }
-
- //--------------------------------------------------------------------------------
- #ifdef DEBUG
- debug_printf("setting the masteru_name, subuname, subu_username relation\n");
- #endif
- {
- int rc = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username);
- if( rc != SQLITE_OK ){
- if(mess)*mess = strdup("insert of masteru subu relation failed");
- RETURN(&resources, SUBU_ERR_DB_FILE);
- }
- }
- #ifdef DEBUG
- debug_printf("finished subu-mk-0(%s)\n", subuname);
- #endif
- RETURN(&resources, 0);
-}
-
-//================================================================================
-#tranche subu.lib.h
- int subu_rm_0(char **mess, sqlite3 *db, char *subuname);
-#tranche-end
-int subu_rm_0(char **mess, sqlite3 *db, char *subuname){
-
- int rc;
- if(mess)*mess = 0;
- Da resources;
- da_alloc(&resources, sizeof(char *));
-
- //--------------------------------------------------------------------------------
- size_t subuname_len;
- rc = allowed_subuname(mess, subuname, &subuname_len);
- if(rc) return rc;
- #ifdef DEBUG
- debug_printf("subuname is well formed\n");
- #endif
-
- //--------------------------------------------------------------------------------
- uid_t masteru_uid;
- gid_t masteru_gid;
- uid_t set_euid;
- gid_t set_egid;
- {
- masteru_uid = getuid();
- masteru_gid = getgid();
- set_euid = geteuid();
- set_egid = getegid();
- #ifdef DEBUG
- debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid);
- #endif
- if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT;
- }
-
- //--------------------------------------------------------------------------------
- // various strings that we will need
- char *masteru_name = 0;
- char *masteru_home = 0;
- char *subuland = 0;
- char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir
- da_push(&resources, masteru_name);
- da_push(&resources, masteru_home);
- da_push(&resources, subuland);
- da_push(&resources, subuhome);
- rc =
- uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
- ||
- mk_subuland(masteru_home, &subuland)
- ||
- mk_subuhome(subuland, subuname, &subuhome)
- ;
- if(rc) RETURN(&resources, rc);
- #ifdef DEBUG
- debug_printf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome);
- #endif
-
- //--------------------------------------------------------------------------------
- // removal from db
- char *subu_username = 0;
- da_push(&resources, subu_username);
-
- db_begin(db);
-
- rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
- if( rc != SQLITE_OK ){
- if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file");
- rc = SUBU_ERR_SUBU_NOT_FOUND;
- db_rollback(db);
- RETURN(&resources, rc);
- }
- #ifdef DEBUG
- printf("subu_username: \"%s\"\n", subu_username);
- #endif
-
- rc = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username);
- if( rc != SQLITE_OK ){
- if(mess)*mess = strdup("removal of masteru subu relation failed");
- db_rollback(db);
- RETURN(&resources, SUBU_ERR_DB_FILE);
- }
- #ifdef DEBUG
- debug_printf("removed the masteru_name, subuname, subu_username relation\n");
- #endif
-
- rc = db_commit(db);
- if( rc != SQLITE_OK ){
- if(mess)*mess = strdup("removal of masteru subu relation in unknown state, exiting");
- RETURN(&resources, SUBU_ERR_DB_FILE);
- }
-
- // even after removing the last masteru subu relation, we still do not remove
- // the max subu count. Hence, a masteru will keep such for a life time.
-
-
- //--------------------------------------------------------------------------------
- // Only masteru can remove directories from masteru/subuland, so we switch to
- // masteru's uid to perform the rmdir.
- //
- {
- #ifdef DEBUG
- debug_printf("as masteru, removing the directory \"%s\"\n", subuhome);
- #endif
- int dispatch_err = dispatch_f_euid_egid
- (
- "masteru_rmdir_subuhome",
- masteru_rmdir_subuhome,
- (void *)subuhome,
- masteru_uid,
- masteru_gid
- );
- if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_RMDIR_SUBUHOME ){
- #ifdef DEBUG
- dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_rmdir_subuhome");
- #endif
- if(mess)*mess = strdup(subuhome);
- RETURN(&resources, SUBU_ERR_RMDIR_SUBUHOME);
- }
- }
-
- //--------------------------------------------------------------------------------
- // Delete the subservient user account
- {
- #ifdef DEBUG
- debug_printf("deleting user \"%s\"\n", subu_username);
- #endif
- #if BUG_SSS_CACHE_RUID
- #ifdef DEBUG
- debug_printf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n");
- #endif
- if( setuid(0) == -1 ){
- RETURN(&resources, SUBU_ERR_BUG_SSS);
- }
- #endif
- char *command = "/usr/sbin/userdel";
- char *argv[4];
- argv[0] = command;
- argv[1] = subu_username;
- argv[2] = "-r";
- argv[3] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- int dispatch_err = dispatch_exec(argv, envp);
- if( dispatch_err != 0 ){
- #ifdef DEBUG
- dispatch_f_mess("dispatch_exec", dispatch_err, command);
- #endif
- if(mess)*mess = userdel_mess(dispatch_err);
- RETURN(&resources, SUBU_ERR_FAILED_USERDEL);
- }
- #ifdef DEBUG
- debug_printf("deleted user \"%s\"\n", subu_username);
- #endif
- }
-
- #ifdef DEBUG
- debug_printf("finished subu-rm-0(%s)\n", subuname);
- #endif
- RETURN(&resources, 0);
-}
-
-//================================================================================
-// identifies masteru, the bindfs maps each subu_user's home to its mount point
-// in subuland.
-#tranche subu.lib.h
- int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome);
-#tranche-end
-int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome){
-
- int rc;
- if(mess)*mess = 0;
- Da resources;
- da_alloc(&resources, sizeof(char *));
-
- // lookup the subu_user_home
- char *subu_user_home = 0;
- da_push(&resources, subu_user_home);
-
- rc = username_to_home(subu_username, &subu_user_home);
- if( rc ){
- if(mess) *mess = strdup("in subu_bind, subu user home directory lookup in /etc/passwd failed.");
- RETURN(&resources, rc);
- }
-
- size_t len = 0;
- char *map = 0;
- da_push(&resources, map);
-
- FILE* map_stream = open_memstream(&map, &len);
- fprintf(map_stream, "--map=%s/%s:@%s/@%s", subu_username, masteru_name, subu_username, masteru_name);
- fclose(map_stream);
-
- char *command = "/usr/bin/bindfs";
- char *argv[5];
- argv[0] = command;
- argv[1] = map;
- argv[2] = subu_user_home;
- argv[3] = subuhome;
- argv[4] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- int dispatch_err = dispatch_exec(argv, envp);
- if( dispatch_err != 0 ){
- #ifdef DEBUG
- dispatch_f_mess(command, dispatch_err, "dispatch_exec");
- #endif
- if(mess)*mess = strdup("bind failed");
- RETURN(&resources, SUBU_ERR_BIND);
- }
- #ifdef DEBUG
- debug_printf("mapped \"%s\" as \"%s\"\n", subu_user_home, subuhome);
- #endif
- RETURN(&resources, 0);
-}
-
-#tranche subu.lib.h
- int subu_bind_all(char **mess, sqlite3 *db);
-#tranche-end
-int subu_bind_all(char **mess, sqlite3 *db){
-
- int rc;
- if(mess)*mess = 0;
- Da resources;
- da_alloc(&resources, sizeof(char *));
-
- //--------------------------------------------------------------------------------
- uid_t masteru_uid;
- gid_t masteru_gid;
- uid_t set_euid;
- gid_t set_egid;
- {
- masteru_uid = getuid();
- masteru_gid = getgid();
- set_euid = geteuid();
- set_egid = getegid();
- #ifdef DEBUG
- debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid);
- #endif
- if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT;
- }
-
- //--------------------------------------------------------------------------------
- // various strings that we will need
- char *masteru_name = 0;
- char *masteru_home = 0;
- char *subuland = 0;
- da_push(&resources, masteru_name);
- da_push(&resources, masteru_home);
- da_push(&resources, subuland);
- rc =
- uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
- ||
- mk_subuland(masteru_home, &subuland)
- ;
- if(rc) RETURN(&resources, rc);
- #ifdef DEBUG
- if(masteru_name)
- debug_printf("masteru_name: \"%s\"", masteru_name);
- else
- debug_printf("masteru_name unknown");
- if(subuland)
- debug_printf("subuland: \"%s\"", subuland);
- else
- debug_printf("subuland unknown");
- debug_printf("\n");
- #endif
-
- //--------------------------------------------------------------------------------
- Da subus;
- Da *subusp = &subus;
- da_alloc(subusp, sizeof(subudb_subu_element));
- rc = subudb_Masteru_Subu_get_subus(db, masteru_name, subusp);
- if( rc != SQLITE_OK ){
- if(mess)*mess = strdup("db access failed when fetching a list of subus");
- return rc;
- }
- // a limitation of our error reporting approach is that we can only
- // return one error, but here is a loop that might generate many
- rc = 0;
- char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir
- uint err_cnt = 0;
- subudb_subu_element *pt = (subudb_subu_element *)(subusp->base);
- while( !da_endq(subusp,pt) ){
- rc = mk_subuhome(subuland, pt->subuname, &subuhome);
- #ifdef DEBUG
- if(subuhome)
- debug_printf("subuhome: \"%s\"\n", subuhome);
- else
- debug_printf("subuhome unknown \n");
- #endif
- if(!rc) rc = subu_bind(NULL, masteru_name, pt->subu_username, subuhome);
- if(rc) err_cnt++;
- free(subuhome);
- subuhome=0;
- pt++;
- }
- if(err_cnt==1){
- RETURN(&resources, rc);
- }
- if(err_cnt > 1){
- *mess = strdup("multiple errors occured while binding subus");
- RETURN(&resources, SUBU_ERR_BIND);
- }
- RETURN(&resources, 0);
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb-init.trc.c b/module/subu-0/trc/subudb-init.trc.c
deleted file mode 100644
index 69bc2a7..0000000
--- a/module/subu-0/trc/subudb-init.trc.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#tranche subudb-init.cli.c
-/*
-This command initializes the db file.
-
-*/
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-int main(){
- sqlite3 *db;
- if( sqlite3_open(DB_File, &db) != SQLITE_OK ){
- fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File);
- return SUBU_ERR_DB_FILE;
- }
- db_begin(db);
- if( subudb_schema(db) != SQLITE_OK ){
- db_rollback(db);
- fprintf(stderr, "error exit, opened db file but could not build schema\n");
- return SUBU_ERR_DB_FILE;
- }
- db_commit(db);
- if( sqlite3_close(db) != SQLITE_OK ){
- fprintf(stderr, "error exit, could not close the db\n");
- return SUBU_ERR_DB_FILE;
- }
- return 0;
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb-number.trc.c b/module/subu-0/trc/subudb-number.trc.c
deleted file mode 100644
index 7844b47..0000000
--- a/module/subu-0/trc/subudb-number.trc.c
+++ /dev/null
@@ -1,67 +0,0 @@
-#tranche subudb-number.cli.c
-/*
-Set or get a new maximum subu number. Currently doesn't do the setting part.
-
-*/
-#include
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
-
- if( argc < 1 || argc > 2){
- fprintf(stderr, "usage: %s [n]\n",argv[0]);
- return SUBU_ERR_ARG_CNT;
- }
-
- int rc;
- sqlite3 *db;
- rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "error exit, could not open db file\n");
- sqlite3_close(db);
- return SUBU_ERR_DB_FILE;
- }
-
- // then arg[1] holds a number to set the max to
- if(argc == 2){
- long int i = strtol(argv[1], NULL, 10);
- if( i < 0 ){
- fprintf(stderr, "n must be positive\n");
- sqlite3_close(db);
- return SUBU_ERR_N;
- }
- if( i > INT_MAX ){
- fprintf(stderr, "n is too big, max supported by this program is %d\n", INT_MAX);
- sqlite3_close(db);
- return SUBU_ERR_N;
- }
- rc = subudb_number_set(db, i);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "couldn't set Max_Subunumber: %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_N;
- }
- }
-
- // read and print the current max
- int n;
- rc = subudb_number_get(db, &n);
- if( rc == SQLITE_OK ){
- printf("%d\n", n);
- }else{
- fprintf(stderr, "couldn't get Max_Subunumber: %s\n", sqlite3_errmsg(db));
- sqlite3_close(db);
- return SUBU_ERR_DB_FILE;
- }
- rc = sqlite3_close(db);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- return 0;
-
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb-rel-get.trc.c b/module/subu-0/trc/subudb-rel-get.trc.c
deleted file mode 100644
index b1f87e3..0000000
--- a/module/subu-0/trc/subudb-rel-get.trc.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#tranche subudb-rel-get.cli.c
-/*
-get the username from the db file
-for testing subudb_Masteru_Subu_get_subu_username
-
-*/
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
-
- if(argc != 3){
- fprintf(stderr, "usage: %s masteru_name subuname\n", argv[0]);
- return SUBU_ERR_ARG_CNT;
- }
-
- int rc;
- sqlite3 *db;
- rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
- return SUBU_ERR_DB_FILE;
- }
-
- char *masteru_name = argv[1];
- char *subuname = argv[2];
- char *subu_username;
-
- int ret = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
- if( ret != SQLITE_DONE ){
- fprintf(stderr, "subudb_Masteru_Subu_get_subu_username indicates failure by returning %d\n",ret);
- fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- ret = sqlite3_close(db);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret);
- fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- return 0;
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb-rel-put.trc.c b/module/subu-0/trc/subudb-rel-put.trc.c
deleted file mode 100644
index 86d8beb..0000000
--- a/module/subu-0/trc/subudb-rel-put.trc.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#tranche subudb-rel-put.cli.c
-/*
-puts a relation in the masteru/subu table
-
-*/
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
-
- if(argc != 4){
- fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]);
- return 1;
- }
- char *masteru_name = argv[1];
- char *subuname = argv[2];
- char *subu_username = argv[3];
-
- sqlite3 *db;
- {
- int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
- return SUBU_ERR_DB_FILE;
- }}
-
- int ret = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "subudb_Masteru_Subu_put indicates failure by returning %d\n",ret);
- fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- ret = sqlite3_close(db);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret);
- fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- return 0;
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb-rel-rm.trc.c b/module/subu-0/trc/subudb-rel-rm.trc.c
deleted file mode 100644
index 88bd70a..0000000
--- a/module/subu-0/trc/subudb-rel-rm.trc.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#tranche subudb-rel-rm.cli.c
-/*
-puts a relation in the masteru/subu table
-
-*/
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
-
- if(argc != 4){
- fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]);
- return 1;
- }
- char *masteru_name = argv[1];
- char *subuname = argv[2];
- char *subu_username = argv[3];
-
- sqlite3 *db;
- {
- int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
- return SUBU_ERR_DB_FILE;
- }}
-
- int ret = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username);
- if( ret != SQLITE_DONE ){
- fprintf(stderr, "subudb_Masteru_Subu_rm indicates failure by returning %d\n",ret);
- fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
- printf("put failed\n");
- return 2;
- }
- ret = sqlite3_close(db);
- if( ret != SQLITE_OK ){
- fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret);
- fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- return 0;
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb-subus.trc.c b/module/subu-0/trc/subudb-subus.trc.c
deleted file mode 100644
index 500f641..0000000
--- a/module/subu-0/trc/subudb-subus.trc.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#tranche subudb-subus.cli.c
-/*
-Set or get a new maximum subu number. Currently doesn't do the setting part.
-
-*/
-#include
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-#include "subu.lib.h"
-
-int main(int argc, char **argv){
-
- if( argc != 2){
- fprintf(stderr, "usage: %s masteru_name\n",argv[0]);
- return SUBU_ERR_ARG_CNT;
- }
- char *masteru_name = argv[1];
-
- int rc;
- sqlite3 *db;
- rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "error exit, could not open db file\n");
- sqlite3_close(db);
- return SUBU_ERR_DB_FILE;
- }
-
- Da subu_arr;
- Da *subu_arrp = &subu_arr;
- rc = subudb_Masteru_Subu_get_subus(db, masteru_name, subu_arrp);
- if( rc == SQLITE_OK ){
- char *pt = subu_arrp->base;
- subudb_subu_element *pt1;
- while( pt < subu_arrp->end ){
- pt1 = (subudb_subu_element *)pt;
- printf("%s %s\n", pt1->subuname, pt1->subu_username);
- pt += subu_arrp->element_size;
- }
- rc = sqlite3_close(db);
- if( rc != SQLITE_OK ){
- fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db));
- return SUBU_ERR_DB_FILE;
- }
- return 0;
- }
- fprintf(stderr, "lookup failed %s\n", sqlite3_errmsg(db));
- sqlite3_close(db);
- return SUBU_ERR_DB_FILE;
-
-}
-#tranche-end
diff --git a/module/subu-0/trc/subudb.trc.c b/module/subu-0/trc/subudb.trc.c
deleted file mode 100644
index c6fb603..0000000
--- a/module/subu-0/trc/subudb.trc.c
+++ /dev/null
@@ -1,202 +0,0 @@
-#tranche subudb.lib.c
-#tranche subudb.lib.h
- /*
- The db file is maintained in SQLite
-
- Because linux user names are limited length, subu user names are of a compact
- form: _s. A separate table translates the numbers into the subu names.
-
- Each of these returns SQLITE_OK upon success
- */
- #include
- #include
-#tranche-end
-
-#include
-#include
-#include
-#include
-#include
-#include "common.lib.h"
-#include "subudb.lib.h"
-
-//--------------------------------------------------------------------------------
-// sqlite transactions don't nest. There is a way to use save points, but still
-// we can't just nest transactions. Instead use these wrappers around the whole
-// of something that needs to be in a transaction.
-#tranche subudb.lib.h
- int db_begin(sqlite3 *db);
- int db_commit(sqlite3 *db);
- int db_rollback(sqlite3 *db);
-#tranche-end
-int db_begin(sqlite3 *db){
- return sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
-}
-int db_commit(sqlite3 *db){
- return sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
-}
-int db_rollback(sqlite3 *db){
- return sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
-}
-
-//--------------------------------------------------------------------------------
-#tranche subudb.lib.h
- int subudb_schema(sqlite3 *db);
-#tranche-end
-int subudb_schema(sqlite3 *db){
- int rc;
-
- { // build tables
- char sql[] =
- "CREATE TABLE Masteru_Subu(masteru_name TEXT, subuname TEXT, subu_username TEXT);"
- "CREATE TABLE Attribute_Int(attribute TEXT, value INT);"
- ;
- rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
- if(rc != SQLITE_OK) return rc;
- }
-
- { // data initialization
- char *sql = "INSERT INTO Attribute_Int (attribute, value) VALUES ('Max_Subunumber', ?1);";
- sqlite3_stmt *stmt;
- sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
- sqlite3_bind_int(stmt, 1, First_Max_Subunumber);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if( rc != SQLITE_DONE ) return rc;
- }
-
- return SQLITE_OK;
-}
-
-//--------------------------------------------------------------------------------
-#tranche subudb.lib.h
- int subudb_number_get(sqlite3 *db, int *n);
-#tranche-end
-int subudb_number_get(sqlite3 *db, int *n){
- char *sql = "SELECT value FROM Attribute_Int WHERE attribute = 'Max_Subunumber';";
- sqlite3_stmt *stmt;
- sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
- int rc = sqlite3_step(stmt);
- if( rc == SQLITE_ROW ){
- *n = sqlite3_column_int(stmt,0);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if( rc != SQLITE_DONE ) return rc;
- return SQLITE_OK;
- }
- // should have a message return, suppose
- sqlite3_finalize(stmt);
- return SQLITE_NOTFOUND;
-}
-
-#tranche subudb.lib.h
- int subudb_number_set(sqlite3 *db, int n);
-#tranche-end
-int subudb_number_set(sqlite3 *db, int n){
- int rc;
- char *sql = "UPDATE Attribute_Int SET value = ?1 WHERE attribute = 'Max_Subunumber';";
- sqlite3_stmt *stmt;
- sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
- sqlite3_bind_int(stmt, 1, n);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if( rc == SQLITE_DONE ) return SQLITE_OK;
- return rc;
-}
-
-//--------------------------------------------------------------------------------
-// put relation into Masteru_Subu table
-#tranche subudb.lib.h
- int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
-#tranche-end
-int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){
- char *sql = "INSERT INTO Masteru_Subu VALUES (?1, ?2, ?3);";
- sqlite3_stmt *stmt;
- sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
- sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC);
- sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC);
- sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC);
- int rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if( rc == SQLITE_DONE ) return SQLITE_OK;
- return rc;
-}
-
-//--------------------------------------------------------------------------------
-#tranche subudb.lib.h
- int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username);
-#tranche-end
-int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username){
- char *sql = "SELECT subu_username FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2;";
- size_t sql_len = strlen(sql);
- sqlite3_stmt *stmt;
- int rc;
- rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
- if( rc != SQLITE_OK ) return rc;
- sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC);
- sqlite3_bind_text(stmt, 2, subuname, strlen(subuname), SQLITE_STATIC);
- rc = sqlite3_step(stmt);
- if( rc == SQLITE_ROW ){
- const char *username = sqlite3_column_text(stmt, 0);
- *subu_username = strdup(username);
- }else{
- sqlite3_finalize(stmt);
- return rc; // woops this needs to return an error!, be sure it is not SQLITE_DONE
- }
- rc = sqlite3_step(stmt);
- if( rc == SQLITE_DONE ) return SQLITE_OK;
- return rc;
-}
-
-//--------------------------------------------------------------------------------
-#tranche subudb.lib.h
- typedef struct{
- char *subuname; // the name that masteru chose for his or her subu
- char *subu_username; // the adduser name we gave it, typically of the s
- } subudb_subu_element;
- int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subus);
-#tranche-end
-//returns an array of subudb_subu_elements that correspond to the masteru_name
-int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subusp){
- char *sql = "SELECT subuname, subu_username"
- " FROM Masteru_Subu"
- " WHERE masteru_name = ?1;";
- size_t sql_len = strlen(sql);
- sqlite3_stmt *stmt;
- int rc;
- rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
- if( rc != SQLITE_OK ) return rc;
- sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC);
-
- subudb_subu_element *pt;
- rc = sqlite3_step(stmt);
- while( rc == SQLITE_ROW ){
- pt = (subudb_subu_element *)da_push_alloc(subusp);
- pt->subuname = strdup(sqlite3_column_text(stmt, 0));
- pt->subu_username = strdup(sqlite3_column_text(stmt, 1));
- rc = sqlite3_step(stmt);
- }
- sqlite3_finalize(stmt);
- if( rc != SQLITE_DONE ) return rc;
- return SQLITE_OK;
-}
-
-//--------------------------------------------------------------------------------
-#tranche subudb.lib.h
- int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
-#tranche-end
-int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){
- char *sql = "DELETE FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2 AND subu_username = ?3;";
- size_t sql_len = strlen(sql);
- sqlite3_stmt *stmt;
- int rc;
- rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
- if( rc != SQLITE_OK ) return rc;
- sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC);
- sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC);
- sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC);
- rc = sqlite3_step(stmt);
- sqlite3_finalize(stmt);
- if( rc == SQLITE_DONE ) return SQLITE_OK;
- return rc;
-}
diff --git a/module/subu-0/try/multiple-makefile-targets/makefile b/module/subu-0/try/multiple-makefile-targets/makefile
deleted file mode 100644
index 400ec02..0000000
--- a/module/subu-0/try/multiple-makefile-targets/makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-a b c:
- echo $@
-
-x y z:
- echo $@
-
-e f g: x y z
- echo $^
-
diff --git a/module/subu-0/try/voidptr.c b/module/subu-0/try/voidptr.c
deleted file mode 100644
index 383e9e3..0000000
--- a/module/subu-0/try/voidptr.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-They say a cast is not required passing a typed pointer to a void * argument,
-but What about void **? .. oop then it matters.
-
-gcc -std=gnu11 -o voidptr voidptr.c
-voidptr.c: In function âmainâ:
-voidptr.c:28:5: warning: passing argument 1 of âgâ from incompatible pointer type [-Wincompatible-pointer-types]
- g(&pt, y);
- ^~~
-voidptr.c:13:15: note: expected âvoid **â but argument is of type âint **â
- void g(void **pt0, void *pt1){
- ~~~~~~~^~~
-
-*/
-#include
-
-int f(void *pt){
- return *(int *)pt;
-}
-
-/* fails
-void g(void **pt0, int *pt1){
- *pt0 = pt1;
-}
-*/
-
-// passes
-void g(void *pt0, int *pt1){
- *(int **)pt0 = pt1;
-}
-
-int main(){
- int x = 5;
- int *xp = &x;
- printf("%d\n",f(xp));
-
- int y[3];
- y[0] = 10;
- y[1] = 11;
- y[2] = 12;
-
- int *pt;
- g(&pt, y);
- printf("%d\n",*pt);
-
- printf("that's all folks\n");
- return 0;
-}
diff --git a/module/subu-1/subu-mk.py b/module/subu-1/subu-mk.py
deleted file mode 100644
index 203fab4..0000000
--- a/module/subu-1/subu-mk.py
+++ /dev/null
@@ -1,299 +0,0 @@
-#!/usr/bin/python
-# see the help option for syntax
-# this script must be run from root or sudo
-#
-# on Fedora 29 os.getresuid returned all zeros for a script run from sudo.
-# Hence, I am using the environment variable SUDO_USER
-
-import getpass
-import os
-import sys
-import libuser
-from __future__ import print_function
-
-command = os.path.base(argv[0])
-
-#--------------------------------------------------------------------------------
-# utilities
-#
-def prn(str):
- print(str,end='')
-
-#--------------------------------------------------------------------------------
-# help
-#
-def help():
- print( command +
-""" [=help] [=version] [shell=][owner=] [subu=]
-Makes a subservient user.
-If no arguments are given, or if =help is given, this message is printed.
-When this command is invoked through sudo, $SUDO_USER is taken as the owner's username.
-Otherwise, when invoked directly from root, the owner= option must be provided.
-The subu-username argument is the username for the new subservient user
-The the new subu home directory is created in /home/owner/subu/.
-Facls are set to give the owner access to the new subu's home directory.
-The shell option is not implemented yet. Probably need a number of other options also.
-"""
- )
-
-def version():
- print(" version 0")
-
-#--------------------------------------------------------------------------------
-# a manager for handling error messages
-#
-class class_err:
-"""
-An error record has the form [flag, message, args]
- class is fatal, warning, info [currently not implemented]
- flag is true if an error has occured [need to change this to a count]
- args is an array of strings to be given after the error message is printed.
-
-The dict holds named error records.
-
-register() is used to name and place error records in the dict. register() is
-typically called multiple times to initialize and error instance.
-
-tattle() is used by the program at run time in order to signal errors.
-
-has_error() returns true if tattle was ever called
-
-report() prints an error report. When errors have occured this
-
-vector() [unimplemented] returns a bit vector with one bit per fatal error
-record, in the order they appear in the dictionary. The bit is set if the error
-ever occured.
-
-We check for as many errors as is convenient to do so rather than stopping on
-the first error.
-"""
-
- # field offsets into the error record
- flag_dex = 0;
- message_dex = 1;
- args_dex = 2;
-
- def __init__(self):
- self.total_cnt = 0
- self.dict = {}
-
- def register(name, message):
- self.dict[name] = [False, message, []]
-
- def tattle(name, *args):
- self.total_cnt += 1
- if name in self.dict:
- self.dict[name][0] = True
- self.dict[name][2].extend(args)
-
- def report():
- if self.total_cnt:
- for k,v in self.dict.items():
- if v[self.flag_dex]:
- print(v[self.message_dex],end='')
- args = v[self.args_dex]
- if length(args) :
- print(args[0],end='')
- for arg in args[1:]:
- print( " " + arg, end='')
- print()
-
-#--------------------------------------------------------------------------------
-# parse the command line
-#
-err.register(
- 'impossible_split',
- "It is not possible, yet this token split into other than one or two pieces: "
- )
-err.register(
- 'lone_delim',
- "No spaces should appear around the '=' delimiter."
- )
-
-args = sys.argv[1:]
-if len(args) == 0 :
- version()
- help()
- exit(1)
-
-#create a dictionary based on the command line arguments
-arg_dict = {}
-subu_cnt = 0
-delim = '='
-for token in args:
- token_pair = split(token, delim);
- if len(token_pair) == 1 : #means there was no '=' in the token
- arg_dict['subu'] = token_pair
- subu_cnt++
- elif len(token_pair) == 2 :
- if token_pair[0] == '' and token_pair[1] == '' :
- err.tattle('lone_delim')
- elif token_pair[1] == '' : # then has trailing delim, will treat the same as a leading delim
- arg_dict[token_pair[0]] = None
- elif token_pair[0] == '' : # then has leading delim
- arg_dict[token_pair[1]] = None
- else:
- arg_dict[token_pair[0]] = token_pair[1]
- else:
- err.tattle('impossible_split', token)
-
-if not arg_dict or arg_dict.get('help'):
- help()
- err.report()
- exit(1)
-
-if arg_dict.get('version'):
- version()
-
-#--------------------------------------------------------------------------------
-# check that the command line arguments are well formed.
-#
-err.register(
- 'too_many_args',
- command + " takes at most one non-option argument, but we counted: "
- )
-err.register(
- 'no_subu'
- command + " missing subservient username."
- )
-err.register(
- 'bad_username'
- "Usernames match ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$, but found: "
- )
-err.register(
- 'unknown_option'
- command + " doesn't implement option: "
- )
-
-subu = arg_dict.get('subu')
-if subu_cnt > 1:
- err.tattle('too_many_args')
-elif not subu
- err.tattle('no_subu')
-elif not re.match("^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$", subu)
- err.tattle('bad_username', subu)
-
-for k in arg_dict:
- if k not in ['help', 'version', 'shell', 'owner', 'subu'] :
- err.tattle('unkown_option', k)
-
-if arg_dict.get('shell') :
- print "shell option aint implemented yet"
-
-
-
-#--------------------------------------------------------------------------------
-# check that we have root privilege
-#
-err.register(
- 'not_root'
- command + "requires root privilege"
- )
-
-uid = os.getuid()
-if uid != 0 :
- err.tattle('not root')
-
-username = getpass.getuser()
-sudo_caller_username = os.environ.get('SUDO_USER')
-
-if !sudo_caller_username
- if username not == "root":
- err.tattle('not_root')
- elif:
- owner
-
-
- def has_error(*errs):
- return self.cnt > 0
-
-
-
-#-----
-
-
-
-
-#--------------------------------------------------------------------------------
-# pull out the owner_dir and subu_dir
-#
-admin= libuser.admin()
-
-err_arg_form = class_err()
-err_arg_form.register('too_many', "too many semicolon delineated parts in")
-
-owner_parts = args[0].split(":")
-subu_parts = args[1].split(":")
-
-owner_user_name = owner_parts[0]
-if not owner_user_name:
- err_arg_form.tattle('owner_user_name_missing', args[0])
-else:
- owner_user = admin.lookupUserByName(owner_user_name)
- if owner_user == None:
- err_arg_form.tattle('no_such_user_name', owner_user_name)
- else:
-
-
-subu_user_name = subu_parts[0]
-
-
-if length(owner_parts) > 2:
- err_arg_form.tattle('too_many', args[0])
-elif length(owner_parts) == 2:
- owner_dir = owner_parts[1]
-else # get the home directory
-
-
-
-
-
-#--------------------------------------------------------------------------------
-# set the home directory
-#
-if len(args) > args_dir_index:
- dir = args[args_dir_index]
-else:
- dir = os.getcwd()
-
-home = dir + "/" + name
-home_flag = not os.path.exists(home)
-
-#--------------------------------------------------------------------------------
-# create the user, setfacls
-#
-err_cnt = 0
-name_available_flag = False
-
-if name_flag:
- admin = libuser.admin()
- name_available_flag = name not in admin.enumeratedUsers()
-
-if owner_flag and name_flag and name_available_flag and home_flag :
- user = admin.initUser(name)
- user[libuser.HOMEDIRECTORY] = home
- if opt_shell : user[libuser.SHELL] = opt_shell
- admin.addUser(user)
- #setfacl -m d:u:plato:rwx,u:plato:rwx directory
- setfacl = "setfacl -m d:u:" + name + ":rwx,u:" + name + ":rwx " + home
- exit(0)
-
-#--------------------------------------------------------------------------------
-# error return
-# .. need to grab the return code from setfacl above and delete the user if it fails
-#
-err_flags = 0
-if not owner_flag :
- err_flags |= 2**2
- print "missing owning username argument"
-if not name_flag :
- err_flags |= 2**3
- print name + "missing subservient username argument"
-if not name_available_flag :
- err_flags |= 2**4
- print name + "specified subservient username already exists"
-if not home_flag :
- err_flags |= 2**5
- print "user home directory already exists"
-
-exit(err_flags)
diff --git a/module/tranche/deprecated/0_makefile b/module/tranche/deprecated/0_makefile
deleted file mode 100644
index f0708ef..0000000
--- a/module/tranche/deprecated/0_makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-# src/0_makefile
-
-SHELL=/bin/bash
-
--include 0_makefile_flags
-
-SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh
-MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc
-
-SOURCES=$(wildcard *.c)
-HFILES=$(wildcard *.h)
-
-all: version deps lib execs
-
-version:
- $(MAKE) $@
- @echo "SUID_TOOL: " $(SUID_TOOL)
-
-deps:
- makeheaders $(SOURCES) $(HFILES)
- sed -i '/^ *int *main *(.*)/d' *.h
- $(MAKE) $@
-
-execs:
- $(MAKE) $@
- @echo "-> $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all"
- cat $(SUID_TOOL)
- @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ]
- sudo $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all
-
-clean:
- $(MAKE) $@
- for i in $(HFILES); do rm $$i; done
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/tranche/deprecated/0_makefile-flags b/module/tranche/deprecated/0_makefile-flags
deleted file mode 100644
index d4df01f..0000000
--- a/module/tranche/deprecated/0_makefile-flags
+++ /dev/null
@@ -1,31 +0,0 @@
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-# directories used by this makefile, these could all be set to dot for
-# the simplest source directory structure
-
-#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared
-#$(PWD) is the directory that make was called from, this is already build in
-#set to dot to use the same directory as the source code
-#leave blank to ommit
-DEPRDIR=1_deprecated
-DOCDIR=1_doc
-EXECSDIR=1_execs
-HDIR=1_headers
-LIBDIR=1_lib
-TESTDIR=1_tests
-TMPDIR=1_tmp
-TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools)
-TRYDIR=1_try
-
-
-# compiler and flags
-CC=gcc
-CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB
-#CFLAGS=-std=gnu11 -fPIC -I. -Werror
-LINKFLAGS=-L1_lib -lsubu -lsqlite3
-
-LIBFILE=$(LIBDIR)/libsubu.a
-
diff --git a/module/tranche/doc/todo.txt b/module/tranche/doc/todo.txt
deleted file mode 100644
index 1494e66..0000000
--- a/module/tranche/doc/todo.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-
-2019-03-22T13:37:23Z
-1. indentation
-
- the first non blank line after the #tranche keyword sets the indentation
- level for the following text. When echoing to the output file
- remove that many leading spaces.
-
- Hmm, or allow options among the tranche parameters, -indent 3 or
- -indent ' '.
-
diff --git a/module/tranche/makefile b/module/tranche/makefile
deleted file mode 100644
index 9f66b5c..0000000
--- a/module/tranche/makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# tranche/makefile
-
-SHELL=/bin/bash
-MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
-
--include makefile-flags
-
-.PHONY: all
-all: version
-
-.PHONY: dep
-dep:
- if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
- $(MAKE) $@
-
-.PHONY: lib
-lib:
- cp $(SRCDIR)/tranche.lib.h include/tranche.h
- $(MAKE) $@
-
-.PHONY: exec
-exec:
- $(MAKE) $@
-
-.PHONY: share
-share:
- @echo "instead of share, the 'install' target will put the execs in tools/bin"
-
-.PHONY: install
-install:
- if [ -d $(EXECDIR) ]; then if [ ! -z "$(wildcard $(EXECDIR)/*)" ]; then cp $(EXECDIR)/* $(PROJECT_SUBU)/tool/bin; fi; fi
-
-%::
- $(MAKE) $@
-
-
-
-
diff --git a/module/tranche/makefile-flags b/module/tranche/makefile-flags
deleted file mode 100644
index 46febb1..0000000
--- a/module/tranche/makefile-flags
+++ /dev/null
@@ -1,26 +0,0 @@
-MODULE=tranche
-
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
-SRCDIR=src
-TESTDIR=
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-cc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
-ECHO= echo
-#ECHO= echo -e
-
-C=gcc
-CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
-LINKFLAGS=-L$(LIBDIR) -L$(SHAREDIR)/lib/ -l$(MODULE) -lda
-
diff --git a/module/tranche/src/tranche-make.cli.c b/module/tranche/src/tranche-make.cli.c
deleted file mode 100644
index bfe9d9b..0000000
--- a/module/tranche/src/tranche-make.cli.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-
-usage:
- argv[0] [] [-sname ] [-tdir ] [-mfile ]
-
-gets the names of all the targets from the source file, then appends
-to the mfile a couple of lines of the form:
-
-... :
- tranche $@
-
-Our makefile is typically run in the directory above where the sources are
-located.
-
-options
- the trc file to be read
--tdir prepend / to each "
--mfile where to send the output, defaults to stdout
--sname replaces sourcename as the name to write as the source - useful for pipes
-
-If is not provided stdin is used.
-If -mfile is not provided, stdout is used.
-If -sdir is not provided, the directory part of the is used. If the
-user does not want this behavior, give a value of "." for -sdir.
-
-.. should modify this to allow multiple source files on the command line ..
-.. should check that tdir is an existing directory
-*/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "tranche.lib.h"
-
-int main(int argc, char **argv, char **envp){
-
- int err = 0;
- char *sname = 0;
- char *tdir = 0;
- char *mfile_path = 0;
- Da args; // we will queue the non option args here
- Da *argsp = &args; // collection of the non-option non-option-value args
- da_alloc(argsp, sizeof(char *));
- { // argument parse
- char **pt = argv + 1; // skip the command name
- char *option;
- char *value; // currently all our tranche options have exactly one value
- while(*pt){
- if( **pt == '-' ){
- option = *pt + 1;
-
- // options that take no values:
- if(!*option){
- fprintf(stderr, "Currently there is no lone '-' option.\n");
- err |= TRANCHE_ERR_ARG_PARSE;
- goto endif;
- }
- if( !strcmp(option, "h") || !strcmp(option, "help") ){
- err |= TRANCHE_ERR_HELP; // this will force the usage message, though it will also return an error
- goto endif;
- }
-
- // options that take one value:
- pt++; if(!*pt || **pt == '-'){
- fprintf(stderr, "Missing value for option %s.\n", option);
- err |= TRANCHE_ERR_ARG_PARSE;
- if(!*pt) break; // then nothing more to parse
- goto endif;
- }
- value = *pt;
- if( !strcmp(option, "mfile") ){
- mfile_path = value;
- goto endif;
- }
- if( !strcmp(option, "tdir") ){
- tdir = value;
- path_trim_slashes(tdir);
- goto endif;
- }
- if( !strcmp(option, "sname") ){
- sname = value;
- goto endif;
- }
- fprintf(stderr, "Unrecognized option %s.", option);
- err |= TRANCHE_ERR_ARG_PARSE;
- goto endif;
- }
- // else clause
- da_push(argsp, pt);
- endif:
- pt++;
- }
- if(da_emptyq(argsp) && !sname){
- fprintf(stderr, "Must be given at least one source name argument or an sname option\n");
- err |= TRANCHE_ERR_SNAME;
- }
- if(err){
- fprintf(stderr, "usage: %s [].. [-sname ] [-tdir ]\n", argv[0]);
- return err;
- }
- }// end of argument parse
-
- // open the output file
- int mfile_fd;
- {
- if(mfile_path)
- mfile_fd = open(mfile_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
- else
- mfile_fd = STDOUT_FILENO;
-
- if(mfile_fd == -1){
- fprintf(stderr, "Could not open the dep file %s\n", mfile_path);
- err |= TRANCHE_ERR_DST_OPEN;
- }
- }
-
- // The arguments are source file paths, but we process each one only once.
- Da src_arr;
- Da *src_arrp = &src_arr;
- da_alloc(src_arrp, sizeof(char *));
- da_strings_set_union(src_arrp, argsp, NULL); // NULL destructor
- da_free(argsp);
-
- char *src_file_path;
- FILE *src_file;
- if(da_emptyq(src_arrp))
- tranche_make(stdin, sname, mfile_fd, tdir);
- else{
- char *pt = src_arrp->base;
- while( pt < src_arrp->end ){
- src_file_path = *(char **)pt;
- src_file = fopen(src_file_path, "r");
- if(!src_file){
- fprintf(stderr,"Could not open source file %s.\n", src_file_path);
- err |= TRANCHE_ERR_SRC_OPEN;
- }else{
- tranche_make(src_file, src_file_path, mfile_fd, tdir);
- if( fclose(src_file) == -1 ){perror(NULL); err |= TRANCHE_ERR_FCLOSE;}
- }
- pt += src_arrp->element_size;
- }
- }
- da_free(src_arrp);
-
- if(mfile_fd != STDOUT_FILENO && close(mfile_fd) == -1 ){
- perror(NULL);
- err |= TRANCHE_ERR_FCLOSE;
- }
- return err;
-}
diff --git a/module/tranche/src/tranche-target.cli.c b/module/tranche/src/tranche-target.cli.c
deleted file mode 100644
index 52277b9..0000000
--- a/module/tranche/src/tranche-target.cli.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-Scans a tranche and lists the named target files.
-
-stdout is not explicitly named. Would be intersting if stdout
-were also listed if anything is sent to stdout. Might distinguish
-between blank lines being sent and text being sent to stdout.
-
-*/
-
-#include
-#include
-#include
-#include
-#include "tranche.lib.h"
-
-#define ERR_ARGC 1
-#define ERR_SRC_OPEN 2
-
-
-int main(int argc, char **argv, char **envp){
-
- int err = 0;
- char *sep = 0;
- char *tdir = 0;
- Da args; // we will queue the non option args here
- Da *argsp = &args; // collection of the non-option non-option-value args
- da_alloc(argsp, sizeof(char *));
- { // argument parse
- char **pt = argv + 1; // skip the command name
- char *option;
- char *value; // currently all our tranche options have exactly one value
- while(*pt){
- if( **pt == '-' ){
- option = *pt + 1;
-
- // options that take no values:
- if(!*option){
- fprintf(stderr, "Currently there is no lone '-' option.\n");
- err |= TRANCHE_ERR_ARG_PARSE;
- goto endif;
- }
- if( !strcmp(option, "h") || !strcmp(option, "help") ){
- err |= TRANCHE_ERR_HELP; // this will force the usage message, though it will also return an error
- goto endif;
- }
-
- // options that take one value:
- pt++; if(!*pt || **pt == '-'){
- fprintf(stderr, "Missing value for option %s.\n", option);
- err |= TRANCHE_ERR_ARG_PARSE;
- if(!*pt) break; // then nothing more to parse
- goto endif;
- }
- value = *pt;
- if( !strcmp(option, "sep") ){
- sep = value;
- goto endif;
- }
- if( !strcmp(option, "tdir") ){
- tdir = value;
- path_trim_slashes(tdir);
- goto endif;
- }
- fprintf(stderr, "Unrecognized option %s.", option);
- err |= TRANCHE_ERR_ARG_PARSE;
- goto endif;
- }
- // else clause
- da_push(argsp, pt);
- endif:
- pt++;
- }
- if(!sep)sep = "\n";
- if(err){
- fprintf(stderr, "usage: %s [].. [-sep ]\n", argv[0]);
- return err;
- }
- }// end of argument parse
-
- // The arguments are source file paths, but we process each one only once.
- Da src_arr;
- Da *src_arrp = &src_arr;
- da_alloc(src_arrp, sizeof(char *));
- da_strings_set_union(src_arrp, argsp, NULL); // NULL destructor
- da_free(argsp);
-
- // a list of unique targets
- Da target_arr;
- Da *target_arrp = &target_arr;
- da_alloc(target_arrp, sizeof(char *));
-
- uint err_cnt = 0;
- char *src_file_path;
- FILE *src_file;
- if(da_emptyq(src_arrp))
- tranche_target(stdin, target_arrp, tdir);
- else{
- char *pt = src_arrp->base;
- while( pt < src_arrp->end ){
- src_file_path = *(char **)pt;
- src_file = fopen(src_file_path, "r");
- if(!src_file){
- fprintf(stderr,"Could not open source file %s.\n", src_file_path);
- err |= TRANCHE_ERR_SRC_OPEN;
- }else{
- tranche_target(src_file, target_arrp, tdir);
- if( fclose(src_file) == -1 ){perror(NULL); err |= TRANCHE_ERR_FCLOSE;}
- }
- pt += src_arrp->element_size;
- }
- }
- da_free(src_arrp);
- da_strings_print(target_arrp, sep);
- da_free_elements(target_arrp);
- da_free(target_arrp);
- return err;
-}
diff --git a/module/tranche/src/tranche.cli.c b/module/tranche/src/tranche.cli.c
deleted file mode 100644
index 447a78b..0000000
--- a/module/tranche/src/tranche.cli.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-The purpose of this tools is to facilitate putting prototypes (declarations) next
-to implementations (definitions) in a single source file of a C/C++ programs.
-
-Sends code tranches from a single source file into one or more output files.
-Scans through the single source file looking for lines of the form:
-
- #tranche-begin filename filename ...
-
-With the # as the first non-space character on the line, with one or more filenames
-following the tag. Upon finding such a line, copies all following lines into the
-listed files, until reaching the end marker:
-
- #tranche-end
-
-Files are opened for create or append. Typically the user will want to delete
-the tranche output files before running tranche a second time.
-
-.. currently tranche_send will probably mess up if the user nests a tranche to
-the same file as one already open in the containing tranche ..
-
-*/
-
-#include
-#include
-#include
-#include
-#include "tranche.lib.h"
-
-int main(int argc, char **argv, char **envp){
-
- int err = 0;
- char *tdir = 0;
- Da args; // we will queue the non option args here
- Da *argsp = &args; // collection of the non-option non-option-value args
- da_alloc(argsp, sizeof(char *));
- { // argument parse
- char **pt = argv + 1; // skip the command name
- char *option;
- char *value; // currently all our tranche options have exactly one value
- while(*pt){
- if( **pt == '-' ){
- option = *pt + 1;
-
- // options that take no values:
- if(!*option){
- fprintf(stderr, "Currently there is no lone '-' option.\n");
- err |= TRANCHE_ERR_ARG_PARSE;
- goto endif;
- }
- if( !strcmp(option, "h") || !strcmp(option, "help") ){
- err |= TRANCHE_ERR_HELP; // this will force the usage message, though it will also return an error
- goto endif;
- }
-
- // options that take one value:
- pt++; if(!*pt || **pt == '-'){
- fprintf(stderr, "Missing value for option %s.\n", option);
- err |= TRANCHE_ERR_ARG_PARSE;
- if(!*pt) break; // then nothing more to parse
- goto endif;
- }
- value = *pt;
- if( !strcmp(option, "tdir") ){
- tdir = value;
- goto endif;
- }
- fprintf(stderr, "Unrecognized option %s.", option);
- err |= TRANCHE_ERR_ARG_PARSE;
- goto endif;
- }
- // else clause
- da_push(argsp, pt);
- endif:
- pt++;
- }
- if(err){
- fprintf(stderr, "usage: %s [].. [-tdir ]\n", argv[0]);
- return err;
- }
- }// end of argument parse
-
- Da targets;
- Da *target_arrp = &targets;
- da_alloc(target_arrp, sizeof(int));
- int fd = STDOUT_FILENO;
- da_push(target_arrp, &fd);
-
- Da src_arr;
- Da *src_arrp = &src_arr;
- da_alloc(src_arrp, sizeof(char *));
- da_strings_set_union(src_arrp, argsp, NULL);
- da_free(argsp);
-
- char *src_file_path;
- FILE *src_file;
- if(da_emptyq(src_arrp))
- tranche_send(stdin, target_arrp, tdir);
- else{
- char *pt = src_arrp->base;
- while( pt < src_arrp->end ){
- src_file_path = *(char **)pt;
- src_file = fopen(src_file_path, "r");
- if(!src_file){
- fprintf(stderr,"Could not open source file %s.\n", src_file_path);
- err |= TRANCHE_ERR_SRC_OPEN;
- }else{
- tranche_send(src_file, target_arrp, tdir);
- if( fclose(src_file) == -1 ){perror(NULL); err |= TRANCHE_ERR_FCLOSE;}
- }
- pt += src_arrp->element_size;
- }
- }
-
- da_free(target_arrp);
- da_free(src_arrp);
- return err;
-}
diff --git a/module/tranche/src/tranche.lib.c b/module/tranche/src/tranche.lib.c
deleted file mode 100644
index 9c154ce..0000000
--- a/module/tranche/src/tranche.lib.c
+++ /dev/null
@@ -1,238 +0,0 @@
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-//--------------------------------------------------------------------------------
-// parsing
-
-char sp = ' ';
-char colon = ':';
-char slash = '/';
-char newline = '\n';
-char tab = '\t';
-char terminator = 0;
-
-
-char tranche_begin_tag[] = "#tranche";
-size_t tranche_begin_tag_len = 8;
-
-char tranche_end_tag[] = "#tranche-end";
-size_t tranche_end_tag_len = 12;
-
-// given a line
-// returns beginning of file name list
-static char *is_tranche_begin(char *pt){
- while( *pt && isspace(*pt) ) pt++;
- if(!*pt) return NULL;
- if( strncmp(pt, tranche_begin_tag, tranche_begin_tag_len) ) return NULL;
- return pt + tranche_begin_tag_len;
-}
-
-static char *is_tranche_end(char *pt){
- while( *pt && isspace(*pt) ) pt++;
- if(!*pt) return NULL;
- if( strncmp(pt, tranche_end_tag, tranche_end_tag_len) ) return NULL;
- return pt + tranche_end_tag_len;
-}
-
-static void parse_file_list(Da *file_names, char *pt, char *tdir){
- Da filename_arr;
- Da *fn_arrp = &filename_arr;
- da_alloc(fn_arrp,sizeof(char));
-
- while( *pt && isspace(*pt) ) pt++;
- while( *pt ){
- if(tdir){
- da_string_push(fn_arrp, tdir);
- da_push(fn_arrp, &slash);
- }
- while( *pt && !isspace(*pt) ){
- da_push(fn_arrp, pt);
- pt += fn_arrp->element_size;
- }
- da_push(fn_arrp, &terminator);
- char *file_name = strdup(fn_arrp->base);
- da_rewind(fn_arrp);
- da_push(file_names, &file_name);
- while( *pt && isspace(*pt) ) pt++;
- }
-}
-
-//--------------------------------------------------------------------------------
-// da_map calls
-
-static void tranche_open_fd(void *fnp, void *closure){
- char *file_name = *(char **)fnp;
- Da *fdap = (Da *)closure;
- int fd = open(file_name, O_WRONLY | O_APPEND | O_CREAT, 0666);
- if(fd == -1){
- fprintf(stderr, "Could not open file %s\n", file_name);
- return;
- }
- da_push(fdap, &fd);
- return;
-}
-static void tranche_open_fds(Da *fnap, Da *fdap){
- da_map(fnap, tranche_open_fd, fdap);
-}
-
-static void tranche_close_fd(void *fdp, void *closure){
- close(*(int *)fdp);
-}
-static void tranche_close_fds(Da *fdap){
- da_map(fdap, tranche_close_fd, NULL);
- da_rewind(fdap);
-}
-
-static void tranche_puts(void *fdp, void *string){
- write(*(int *)fdp, string, strlen(string));
-}
-static void tranche_puts_all(Da *fdap, char *string){
- da_map(fdap, tranche_puts, string);
-}
-
-//--------------------------------------------------------------------------------
-// does the work of tranching a source file
-
-int tranche_send(FILE *src, Da *arg_fdap, char *tdir){
- char *pt;
- Da line; // buffer holding the characters from a line
- Da file_name_arr; // an array of file name parameters parsed from a #tranche line
- Da fda; // open file descriptors corresponding to the file name parameters
- da_alloc(&line, sizeof(char));
- da_alloc(&file_name_arr, sizeof(char *));
- da_alloc(&fda, sizeof(int));
-
- while( !feof(src) ){
- da_string_input(&line, src);
- if( is_tranche_end(line.base) ) break;
- pt = is_tranche_begin(line.base);
- if(pt){ // then this line is the start of a nested tranche block
- parse_file_list(&file_name_arr, pt, tdir);
- tranche_open_fds(&file_name_arr, &fda);
- da_free_elements(&file_name_arr);
- tranche_send(src, &fda, tdir);
- tranche_close_fds(&fda);
- }else{
- da_pop(&line, NULL); // pop the terminating zero
- da_push(&line, &newline);
- da_push(&line, &terminator);
- tranche_puts_all(arg_fdap, line.base);
- }
- da_rewind(&line);
- }
-
- da_free(&line);
- da_free(&file_name_arr);
- da_free(&fda);
- return 0;
-}
-
-//--------------------------------------------------------------------------------
-// returns a list of unique target file names from a tranche source
-
-// make a list of the unique tranche target files found in src
-int tranche_target(FILE *src, Da *target_arrp, char *tdir){
- char *pt;
- Da line; // buffer holding the characters from a line
- Da file_name_arr;// an array of file name parameters parsed from a #tranche line
- da_alloc(&line, sizeof(char));
- da_alloc(&file_name_arr, sizeof(char *));
- while( !feof(src) ){
- da_string_input(&line, src);
- if( is_tranche_end(line.base) ) break;
- pt = is_tranche_begin(line.base);
- if(pt){ // then this line is the start of a nested tranche block
- parse_file_list(&file_name_arr, pt, tdir);
- da_strings_set_union(target_arrp, &file_name_arr, free);
- da_rewind(&file_name_arr);
- tranche_target(src, target_arrp, tdir);
- }
- da_rewind(&line);
- }
- da_free(&line);
- da_free(&file_name_arr);
- return 0;
-}
-
-// replaces trailing slashes with zeros
-void path_trim_slashes(char *path){
- if(!path || !*path) return;
- char *pt = path + strlen(path) - 1;
- loop:
- if(*pt == '/'){
- *pt = 0;
- if(pt != path){
- pt--;
- goto loop;
- }
- }
- return;
-}
-
-// write a make file rule for making the tranche targets
-void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *tdir){
-
- // array of the target file names -----------------------------------------
- Da target_arr;
- Da *target_arrp=&target_arr; // target array pointer
- da_alloc(target_arrp, sizeof(char *));
- tranche_target(src_file, target_arrp, tdir);
-
- // a space separated list of the target file names
- Da target_arr_as_string;
- Da *taasp = &target_arr_as_string;
- da_alloc(taasp, sizeof(char));
- char *pt = target_arrp->base; // char * because it points to a byte in the array
- if( pt < target_arrp->end ){
- da_string_push(taasp, *(char **)pt);
- pt += target_arrp->element_size;
- }
- while( pt < target_arrp->end ){
- da_push(taasp, &sp);
- da_string_push(taasp, *(char **)pt);
- pt += target_arrp->element_size;
- }
- da_free_elements(target_arrp);
- da_free(target_arrp);
-
- // construct then output the dependency line ----------------------------------------
- Da make_line_string;
- Da *mlsp = &make_line_string;
- da_alloc(mlsp, sizeof(char));
- da_cat(mlsp, taasp);
- da_push(mlsp, &colon);
- da_push(mlsp, &sp);
- da_string_push(mlsp, src_name);
- da_push(mlsp, &newline);
- write(mfile_fd, mlsp->base, mlsp->end - mlsp->base);
-
- // output action lines ----------------------------------------
- da_rewind(mlsp); // reuse make line buffer
- da_push(mlsp, &tab);
- da_string_push(mlsp, "rm -f ");
- da_cat(mlsp, taasp);
- da_push(mlsp, &newline);
- write(mfile_fd, mlsp->base, mlsp->end - mlsp->base);
-
- da_rewind(mlsp); // reuse the line buffer
- da_push(mlsp, &tab);
- da_string_push(mlsp, "tranche $<");
- if(tdir){
- da_string_push(mlsp, " -tdir ");
- da_string_push(mlsp, tdir);
- }
- da_push(mlsp, &newline);
- da_push(mlsp, &newline);
- write(mfile_fd, mlsp->base, mlsp->end - mlsp->base);
-
- da_free(taasp);
- da_free(mlsp);
- return;
-}
diff --git a/module/tranche/src/tranche.lib.h b/module/tranche/src/tranche.lib.h
deleted file mode 100644
index 575c97f..0000000
--- a/module/tranche/src/tranche.lib.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef TRANCHE_LIB_H
-#define TRANCHE_LIB_H
-
-#define TRANCHE_ERR_ARG_PARSE 1
-#define TRANCHE_ERR_SRC_OPEN 2
-#define TRANCHE_ERR_DST_OPEN 4
-#define TRANCHE_ERR_FCLOSE 8
-#define TRANCHE_ERR_HELP 16
-#define TRANCHE_ERR_SNAME 32
-
-void path_trim_slashes(char *path);
-int tranche_send(FILE *src, Da *arg_fds, char *tdir);
-int tranche_target(FILE *src, Da *targets, char *tdir);
-void tranche_make(FILE *src_file, char *src_name, int mfile_fd, char *tdir);
-
-#endif
diff --git a/module/tranche/test/try/test1.dat b/module/tranche/test/try/test1.dat
deleted file mode 100644
index b03df3f..0000000
--- a/module/tranche/test/try/test1.dat
+++ /dev/null
@@ -1,23 +0,0 @@
-
-#tranche test11.dat test12.dat
-The little red hen said to Mick, no thank you not today sir.
-And then all the barnes animals shouted out in glee.
-No more misery!
-#tranche test13.dat
-apple banana pear
-kiwi
-#tranche-end
-cows
-and cats
-#tranche-end
-
-the between space
-
-#tranche test14.dat
-int float if while
-do
-function
-#tranche-end
-
-#tranche test15.dat
-#tranche-end
\ No newline at end of file
diff --git a/module/tranche/test/try/test1.sh b/module/tranche/test/try/test1.sh
deleted file mode 100644
index 0551905..0000000
--- a/module/tranche/test/try/test1.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash -x
-./tranche test1.dat >test1stdout.dat
-diff -q test11.dat test11.dat.expected
-diff -q test12.dat test12.dat.expected
-diff -q test13.dat test13.dat.expected
-diff -q test14.dat test14.dat.expected
-diff -q test15.dat test15.dat.expected
-diff -q test1stdout.dat test1stdout.dat.expected
-rm test11.dat test12.dat test13.dat test14.dat test15.dat test1stdout.dat
-
diff --git a/module/tranche/test/try/test11.dat.expected b/module/tranche/test/try/test11.dat.expected
deleted file mode 100644
index 2c2904a..0000000
--- a/module/tranche/test/try/test11.dat.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-The little red hen said to Mick, no thank you not today sir.
-And then all the barnes animals shouted out in glee.
-No more misery!
-cows
-and cats
diff --git a/module/tranche/test/try/test12.dat.expected b/module/tranche/test/try/test12.dat.expected
deleted file mode 100644
index 2c2904a..0000000
--- a/module/tranche/test/try/test12.dat.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-The little red hen said to Mick, no thank you not today sir.
-And then all the barnes animals shouted out in glee.
-No more misery!
-cows
-and cats
diff --git a/module/tranche/test/try/test13.dat.expected b/module/tranche/test/try/test13.dat.expected
deleted file mode 100644
index 81fb20c..0000000
--- a/module/tranche/test/try/test13.dat.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-apple banana pear
-kiwi
diff --git a/module/tranche/test/try/test14.dat.expected b/module/tranche/test/try/test14.dat.expected
deleted file mode 100644
index 0d8b89b..0000000
--- a/module/tranche/test/try/test14.dat.expected
+++ /dev/null
@@ -1,3 +0,0 @@
-int float if while
-do
-function
diff --git a/module/tranche/test/try/test15.dat.expected b/module/tranche/test/try/test15.dat.expected
deleted file mode 100644
index e69de29..0000000
diff --git a/module/tranche/test/try/test1stdout.dat.expected b/module/tranche/test/try/test1stdout.dat.expected
deleted file mode 100644
index 4e519ff..0000000
--- a/module/tranche/test/try/test1stdout.dat.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-the between space
-
-
diff --git a/module/tranche/test/try/test2.c.expected b/module/tranche/test/try/test2.c.expected
deleted file mode 100644
index a4876a1..0000000
--- a/module/tranche/test/try/test2.c.expected
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-#include "test2.h"
-
-
-int f(int x){
- return x;
-}
-
-
diff --git a/module/tranche/test/try/test2.h.expected b/module/tranche/test/try/test2.h.expected
deleted file mode 100644
index fdc4d72..0000000
--- a/module/tranche/test/try/test2.h.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef TEST2_H
-#define TEST2_H
-int f(int x);
-#endif
diff --git a/module/tranche/test/try/test2.sh b/module/tranche/test/try/test2.sh
deleted file mode 100644
index c5617a8..0000000
--- a/module/tranche/test/try/test2.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash -x
-./tranche test2.trc.c >test2stdout.dat
-diff -q test2.c test2.c.expected
-diff -q test2.h test2.h.expected
-diff -q test2stdout.dat test2stdout.dat.expected
-rm test2.c test2.h test2stdout.dat
-
-
diff --git a/module/tranche/test/try/test2.trc.c b/module/tranche/test/try/test2.trc.c
deleted file mode 100644
index ff7d696..0000000
--- a/module/tranche/test/try/test2.trc.c
+++ /dev/null
@@ -1,23 +0,0 @@
-
-#tranche test2.c
-
-#tranche test2.h
-#ifndef TEST2_H
-#define TEST2_H
-#tranche-end
-
-#include "test2.h"
-
-#tranche test2.h
-int f(int x);
-#tranche-end
-
-int f(int x){
- return x;
-}
-
-#tranche test2.h
-#endif
-#tranche-end
-
-#tranche-end
diff --git a/module/tranche/test/try/test2stdout.dat.expected b/module/tranche/test/try/test2stdout.dat.expected
deleted file mode 100644
index 139597f..0000000
--- a/module/tranche/test/try/test2stdout.dat.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/module/tranche/test/try/test3.out.expected b/module/tranche/test/try/test3.out.expected
deleted file mode 100644
index 8bb7f8f..0000000
--- a/module/tranche/test/try/test3.out.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-test11.dat
-test12.dat
-test13.dat
-test14.dat
-test15.dat
\ No newline at end of file
diff --git a/module/tranche/test/try/test3.sh b/module/tranche/test/try/test3.sh
deleted file mode 100644
index 669739c..0000000
--- a/module/tranche/test/try/test3.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash -x
-./tranche-target test1.dat > test3.out
-diff -q test3.out test3.out.expected
-rm test3.out
-
-
diff --git a/module/tranche/test/try/test4.out.expected b/module/tranche/test/try/test4.out.expected
deleted file mode 100644
index c7ff184..0000000
--- a/module/tranche/test/try/test4.out.expected
+++ /dev/null
@@ -1,2 +0,0 @@
-test2.c
-test2.h
\ No newline at end of file
diff --git a/module/tranche/test/try/test4.sh b/module/tranche/test/try/test4.sh
deleted file mode 100644
index b40b49b..0000000
--- a/module/tranche/test/try/test4.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash -x
-./tranche-target test2.trc.c > test4.out
-diff -q test4.out test4.out.expected
-rm test4.out
-
-
diff --git a/module/tranche/test/try/test5.sh b/module/tranche/test/try/test5.sh
deleted file mode 100644
index b949f72..0000000
--- a/module/tranche/test/try/test5.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-./tranche test1.dat test2.trc.c > /dev/null
-
-diff -q test11.dat test11.dat.expected
-diff -q test12.dat test12.dat.expected
-diff -q test13.dat test13.dat.expected
-diff -q test14.dat test14.dat.expected
-diff -q test15.dat test15.dat.expected
-
-diff -q test2.c test2.c.expected
-diff -q test2.h test2.h.expected
-
-rm test11.dat test12.dat test13.dat test14.dat test15.dat
-rm test2.c test2.h
diff --git a/module/tranche/test/try/tranche b/module/tranche/test/try/tranche
deleted file mode 120000
index 982210d..0000000
--- a/module/tranche/test/try/tranche
+++ /dev/null
@@ -1 +0,0 @@
-../../exec/tranche
\ No newline at end of file
diff --git a/module/tranche/test/try/tranche-make b/module/tranche/test/try/tranche-make
deleted file mode 120000
index b3adcec..0000000
--- a/module/tranche/test/try/tranche-make
+++ /dev/null
@@ -1 +0,0 @@
-../../exec/tranche-make
\ No newline at end of file
diff --git a/module/tranche/test/try/tranche-target b/module/tranche/test/try/tranche-target
deleted file mode 120000
index 07d6f40..0000000
--- a/module/tranche/test/try/tranche-target
+++ /dev/null
@@ -1 +0,0 @@
-../../exec/tranche-target
\ No newline at end of file
diff --git a/tool/bin/@System.solv b/tool/bin/@System.solv
deleted file mode 100644
index 1e89182..0000000
Binary files a/tool/bin/@System.solv and /dev/null differ
diff --git a/tool/bin/gitadd b/tool/bin/gitadd
deleted file mode 100755
index 11c23a2..0000000
--- a/tool/bin/gitadd
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-set -x
-make -C "$PROJECT_SUBU" dist-clean
-git add "$@"
-
diff --git a/tool/bin/makeheaders b/tool/bin/makeheaders
deleted file mode 100755
index a50d9a0..0000000
Binary files a/tool/bin/makeheaders and /dev/null differ
diff --git a/tool/bin/setuid_root.sh b/tool/bin/setuid_root.sh
deleted file mode 100755
index aedd564..0000000
--- a/tool/bin/setuid_root.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-chown root "$@" && \
-chmod u+rsx,u-w,go+rx-s-w "$@"
-
diff --git a/tool/bin/tranche b/tool/bin/tranche
deleted file mode 100755
index 886b915..0000000
Binary files a/tool/bin/tranche and /dev/null differ
diff --git a/tool/bin/tranche-make b/tool/bin/tranche-make
deleted file mode 100755
index d2f5d91..0000000
Binary files a/tool/bin/tranche-make and /dev/null differ
diff --git a/tool/bin/tranche-target b/tool/bin/tranche-target
deleted file mode 100755
index 8ef74f3..0000000
Binary files a/tool/bin/tranche-target and /dev/null differ
diff --git a/tool/doc/makefile.txt b/tool/doc/makefile.txt
deleted file mode 100644
index 722de84..0000000
--- a/tool/doc/makefile.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-these are the comments from my RT makefile:
-
-#
-# 2010 11 20 TWL Created
-# 2011 05 26 TWL Modified to generalize
-# 2012 02 23 NLS Add ECHO variable to use on different environnement
-# corrected setup macro --> add include directory in the path to copy
-# corrected install macro --> change the name of installed library : lib$(LIB)$(LIBSUFFIX)
-# changed DOC_DIR directory name to 5_documents
-# 2012 02 23 TWL removed LIB variable which is now set from the command line so
-# so that all source dirs can use the same makefile
-# 2012 02 23 TWL added target make dist_clean which also deletes the 2_makefile_deps file
-# 2012 04 11 AWW added creation of temporary disk before each test is run
-# 2012 06 05 TWL moved tests and try .cc files to directories. caused rtmake tests to
-# dist_clean and make deps
-#
-#
-#----------------------------------------------------------------------------
-# use this makefile to compile and test the code:
-#
-# for a first time run, or for regression use the following:
-#
-# $ make setup # makes the directories, though should already exist
-# $ make regress
-#
-# the usual development workflow makes use of these:
-#
-# $ make deps # only when needed, for example if headers includes change or new files introduced
-# $ cd tests; make deps # only when needed
-# $ make lib # this makes the local library
-# $ make tests # this updates tests and compiles
-# $ make clean # deletes the .o files and library to force a recompile
-# $ cd 1_tests; make clean
-#
-# for a release of a component
-#
-# $ make regress
-# $ make install # this will only work if all the tests in 1_tests are passing
-#
-# before a checkin
-#
-# $ make dist_clean # will also clean the tests and try directories
-#
-# .lib.cc c++ files taken as source of object files for local build library
-# .exl.cc c++ files taken to have main calls and are linked against local build libary
-# .ex.cc c++ files taken to have main calls and are not linked against the local build library
-# there are no rules for other files in this makefile
-#
-# about dependencies
-# The makefile has no way of knowing if an edit changed the dependencies. Often they do not
-# and it would be unwieldy to make the deps every time. Hence *the programmer* must delete
-# the deps file if he has made any changes that change the dependencies.
-#
-# The makefile will make the 2_makefile_deps if the file is missing.
-#
-#
-# about testing
-#
-# the name of the directory you run make in is taken to also be: the name of the library,
-# the name of the main include file (with a .h added), and the name of the include directory
-# where the individual headers are found. It is called LIB
-#
-# test programs are kept in a subdirectory called 1_tests, and are either .exl.cc, ex.cc,
-# .sh files. When 'make tests' target is invoked they are all run. Test executables return 0
-# if the test fails, non-zero otherwise.
-#
-# to remove a test from the pool move it into the subdirectory in 1_tests, 9_broken,
-# 5_more_tests of 5_scratch. broken tests are things that are known but must be fixed
-# before a release. 5_more_tests are tests being worked on. 5_scratch is stuff that is
-# probably going to be deleted. if there is a 5_deprecated, that is for good stuff but it
-# is no longer used for some reason or other.
-#
-# There is a standard source code template and a
-# messaging convention. Also, the names, by convention,are test_xxxx_ where xxx is a
-# hexadecimal series nummber. If all the test executables pass the file 1_TESTS_PASSED is
-# left in the directory. Otherwise the file 1_TESTS_FAILED is left in the directory.
-#
-# about release directory
-#
-# this is set in the ApplicationBase variable by rt_init
-#
-# after the tests pass stuff might be copied to the release directory using
-#
-# make install
-#
-# the release directory must have these subdirectories:
-#
-# bin documents include src
-#
-#
-#
diff --git a/tool/doc/makeheaders-notes.txt b/tool/doc/makeheaders-notes.txt
deleted file mode 100644
index 5aebda9..0000000
--- a/tool/doc/makeheaders-notes.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-
-This worked to force the include to be part of the interface:
-
-#if INTERFACE
-#include
-#endif
-
-But this did not:
-
-#if INTERFACE
- #include
-#endif
-
-makeheaders looks to be sensitive to indentation
-
-
diff --git a/tool/doc/makeheaders.html b/tool/doc/makeheaders.html
deleted file mode 100644
index 289da58..0000000
--- a/tool/doc/makeheaders.html
+++ /dev/null
@@ -1,1150 +0,0 @@
-
-The Makeheaders Program
-
-
The Makeheaders Program
-
-
-
-This document describes makeheaders,
-a tool that automatically generates “.h”
-files for a C or C++ programming project.
-
-A piece of C source code can be one of two things:
-a declaration or a definition.
-A declaration is source text that gives information to the
-compiler but doesn't directly result in any code being generated.
-A definition is source text that results in executable machine
-instructions or initialization data.
-(These two terms are sometimes used inconsistently by other authors.
-In particular, many people reverse the meanings of these words when
-discussing Pascal or Ada code.
-The meanings described here are the same as used in the ANSI-C
-standards document.)
-
-
-
-Declarations in C include things such as the following:
-
-
Typedefs.
-
Structure, union and enumeration declarations.
-
Function and procedure prototypes.
-
Preprocessor macros and #defines.
-
“extern” variable declarations.
-
-
-
-
-Definitions in C, on the other hand, include these kinds of things:
-
-
Variable definitions.
-
The bodies of functions and procedures.
-
Initialization data.
-
-
-
-
-The distinction between a declaration and a definition is common in
-modern software engineering.
-Another way of looking at the difference is that the declaration
-is the interface and the definition is the implementation.
-
-
-
-In C programs, it has always been the tradition that declarations are
-put in files with the “.h” suffix and definitions are
-placed in “.c” files.
-The .c files contain “#include” preprocessor statements
-that cause the contents of .h files to be included as part of the
-source code when the .c file is compiled.
-In this way, the .h files define the interface to a subsystem and
-the .c files define how the subsystem is implemented.
-
-
-
-
1.1 Problems With The Traditional Approach
-
-
-As the art of computer programming continues to advance, and the size
-and complexity of programs continues to swell, the traditional C
-approach of placing declarations and definitions in separate files begins
-to present the programmer with logistics and
-maintenance problems.
-To wit:
-
-
-
-
-
-In large codes with many source files, it becomes difficult to determine
-which .h files should be included in which .c files.
-
-It is typically the case that a .h file will be forced to include
-another .h files, which in turn might include other .h files,
-and so forth.
-The .c file must be recompiled when any of the .h files in this chain
-are altered, but it can be difficult to determine what .h files are found
-in the include chain.
-A frequent Makefile error is to omit some .h files from a dependency
-list even though those files are on the include file chain.
-
-Some information is common to both the declaration and the definition of
-an object in C, and so must be repeated in both the .h and the .c files
-for that object.
-In a large project, it can become increasingly difficult to keep the two
-files in sync.
-
-When a .c file includes a .h file and the .h files changes, the .c file
-must be recompiled, even if the part of the .h file that changed is not
-actually used by the .c file.
-In a large program, it is generally the case that almost every .c file ends up
-depending on one or two of the more important .h files, and so when those .h
-files change, the entire program must be recompiled.
-It also happens that those important .h files tend to be the ones that
-change most frequently.
-This means that the entire program must be recompiled frequently,
-leading to a lengthy modify-compile-test cycle and a corresponding
-decrease in programmer productivity.
-
-The C programming language requires that declarations depending upon
-each other must occur in a particular order.
-In a program with complex, interwoven data structures, the correct
-declaration order can become very difficult to determine manually,
-especially when the declarations involved are spread out over several
-files.
-
-
-
-
-
1.2 The Makeheaders Solution
-
-
-The makeheaders program is designed to ameliorate the problems associated
-with the traditional C programming model by automatically generating
-the interface information in the .h files from
-interface information contained in other .h files and
-from implementation information in the .c files.
-When the makeheaders program is run, it scans the source
-files for a project,
-then generates a series of new .h files, one for each .c file.
-The generated .h files contain exactly those declarations required by the
-corresponding .c files, no more and no less.
-
-
-
-The makeheaders programming model overcomes all of the objections to the
-traditional C programming model.
-
-
-Because all declarations needed by a .c file are contained in a
-single .h file, there is never any question about what .h files
-a .c will need to include. If the .c file is named
-alpha.c then it must include only the single .h file
-named alpha.h.
-(The .c file might also use some include files from the standard
-library, such as <stdio.h>, but that is another matter.)
-
-The generated .h files do not include other .h files, and so there
-are no include chains to worry about.
-The file alpha.c depends on alpha.h and
-nothing more.
-
-There is still duplication in the .h and the .c file, but because
-the duplicate information is automatically generated, it is no longer
-a problem.
-Simply rerun makeheaders to resynchronize everything.
-
-The generated .h file contains the minimal set of declarations needed
-by the .c file.
-This means that when something changes, a minimal amount of recompilation
-is required to produce an updated executable.
-Experience has shown that this gives a dramatic improvement
-in programmer productivity by facilitating a rapid modify-compile-test
-cycle during development.
-
-The makeheaders program automatically sorts declarations into the
-correct order, completely eliminating the wearisome and error-prone
-task of sorting declarations by hand.
-
-
-
-
-In addition, the makeheaders program is fast and unintrusive.
-It is a simple matter to incorporate makeheaders into a Makefile
-so that makeheaders will be run automatically whenever the project
-is rebuilt.
-And the burden of running makeheaders is light.
-It will easily process tens of thousands of lines of source
-code per second.
-
-
-
-
2.0 Running The Makeheaders Program
-
-
-The makeheaders program is very easy to run.
-If you have a collection of C source code and include files in the working
-directory, then you can run makeheaders to generate appropriate .h
-files using the following command:
-
- makeheaders *.[ch]
-
-That's really all there is to it!
-This command will generate one .h file for every .c file.
-Any .h files that were generated by a prior run of makeheaders
-are ignored,
-but manually entered .h files
-that contain structure declarations and so forth will be scanned and
-the declarations will be copied into the generated .h files as
-appropriate.
-But if makeheaders sees that the .h file that it has generated is no
-different from the .h file it generated last time, it doesn't update
-the file.
-This prevents the corresponding .c files from having to
-be needlessly recompiled.
-
-
-
-There are several options to the makeheaders program that can
-be used to alter its behavior.
-The default behavior is to write a single .h file for each .c file and
-to give the .h file the same base name as the .c file.
-Instead of generating a whole mess of .h files, you can, if you choose,
-generate a single big .h file that contains all declarations needed
-by all the .c files. Do this using the -h option to makeheaders.
-As follows:
-
- makeheaders -h *.[ch] >common.h
-
-With the -h option, the .h file is not actually written to a disk file but
-instead appears on standard output, where you are free to redirect it
-into the file of your choice.
-
-
-
-A similar option is -H. Like the lower-case -h option, big -H
-generates a single include file on standard output. But unlike
-small -h, the big -H only emits prototypes and declarations that
-have been designated as “exportable”.
-The idea is that -H will generate an include file that defines
-the interface to a library.
-More will be said about this in section 3.4.
-
-
-
-Sometimes you want the base name of the .c file and the .h file to
-be different.
-For example, suppose you want the include file for alpha.c
-to be called beta.h.
-In this case, you would invoke makeheaders as follows:
-
- makeheaders alpha.c:beta.h
-
-Any time a filename argument contains a colon, the name before the
-colon is taken to be the name of the .c file and the name after the
-colon is taken to be the name of the .h file.
-You can't use the shell's wildcard mechanism with this approach, but that
-normally isn't a problem in Makefiles, which is where this stuff
-comes in handy.
-
-
-
-If you want a particular file to be scanned by makeheaders but you
-don't want makeheaders to generate a header file for that file,
-then you can supply an empty header filename, like this:
-
- makeheaders alpha.c beta.c gamma.c:
-
-In this example, makeheaders will scan the three files named
-“alpha.c”,
-“beta.c” and
-“gamma.c”
-but because of the colon on the end of third filename
-it will only generate headers for the first two files.
-Unfortunately,
-it is not possible to get makeheaders to process any file whose
-name contains a colon.
-
-
-
-In a large project, the length of the command line for makeheaders
-can become very long.
-If the operating system doesn't support long command lines
-(example: DOS and Win32) you may not be able to list all of the
-input files in the space available.
-In that case, you can use the “-f” option followed
-by the name of a file to cause makeheaders to read command line
-options and filename from the file instead of from the command line.
-For example, you might prepare a file named “mkhdr.dat”
-that contains text like this:
-
-The “-local” option causes makeheaders to
-generate of prototypes for “static” functions and
-procedures.
-Such prototypes are normally omitted.
-
-
-
-Finally, makeheaders also includes a “-doc” option.
-This command line option prevents makeheaders from generating any
-headers at all.
-Instead, makeheaders will write to standard output
-information about every definition and declaration that it encounters
-in its scan of source files.
-The information output includes the type of the definition or
-declaration and any comment that preceeds the definition or
-declaration.
-The output is in a format that can be easily parsed, and is
-intended to be read by another program that will generate
-documentation about the program.
-We'll talk more about this feature later.
-
-
-
-If you forget what command line options are available, or forget
-their exact name, you can invoke makeheaders using an unknown
-command line option (like “--help” or
-“-?”)
-and it will print a summary of the available options on standard
-error.
-If you need to process a file whose name begins with
-“-”,
-you can prepend a “./” to its name in order to get it
-accepted by the command line parser.
-Or, you can insert the special option “--” on the
-command line to cause all subsequent command line arguments to be treated as
-filenames even if their names begin with “-”.
-
-
-
-
3.0 Preparing Source Files For Use With Makeheaders
-
-
-Very little has to be done to prepare source files for use with
-makeheaders since makeheaders will read and understand ordinary
-C code.
-But it is important that you structure your files in a way that
-makes sense in the makeheaders context.
-This section will describe several typical uses of makeheaders.
-
-
-
-
3.1 The Basic Setup
-
-
-The simplest way to use makeheaders is to put all definitions in
-one or more .c files and all structure and type declarations in
-separate .h files.
-The only restriction is that you should take care to chose basenames
-for your .h files that are different from the basenames for your
-.c files.
-Recall that if your .c file is named (for example)
-“alpha.c”
-makeheaders will attempt to generate a corresponding header file
-named “alpha.h”.
-For that reason, you don't want to use that name for
-any of the .h files you write since that will prevent makeheaders
-from generating the .h file automatically.
-
-
-
-The structure of a .c file intented for use with makeheaders is very
-simple.
-All you have to do is add a single “#include” to the
-top of the file that sources the header file that makeheaders will generate.
-Hence, the beginning of a source file named “alpha.c”
-might look something like this:
-
-
-
- /*
- * Introductory comment...
- */
- #include "alpha.h"
-
- /* The rest of your code... */
-
-
-
-Your manually generated header files require no special attention at all.
-Code them as you normally would.
-However, makeheaders will work better if you omit the
-“#if” statements people often put around the outside of
-header files that prevent the files from being included more than once.
-For example, to create a header file named “beta.h”,
-many people will habitually write the following:
-
-
- #ifndef BETA_H
- #define BETA_H
-
- /* declarations for beta.h go here */
-
- #endif
-
-
-You can forego this cleverness with makeheaders.
-Remember that the header files you write will never really be
-included by any C code.
-Instead, makeheaders will scan your header files to extract only
-those declarations that are needed by individual .c files and then
-copy those declarations to the .h files corresponding to the .c files.
-Hence, the “#if” wrapper serves no useful purpose.
-But it does make makeheaders work harder, forcing it to put
-the statements
-
-
- #if !defined(BETA_H)
- #endif
-
-
-around every declaration that it copies out of your header file.
-No ill effect should come of this, but neither is there any benefit.
-
-
-
-Having prepared your .c and .h files as described above, you can
-cause makeheaders to generate its .h files using the following simple
-command:
-
-
- makeheaders *.[ch]
-
-
-The makeheaders program will scan all of the .c files and all of the
-manually written .h files and then automatically generate .h files
-corresponding to all .c files.
-
-
-
-Note that
-the wildcard expression used in the above example,
-“*.[ch]”,
-will expand to include all .h files in the current directory, both
-those entered manually be the programmer and others generated automatically
-by a prior run of makeheaders.
-But that is not a problem.
-The makeheaders program will recognize and ignore any files it
-has previously generated that show up on its input list.
-
-
-
-
3.2 What Declarations Get Copied
-
-
-The following list details all of the code constructs that makeheaders
-will extract and place in
-the automatically generated .h files:
-
-
-
-
-When a function is defined in any .c file, a prototype of that function
-is placed in the generated .h file of every .c file that
-calls the function.
-
-
If the “static” keyword of C appears at the
-beginning of the function definition, the prototype is suppressed.
-If you use the “LOCAL” keyword where you would normally
-say “static”, then a prototype is generated, but it
-will only appear in the single header file that corresponds to the
-source file containing the function. For example, if the file
-alpha.c contains the following:
-
- LOCAL int testFunc(void){
- return 0;
- }
-
-Then the header file alpha.h will contain
-
- #define LOCAL static
- LOCAL int testFunc(void);
-
-However, no other generated header files will contain a prototype for
-testFunc() since the function has only file scope.
-
-
When the “LOCAL” keyword is used, makeheaders will
-also generate a #define for LOCAL, like this:
-
- #define LOCAL static
-
-so that the C compiler will know what it means.
-
-
If you invoke makeheaders with a “-local”
-command-line option, then it treats the “static”
-keyword like “LOCAL” and generates prototypes in the
-header file that corresponds to the source file containing the function
-definition.
-
-
-When a global variable is defined in a .c file, an
-“extern”
-declaration of that variable is placed in the header of every
-.c file that uses the variable.
-
-
-
-When a structure, union or enumeration declaration or a
-function prototype or a C++ class declaration appears in a
-manually produced .h file, that declaration is copied into the
-automatically generated
-.h files of all .c files that use the structure, union, enumeration,
-function or class.
-But declarations that appear in a
-.c file are considered private to that .c file and are not copied into
-any automatically generated files.
-
-
-
-All #defines and typedefs that appear in manually produced .h files
-are copied into automatically generated .h files as needed.
-Similar constructs that appear in .c files are considered private to
-those files and are not copied.
-
-
-
-When a structure, union or enumeration declaration appears in a .h
-file, makeheaders will automatically
-generate a typedef that allows the declaration to be referenced without
-the “struct”, “union” or
-“enum” qualifier.
-In other words, if makeheaders sees the code:
-
- struct Examp { /* ... */ };
-
-it will automatically generate a corresponding typedef like this:
-
- typedef struct Examp Examp;
-
-
-
-
-Makeheaders generates an error message if it encounters a function or
-variable definition within a .h file.
-The .h files are suppose to contain only interface, not implementation.
-C compilers will not enforce this convention, but makeheaders does.
-
-
-
-As a final note, we observe that automatically generated declarations
-are ordered as required by the ANSI-C programming language.
-If the declaration of some structure “X” requires a
-prior declaration of another structure “Y”, then Y will
-appear first in the generated headers.
-
-
-
-
3.3 How To Avoid Having To Write Any Header Files
-
-
-In my experience, large projects work better if all of the manually
-written code is placed in .c files and all .h files are generated
-automatically.
-This is slightly different for the traditional C method of placing
-the interface in .h files and the implementation in .c files, but
-it is a refreshing change that brings a noticable improvement to the
-coding experience.
-Others, I believe, share this view since I've
-noticed recent languages (ex: java, tcl, perl, awk) tend to
-support the one-file approach to coding as the only option.
-
-
-
-The makeheaders program supports putting both
-interface and implementation into the same source file.
-But you do have to tell makeheaders which part of the source file is the
-interface and which part is the implementation.
-Makeheaders has to know this in order to be able to figure out whether or
-not structures declarations, typedefs, #defines and so forth should
-be copied into the generated headers of other source files.
-
-
-
-You can instruct makeheaders to treat any part of a .c file as if
-it were a .h file by enclosing that part of the .c file within:
-
- #if INTERFACE
- #endif
-
-Thus any structure definitions that appear after the
-“#if INTERFACE” but before the corresponding
-“#endif” are eligable to be copied into the
-automatically generated
-.h files of other .c files.
-
-
-
-If you use the “#if INTERFACE” mechanism in a .c file,
-then the generated header for that .c file will contain a line
-like this:
-
- #define INTERFACE 0
-
-In other words, the C compiler will never see any of the text that
-defines the interface.
-But makeheaders will copy all necessary definitions and declarations
-into the .h file it generates, so .c files will compile as if the
-declarations were really there.
-This approach has the advantage that you don't have to worry with
-putting the declarations in the correct ANSI-C order -- makeheaders
-will do that for you automatically.
-
-
-
-Note that you don't have to use this approach exclusively.
-You can put some declarations in .h files and others within the
-“#if INTERFACE” regions of .c files.
-Makeheaders treats all declarations alike, no matter where they
-come from.
-You should also note that a single .c file can contain as many
-“#if INTERFACE” regions as desired.
-
-
-
-
3.4 Designating Declarations For Export
-
-
-In a large project, one will often construct a hierarchy of
-interfaces.
-For example, you may have a group of 20 or so files that form
-a library used in several other parts of the system.
-Each file in this library will present two interfaces.
-One interface will be the routines and data structures it is
-willing to share with other files in the same library, and the
-second interface is those routines and data structures it wishes
-to make available to other subsystems.
-(The second interface is normally a subset of the first.)
-Ordinary C does not provide support for a tiered interface
-like this, but makeheaders does.
-
-
-
-Using makeheaders, it is possible to designate routines and data
-structures as being for “export”.
-Exported objects are visible not only to other files within the
-same library or subassembly but also to other
-libraries and subassemblies in the larger program.
-By default, makeheaders only makes objects visible to other members
-of the same library.
-
-
-
-That isn't the complete truth, actually.
-The semantics of C are such that once an object becomes visible
-outside of a single source file, it is also visible to any user
-of the library that is made from the source file.
-Makeheaders can not prevent outsiders for using non-exported resources,
-but it can discourage the practice by refusing to provide prototypes
-and declarations for the services it does not want to export.
-Thus the only real effect of the making an object exportable is
-to include it in the output makeheaders generates when it is run
-using the -H command line option.
-This is not a perfect solution, but it works well in practice.
-
-
-
-But trouble quickly arises when we attempt to devise a mechanism for
-telling makeheaders which prototypes it should export and which it should
-keep local.
-The built-in “static” keyword of C works well for
-prohibiting prototypes from leaving a single source file, but because C doesn't
-support a linkage hierarchy, there is nothing in the C language to help us.
-We'll have to invite our own keyword: “EXPORT”
-
-
-
-Makeheaders allows the EXPORT keyword to precede any function or
-procedure definition.
-The routine following the EXPORT keyword is then eligable to appear
-in the header file generated using the -H command line option.
-Note that if a .c file contains the EXPORT keyword, makeheaders will
-put the macro
-
- #define EXPORT
-
-in the header file it generates for the .c file so that the EXPORT keyword
-will never be seen by the C compiler.
-
-
-
-But the EXPORT keyword only works for function and procedure definitions.
-For structure, union and enum definitions, typedefs, #defines and
-class declarations, a second mechanism is used.
-Just as any declarations or definition contained within
-
- #if INTERFACE
- #endif
-
-are visible to all files within the library, any declarations
-or definitions within
-
- #if EXPORT_INTERFACE
- #endif
-
-will become part of the exported interface.
-The “#if EXPORT_INTERFACE” mechanism can be used in
-either .c or .h files.
-(The “#if INTERFACE” can also be used in both .h and
-.c files, but since it's use in a .h file would be redundant, we haven't
-mentioned it before.)
-
-
-
-
3.5 Local declarations processed by makeheaders
-
-
-Structure declarations and typedefs that appear in .c files are normally
-ignored by makeheaders.
-Such declarations are only intended for use by the source file in which
-they appear and so makeheaders doesn't need to copy them into any
-generated header files.
-We call such declarations “private”.
-
-
-
-Sometimes it is convenient to have makeheaders sort a sequence
-of private declarations into the correct order for us automatically.
-Or, we could have static functions and procedures for which we would like
-makeheaders to generate prototypes, but the arguments to these
-functions and procedures uses private declarations.
-In both of these cases, we want makeheaders to be aware of the
-private declarations and copy them into the local header file,
-but we don't want makeheaders to propagate the
-declarations outside of the file in which they are declared.
-
-
-
-When this situation arises, enclose the private declarations
-within
-
- #if LOCAL_INTERFACE
- #endif
-
-A “LOCAL_INTERFACE” block works very much like the
-“INTERFACE” and
-“EXPORT_INTERFACE”
-blocks described above, except that makeheaders insures that the
-objects declared in a LOCAL_INTERFACE are only visible to the
-file containing the LOCAL_INTERFACE.
-
-
-
-
3.6 Using Makeheaders With C++ Code
-
-
-You can use makeheaders to generate header files for C++ code, in
-addition to C.
-Makeheaders will recognize and copy both “class”
-declarations
-and inline function definitions, and it knows not to try to generate
-prototypes for methods.
-
-
-
-In fact, makeheaders is smart enough to be used in projects that employ
-a mixture of C and C++.
-For example, if a C function is called from within a C++ code module,
-makeheaders will know to prepend the text
-
- extern "C"
-
-to the prototype for that function in the C++ header file.
-Going the other way,
-if you try to call a C++ function from within C, an
-appropriate error message is issued, since C++ routines can not
-normally be called by C code (due to fact that most C++ compilers
-use name mangling to facilitate type-safe linkage.)
-
-
-
-No special command-line options are required to use makeheaders with
-C++ input. Makeheaders will recognize that its source code is C++
-by the suffix on the source code filename. Simple ".c" or ".h" suffixes
-are assumed to be ANSI-C. Anything else, including ".cc", ".C" and
-".cpp" is assumed to be C++.
-The name of the header file generated by makeheaders is derived from
-the name of the source file by converting every "c" to "h" and
-every "C" to "H" in the suffix of the filename.
-Thus the C++ source
-file “alpha.cpp” will induce makeheaders to
-generate a header file named “alpha.hpp”.
-
-
-
-Makeheaders augments class definitions by inserting prototypes to
-methods where appropriate. If a method definition begins with one
-of the special keywords PUBLIC, PROTECTED, or
-PRIVATE (in upper-case to distinguish them from the regular
-C++ keywords with the same meaning) then a prototype for that
-method will be inserted into the class definition. If none of
-these keywords appear, then the prototype is not inserted. For
-example, in the following code, the constructor is not explicitly
-declared in the class definition but makeheaders will add it there
-because of the PUBLIC keyword that appears before the constructor
-definition.
-
-The first form is preferred because only a single declaration of
-the constructor is required. The second form requires two declarations,
-one in the class definition and one on the defintion of the constructor.
-
-
-
3.6.1 C++ Limitations
-
-
-Makeheaders does not understand more recent
-C++ syntax such as templates and namespaces.
-Perhaps these issues will be addressed in future revisions.
-
-
-
-
3.7 Conditional Compilation
-
-
-The makeheaders program understands and tracks the conditional
-compilation constructs in the source code files it scans.
-Hence, if the following code appears in a source file
-
-The conditional compilation constructs can be nested to any depth.
-Makeheaders also recognizes the special case of
-
- #if 0
- #endif
-
-and treats the enclosed text as a comment.
-
-
-
-
3.8 Caveats
-
-
-The makeheaders system is designed to be robust
-but it is possible for a devious programmer to fool the system,
-usually with unhelpful consequences.
-This subsection is a guide to helping you avoid trouble.
-
-
-
-Makeheaders does not understand the old K&R style of function
-and procedure definitions.
-It only understands the modern ANSI-C style, and will probably
-become very confused if it encounters an old K&R function.
-Therefore you should take care to avoid putting K&R function definitions
-in your code.
-
-
-
-Makeheaders does not understand when you define more than one
-global variable with the same type separated by a comma.
-In other words, makeheaders does not understand this:
-
- int a = 4, b = 5;
-
-The makeheaders program wants every variable to have its own
-definition. Like this:
-
- int a = 4;
- int b = 5;
-
-Notice that this applies to global variables only, not to variables
-you declare inside your functions.
-Since global variables ought to be exceedingly rare, and since it is
-good style to declare them separately anyhow, this restriction is
-not seen as a terrible hardship.
-
-
-
-Makeheaders does not support defining an enumerated or aggregate type in
-the same statement as a variable declaration. None of the following
-statements work completely:
-
-struct {int field;} a;
-struct Tag {int field;} b;
-struct Tag c;
-
-Instead, define types separately from variables:
-
-#if INTERFACE
-struct Tag {int field;};
-#endif
-Tag a;
-Tag b; /* No more than one variable per declaration. */
-Tag c; /* So must put each on its own line. */
-
-The makeheaders program processes its source file prior to sending
-those files through the C preprocessor.
-Hence, if you hide important structure information in preprocessor defines,
-makeheaders might not be able to successfully extract the information
-it needs from variables, functions and procedure definitions.
-For example, if you write this:
-
- #define BEGIN {
- #define END }
-
-at the beginning of your source file, and then try to create a function
-definition like this:
-
- char *StrDup(const char *zSrc)
- BEGIN
- /* Code here */
- END
-
-then makeheaders won't be able to find the end of the function definition
-and bad things are likely to happen.
-
-
-
-For most projects the code constructs that makeheaders cannot
-handle are very rare.
-As long as you avoid excessive cleverness, makeheaders will
-probably be able to figure out what you want and will do the right
-thing.
-
-
-
-Makeheaders has limited understanding of enums. In particular, it does
-not realize the significance of enumerated values, so the enum is not
-emitted in the header files when its enumerated values are used unless
-the name associated with the enum is also used. Moreover, enums can be
-completely anonymous, e.g. “enum {X, Y, Z};”.
-Makeheaders ignores such enums so they can at least be used within a
-single source file. Makeheaders expects you to use #define constants
-instead. If you want enum features that #define lacks, and you need the
-enum in the interface, bypass makeheaders and write a header file by
-hand, or teach makeheaders to emit the enum definition when any of the
-enumerated values are used, rather than only when the top-level name (if
-any) is used.
-
-
-
-
4.0 Using Makeheaders To Generate Documentation
-
-
-Many people have observed the advantages of generating program
-documentation directly from the source code:
-
-
Less effort is involved. It is easier to write a program than
- it is to write a program and a document.
-
The documentation is more likely to agree with the code.
- When documentation is derived directly from the code, or is
- contained in comments immediately adjacent to the code, it is much
- more likely to be correct than if it is contained in a separate
- unrelated file in a different part of the source tree.
-
Information is kept in only one place. When a change occurs
- in the code, it is not necessary to make a corresponding change
- in a separate document. Just rerun the documentation generator.
-
-The makeheaders program does not generate program documentation itself.
-But you can use makeheaders to parse the program source code, extract
-the information that is relevant to the documentation and to pass this
-information to another tool to do the actual documentation preparation.
-
-
-
-When makeheaders is run with the “-doc” option, it
-emits no header files at all.
-Instead, it does a complete dump of its internal tables to standard
-output in a form that is easily parsed.
-This output can then be used by another program (the implementation
-of which is left as an exercise to the reader) that will use the
-information to prepare suitable documentation.
-
-
-
-The “-doc” option causes makeheaders to print
-information to standard output about all of the following objects:
-
-
C++ class declarations
-
Structure and union declarations
-
Enumerations
-
Typedefs
-
Procedure and function definitions
-
Global variables
-
Preprocessor macros (ex: “#define”)
-
-For each of these objects, the following information is output:
-
-
The name of the object.
-
The type of the object. (Structure, typedef, macro, etc.)
-
Flags to indicate if the declaration is exported (contained within
- an EXPORT_INTERFACE block) or local (contained with LOCAL_INTERFACE).
-
A flag to indicate if the object is declared in a C++ file.
-
The name of the file in which the object was declared.
-
The complete text of any block comment that preceeds the declarations.
-
If the declaration occurred inside a preprocessor conditional
- (“#if”) then the text of that conditional is
- provided.
-
The complete text of a declaration for the object.
-
-The exact output format will not be described here.
-It is simple to understand and parse and should be obvious to
-anyone who inspects some sample output.
-
-
-
-
5.0 Compiling The Makeheaders Program
-
-
-The source code for makeheaders is a single file of ANSI-C code,
-approximately 3000 lines in length.
-The program makes only modest demands of the system and C library
-and should compile without alteration on most ANSI C compilers
-and on most operating systems.
-It is known to compile using several variations of GCC for Unix
-as well as Cygwin32 and MSVC 5.0 for Win32.
-
-
-
-
6.0 History
-
-
-The makeheaders program was first written by D. Richard Hipp
-(also the original author of
-SQLite and
-Fossil) in 1993.
-Hipp open-sourced the project immediately, but it never caught
-on with any other developers and it continued to be used mostly
-by Hipp himself for over a decade. When Hipp was first writing
-the Fossil version control system in 2006 and 2007, he used
-makeheaders on that project to help simplify the source code.
-As the popularity of Fossil increased, the makeheaders
-that was incorporated into the Fossil source tree became the
-"official" makeheaders implementation.
-
-
-
-As this paragraph is being composed (2016-11-05), Fossil is the
-only project known to Hipp that is still using makeheaders. On
-the other hand, makeheaders has served the Fossil project well and
-there are no plans remove it.
-
-
-
-
7.0 Summary And Conclusion
-
-
-The makeheaders program will automatically generate a minimal header file
-for each of a set of C source and header files, and will
-generate a composite header file for the entire source file suite,
-for either internal or external use.
-It can also be used as the parser in an automated program
-documentation system.
-
-
-
-The makeheaders program has been in use since 1994,
-in a wide variety of projects under both UNIX and Win32.
-In every project where it has been used, makeheaders has proven
-to be a very helpful aid
-in the construction and maintenance of large C codes.
-In at least two cases, makeheaders has facilitated development
-of programs that would have otherwise been all but impossible
-due to their size and complexity.
-
-
-
diff --git a/tool/lib/bashrc b/tool/lib/bashrc
deleted file mode 100755
index b2f3ded..0000000
--- a/tool/lib/bashrc
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-
-umask 0077
-
-if [ $INSIDE_EMACS ]; then
- echo Hello Emacs
-fi
-export PS1='\n$(/usr/local/bin/Z)\n\u@\h§\w§\n> '
-export PS2='>>'
-PATH=~/bin:$PATH
-
-#temporarily while active in subu code development
-export PROJECT_SUBU=~/subu
-PATH="$PROJECT_SUBU"/tool/bin:$PATH
-
-export PS_FORMAT=user:15,pid,%cpu,%mem,vsz,rss,tty,stat,start,time,command
-
-export EDITOR=emacs
-
-
diff --git a/tool/lib/dot_emacs b/tool/lib/dot_emacs
deleted file mode 100755
index d6d5245..0000000
--- a/tool/lib/dot_emacs
+++ /dev/null
@@ -1,171 +0,0 @@
-;; inspired by dumb 'feature' of gdb where it takes control of an
-;; emacs window, and locks the user out from switching from it
-;; Toggle window dedication
-
- (defun toggle-window-dedicated ()
- "Toggle whether the current active window is dedicated or not"
- (interactive)
- (message
- (if (let (window (get-buffer-window (current-buffer)))
- (set-window-dedicated-p window
- (not (window-dedicated-p window))))
- "Window '%s' is dedicated"
- "Window '%s' is normal")
- (current-buffer)))
-
- (global-set-key (kbd "C-x d") 'toggle-window-dedication)
-
-;; (setq ring-bell-function (lambda ()
-;; (call-process-shell-command
-;; "xset led 3; xset -led 3" nil 0 nil)))
-;;
-;; (setq ring-bell-function nil)
-
- (setq ring-bell-function
- (lambda ()
- (call-process-shell-command "xset led named 'Scroll Lock'")
- (call-process-shell-command "xset -led named 'Scroll Lock'")))
-
-
-;; preferable to have keys for the characters, but the keyboard is already overloaded ..
-;; (define-key key-translation-map (kbd " p") (kbd "¬"))
-;; (set-input-method âlatin-9-prefix)
-
- (global-set-key [f1] 'help-command)
- (global-set-key "\C-h" 'nil)
- (define-key key-translation-map (kbd "M-S") (kbd "§"))
-
- (global-set-key (kbd "C-x g phi SPC") [?Ï]) ; phi for phase
- (global-set-key (kbd "C-x g Phi SPC") [?Φ])
-
- (global-set-key (kbd "C-x g d SPC") [?δ])
- (global-set-key (kbd "C-x g D SPC") [?Î]) ; this is 'delta' is not 'increment'!
- (global-set-key (kbd "C-x g delta SPC") [?δ])
- (global-set-key (kbd "C-x g Delta SPC") [?Î]) ; this is 'delta' is not 'increment'!
-
-
- (global-set-key (kbd "C-x g g SPC") [?γ])
- (global-set-key (kbd "C-x g G SPC") [?Î])
- (global-set-key (kbd "C-x g gamma SPC") [?γ])
- (global-set-key (kbd "C-x g Gamma SPC") [?Î])
-
- (global-set-key (kbd "C-x g l SPC") [?λ])
- (global-set-key (kbd "C-x g L SPC") [?Î])
- (global-set-key (kbd "C-x g lambda SPC") [?λ])
- (global-set-key (kbd "C-x g Lambda SPC") [?Î])
-
- (global-set-key (kbd "C-x g p SPC") [?Ï])
- (global-set-key (kbd "C-x g P SPC") [?Î ])
- (global-set-key (kbd "C-x g pi SPC") [?Ï])
- (global-set-key (kbd "C-x g Pi SPC") [?Î ])
-
- (global-set-key (kbd "C-x g > = SPC") [?â¥])
- (global-set-key (kbd "C-x g < = SPC") [?â¤])
- (global-set-key (kbd "C-x g ! = SPC") [?â ])
- (global-set-key (kbd "C-x g neq SPC") [?â ])
-
- (global-set-key (kbd "C-x g nil SPC") [?â ])
-
- (global-set-key (kbd "C-x g not SPC") [?¬])
-
- (global-set-key (kbd "C-x g and SPC") [?â§])
- (global-set-key (kbd "C-x g or SPC") [?â¨])
-
- (global-set-key (kbd "C-x g exists SPC") [?â])
- (global-set-key (kbd "C-x g all SPC") [?â])
-
- (global-set-key (kbd "C-x g do SPC") [?â³]) ; do
- (global-set-key (kbd "C-x g rb SPC") [?â¨])
- (global-set-key (kbd "C-x g lb SPC") [?â§])
-
- (global-set-key (kbd "C-x g cont SPC") [?â]) ; continue
- (global-set-key (kbd "C-x g thread SPC") [?â¥]) ; thread
-
- (global-set-key (kbd "C-x g in SPC") [?â]) ; set membership
-
-
-
-;; lisp
-;;
- (setq lisp-indent-offset 2)
- (setq inferior-lisp-program "sbcl")
-
- (modify-syntax-entry ?[ "(]" lisp-mode-syntax-table)
- (modify-syntax-entry ?] ")[" lisp-mode-syntax-table)
- (modify-syntax-entry ?{ "(}" lisp-mode-syntax-table)
- (modify-syntax-entry ?} "){" lisp-mode-syntax-table)
-
-;; get the pwd in shell mode from the prompt rather than guessing by
-;; watching the commands typed .. yes! now shell variables and source
-;; scripts will work
-;; in bashrc: export PS1='\n$(/usr/local/bin/Z)\u@\h§\w§\n> '
-;;
- (add-hook 'shell-mode-hook
- (lambda ()
- (shell-dirtrack-mode -1)
- (dirtrack-mode 1)))
-
- (add-hook 'dirtrack-directory-change-hook
- (lambda ()
- (message default-directory)))
-
- (setq dirtrack-list '("§\\(.*\\)§\n> " 1))
-
-;; use a backrevs dir rather than leaving ~file droppings everywhere
-;;
- (setq backup-directory-alist `(("." . "~/emacs_backrevs")))
- (setq backup-by-copying t)
-
-;; stop the 'tab' character polution
-;;
- (setq-default indent-tabs-mode nil)
-
-;; turn off the poison C-z key. Use C-x C-z or the command suspend-emacs
-;;
- (global-set-key (kbd "C-z") nil)
-
-;; truncate rather than wrapping lines (use horizontal scroll to see to the right)
-;;
- (set-default 'truncate-lines t)
- (setq truncate-partial-width-windows nil)
- (setq-default fill-column 80)
-
-;; recover some window real estate
-;; c-x mode-line to toggle the mode-line on and off
-;;
- (defun mode-line () "toggles the modeline on and off"
- (interactive)
- (setq mode-line-format
- (if (equal mode-line-format nil)
- (default-value 'mode-line-format)) )
- (redraw-display))
-
- (tool-bar-mode -1)
- (menu-bar-mode -1)
-
-
-(put 'upcase-region 'disabled nil)
-(put 'narrow-to-region 'disabled nil)
-(put 'downcase-region 'disabled nil)
-(put 'set-goal-column 'disabled nil)
-
-
-(custom-set-variables
- ;; custom-set-variables was added by Custom.
- ;; If you edit it by hand, you could mess it up, so be careful.
- ;; Your init file should contain only one such instance.
- ;; If there is more than one, they won't work right.
- '(ansi-color-names-vector
- ["#212526" "#ff4b4b" "#b4fa70" "#fce94f" "#729fcf" "#e090d7" "#8cc4ff" "#eeeeec"])
- '(custom-enabled-themes (quote (wheatgrass)))
- '(geiser-racket-binary "racket")
- '(send-mail-function (quote smtpmail-send-it))
- '(tool-bar-mode nil))
-(custom-set-faces
- ;; custom-set-faces was added by Custom.
- ;; If you edit it by hand, you could mess it up, so be careful.
- ;; Your init file should contain only one such instance.
- ;; If there is more than one, they won't work right.
- '(default ((t (:family "DejaVu Sans Mono" :foundry "PfEd" :slant normal :weight bold :height 98 :width normal)))))
-
-(put 'erase-buffer 'disabled nil)
diff --git a/tool/lib/makefile-cc b/tool/lib/makefile-cc
deleted file mode 100755
index 687f720..0000000
--- a/tool/lib/makefile-cc
+++ /dev/null
@@ -1,188 +0,0 @@
-
-# This makefile is usually called through a local makefile rather than directly.
-
-# should add test that incdir is not pwd before deleting the include
-# file. Currently it is working for us despite this problem because dist-clean is
-# looking for $(module).h while the include file is always $(module).lib.h.
-
-SHELL=/bin/bash
-
-#--------------------------------------------------------------------------------
-# defaults
-
-# these are the sources edited by the programmer
-C_SOURCE_LIB= $(wildcard $(SRCDIR)/*.lib.c)
-C_SOURCE_CLI= $(wildcard $(SRCDIR)/*.cli.c)
-CC_SOURCE_LIB= $(wildcard $(SRCDIR)/*.lib.cc)
-CC_SOURCE_CLI= $(wildcard $(SRCDIR)/*.cli.cc)
-
-#remove the suffix to get base name
-C_BASE_LIB= $(sort $(patsubst %.lib.c, %, $(notdir $(C_SOURCE_LIB))))
-C_BASE_CLI= $(sort $(patsubst %.cli.c, %, $(notdir $(C_SOURCE_CLI))))
-CC_BASE_LIB= $(sort $(patsubst %.lib.cc, %, $(notdir $(CC_SOURCE_LIB))))
-CC_BASE_CLI= $(sort $(patsubst %.cli.cc, %, $(notdir $(CC_SOURCE_CLI))))
-
-# two sets of object files, one for the lib, and one for the command line interface progs
-OBJECT_LIB= $(patsubst %, $(TMPDIR)/%.lib.o, $(C_BASE_LIB) $(CC_BASE_LIB))
-OBJECT_CLI= $(patsubst %, $(TMPDIR)/%.cli.o, $(C_BASE_CLI) $(CC_BASE_CLI))
-
-# executables are made from CLI sources
-EXEC= $(patsubst %, $(EXECDIR)/%, $(C_BASE_CLI) $(CC_BASE_CLI))
-
-# default directory seteup
-#
-DEPRDIR=deprecated
-DOCDIR=doc
-EXECDIR=exec
-INCDIR=include
-LIBDIR=lib
-SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
-SRCDIR=src
-TESTDIR=test
-TMPDIR=tmp
-TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
-TRYDIR=try
-
-DEPFILE=$(TMPDIR)/makefile-cc.deps
-LIBFILE=$(LIBDIR)/lib$(MODULE).a
-INCFILE=$(INCDIR)/$(MODULE).h
-
-# a single space literal, for example if you wanted to subsitute commas to
-# spaces: $(subst $(space),;,$(string))
-blank :=
-space :=$(blank) $(blank)
-
-# prevent make from subsittuing its default for CC
-C=
-CC=
-
-#--------------------------------------------------------------------------------
-# local customization
-# user must define things needed by the local makefile, the compiler, and flags
-
-include makefile-flags
--include $(DEPFILE)
-
-#--------------------------------------------------------------------------------
-# targets
-
-.PHONY: all
-all: version
-
-.PHONY: version
-version:
- @echo makefile version 6.0
- gcc -v
- g++ -v
- make -v
-
-.PHONY: info
-info:
- @echo "DEPRDIR: " $(DEPRDIR)
- @echo "DOCDIR: " $(DOCDIR)
- @echo "EXECDIR: " $(EXECDIR)
- @echo "INCDIR: " $(INCDIR)
- @echo "LIBDIR: " $(LIBDIR)
- @echo "TESTDIR: " $(TESTDIR)
- @echo "TMPDIR: " $(TMPDIR)
- @echo "TOOLDIR: " $(TOOLDIR)
- @echo "TRYDIR: " $(TRYDIR)
- @echo "DEPFILE: " $(DEPFILE)
- @echo "LIBFILE: " $(LIBFILE)
- @echo "INCFILE: " $(INCFILE)
- @echo "C_SOURCE_LIB: " $(C_SOURCE_LIB)
- @echo "C_SOURCE_LIB: " $(C_SOURCE_LIB)
- @echo "C_SOURCE_CLI: " $(C_SOURCE_CLI)
- @echo "CC_SOURCE_LIB: " $(CC_SOURCE_LIB)
- @echo "CC_SOURCE_CLI: " $(CC_SOURCE_CLI)
- @echo "C_BASE_LIB: " $(C_BASE_LIB)
- @echo "C_BASE_CLI: " $(C_BASE_CLI)
- @echo "CC_BASE_LIB: " $(CC_BASE_LIB)
- @echo "CC_BASE_CLI: " $(CC_BASE_CLI)
- @echo "OBJECT_LIB: " $(OBJECT_LIB)
- @echo "OBJECT_CLI: " $(OBJECT_CLI)
- @echo "EXEC: " $(EXEC)
-
-# should be safe to run this in an already setup or partially setup directory
-# gee looks like a candidate for a makefile function ..
-.PHONY: setup
-setup:
- [ ! -e $(DEPRDIR) ] && mkdir $(DEPRDIR) || true
- [ ! -e $(DOCDIR) ] && mkdir $(DOCDIR) || true
- [ ! -e $(EXECDIR) ] && mkdir $(EXECDIR) || true
- [ ! -e $(INCDIR) ] && mkdir $(INCDIR) || true
- [ ! -e $(LIBDIR) ] && mkdir $(LIBDIR) || true
- [ ! -e $(SRCDIR) ] && mkdir $(SRCDIR) || true
- [ ! -e $(TESTDIR) ] && mkdir $(TESTDIR) || true
- [ ! -e $(TMPDIR) ] && mkdir $(TMPDIR) || true
- [ ! -e $(TRYDIR) ] && mkdir $(TRYDIR) || true
-
-.PHONY: dep
-dep:
- @if [ -z "$(CC)" ]; then\
- if [ -z "$C()" ]; then\
- $(ECHO) "No compiler specified";\
- exit 1;\
- else\
- echo "C compiler only deps" ;\
- $(C) $(CFLAGS) -MM $(C_SOURCE_LIB) $(C_SOURCE_CLI) | sed 's|^.*\.o|$(TMPDIR)/&|' >> $(DEPFILE);\
- echo "deps for C linking";\
- for i in $(C_BASE_CLI); do\
- $(ECHO) >> $(DEPFILE);\
- $(ECHO) "$(EXECDIR)/$$i : $(TMPDIR)/$$i.cli.o $(LIBFILE)" >> $(DEPFILE);\
- $(ECHO) " $(C) -o $(EXECDIR)/$$i $(TMPDIR)/$$i.cli.o $(LINKFLAGS)" >> $(DEPFILE);\
- done;\
- fi;\
- else\
- $(CC) $(CCFLAGS) -MM $(CC_SOURCE_LIB) $(CC_SOURCE_CLI) | sed 's|^.*\.o|$(TMPDIR)/&|' >> $(DEPFILE);\
- if [ -z "$C()" ]; then\
- echo "CC compiler only deps" ;\
- else\
- echo "CC and C mixed compile deps" ;\
- $(C) $(CFLAGS) -MM $(C_SOURCE_LIB) $(C_SOURCE_CLI) | sed 's|^.*\.o|$(TMPDIR)/&|' >> $(DEPFILE);\
- fi;\
- echo "deps for CC linking";\
- for i in $(CC_BASE_CLI) $(C_BASE_CLI) ; do\
- $(ECHO) >> $(DEPFILE);\
- $(ECHO) "$(EXECDIR)/$$i : $(TMPDIR)/$$i.cli.o $(LIBFILE)" >> $(DEPFILE);\
- $(ECHO) " $(CC) -o $(EXECDIR)/$$i $(TMPDIR)/$$i.cli.o $(LINKFLAGS)" >> $(DEPFILE);\
- done;\
- fi
-
-.PHONY: lib
-lib: $(LIBFILE)
-
-$(LIBFILE): $(OBJECT_LIB)
- ar rcs $(LIBFILE) $(OBJECT_LIB)
-
-.PHONY: exec
-exec: $(LIBFILE)
- make sub_exec
-
-.PHONY: sub_exec
-sub_exec: $(EXEC)
-
-.PHONY: share
-share:
- if [ ! -z "$(wildcard $(LIBDIR)/*)" ]; then cp $(LIBDIR)/* $(SHAREDIR)/lib; fi
- if [ ! -z "$(wildcard $(INCDIR)/*)" ]; then cp $(INCDIR)/* $(SHAREDIR)/include; fi
- if [ ! -z "$(wildcard $(EXECDIR)/*)" ]; then cp $(EXECDIR)/* $(SHAREDIR)/bin; fi
-
-.PHONY: clean
-clean:
- for i in $(wildcard tmp/*); do rm $$i || true; done
-
-.PHONY: dist-clean
-dist-clean: clean
- for i in $(EXEC); do [ -e $$i ] && rm $$i || true; done
- rm $(INCFILE) || true
- rm $(LIBFILE) || true
-
-# recipes
- $(TMPDIR)/%.o : $(SRCDIR)/%.c
- $(C) $(CFLAGS) -o $@ -c $<
-
- $(TMPDIR)/%.o : $(SRCDIR)/%.cc
- $(CC) $(CCFLAGS) -o $@ -c $<
-
-
diff --git a/tool/src/makeheaders.c b/tool/src/makeheaders.c
deleted file mode 100644
index b58e787..0000000
--- a/tool/src/makeheaders.c
+++ /dev/null
@@ -1,3739 +0,0 @@
-
-
-
-
-
-
-Fossil: File Content
-
-
-
-
-
File
-src/makeheaders.c
-— part of check-in
-[8cecc544]
-at
-2018-11-02 15:21:54
-on branch trunk
-— Enhance makeheaders so that it is able to deal with static_assert() statements.
-(These do not come up in Fossil itself. This check-in is in response to use
-of Makeheaders by external projects.)
- (user:
-drh
-size: 100011)
-[more...]
-
-
-
-
-/*
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the Simplified BSD License (also
-** known as the "2-Clause License" or "FreeBSD License".)
-**
-** Copyright 1993 D. Richard Hipp. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or
-** without modification, are permitted provided that the following
-** conditions are met:
-**
-** 1. Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-**
-** 2. Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-**
-** This software is provided "as is" and any express or implied warranties,
-** including, but not limited to, the implied warranties of merchantability
-** and fitness for a particular purpose are disclaimed. In no event shall
-** the author or contributors be liable for any direct, indirect, incidental,
-** special, exemplary, or consequential damages (including, but not limited
-** to, procurement of substitute goods or services; loss of use, data or
-** profits; or business interruption) however caused and on any theory of
-** liability, whether in contract, strict liability, or tort (including
-** negligence or otherwise) arising in any way out of the use of this
-** software, even if advised of the possibility of such damage.
-**
-** This program is distributed in the hope that it will be useful,
-** but without any warranty; without even the implied warranty of
-** merchantability or fitness for a particular purpose.
-** appropriate header files.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <memory.h>
-#include <sys/stat.h>
-#include <assert.h>
-#include <string.h>
-
-#if defined( __MINGW32__) || defined(__DMC__) || defined(_MSC_VER) || defined(__POCC__)
-# ifndef WIN32
-# define WIN32
-# endif
-#else
-# include <unistd.h>
-#endif
-
-/*
-** Macros for debugging.
-*/
-#ifdef DEBUG
-static int debugMask = 0;
-# define debug0(F,M) if( (F)&debugMask ){ fprintf(stderr,M); }
-# define debug1(F,M,A) if( (F)&debugMask ){ fprintf(stderr,M,A); }
-# define debug2(F,M,A,B) if( (F)&debugMask ){ fprintf(stderr,M,A,B); }
-# define debug3(F,M,A,B,C) if( (F)&debugMask ){ fprintf(stderr,M,A,B,C); }
-# define PARSER 0x00000001
-# define DECL_DUMP 0x00000002
-# define TOKENIZER 0x00000004
-#else
-# define debug0(Flags, Format)
-# define debug1(Flags, Format, A)
-# define debug2(Flags, Format, A, B)
-# define debug3(Flags, Format, A, B, C)
-#endif
-
-/*
-** The following macros are purely for the purpose of testing this
-** program on itself. They don't really contribute to the code.
-*/
-#define INTERFACE 1
-#define EXPORT_INTERFACE 1
-#define EXPORT
-
-/*
-** Each token in a source file is represented by an instance of
-** the following structure. Tokens are collected onto a list.
-*/
-typedef struct Token Token;
-struct Token {
- const char *zText; /* The text of the token */
- int nText; /* Number of characters in the token's text */
- int eType; /* The type of this token */
- int nLine; /* The line number on which the token starts */
- Token *pComment; /* Most recent block comment before this token */
- Token *pNext; /* Next token on the list */
- Token *pPrev; /* Previous token on the list */
-};
-
-/*
-** During tokenization, information about the state of the input
-** stream is held in an instance of the following structure
-*/
-typedef struct InStream InStream;
-struct InStream {
- const char *z; /* Complete text of the input */
- int i; /* Next character to read from the input */
- int nLine; /* The line number for character z[i] */
-};
-
-/*
-** Each declaration in the C or C++ source files is parsed out and stored as
-** an instance of the following structure.
-**
-** A "forward declaration" is a declaration that an object exists that
-** doesn't tell about the objects structure. A typical forward declaration
-** is:
-**
-** struct Xyzzy;
-**
-** Not every object has a forward declaration. If it does, thought, the
-** forward declaration will be contained in the zFwd field for C and
-** the zFwdCpp for C++. The zDecl field contains the complete
-** declaration text.
-*/
-typedef struct Decl Decl;
-struct Decl {
- char *zName; /* Name of the object being declared. The appearance
- ** of this name is a source file triggers the declaration
- ** to be added to the header for that file. */
- const char *zFile; /* File from which extracted. */
- char *zIf; /* Surround the declaration with this #if */
- char *zFwd; /* A forward declaration. NULL if there is none. */
- char *zFwdCpp; /* Use this forward declaration for C++. */
- char *zDecl; /* A full declaration of this object */
- char *zExtra; /* Extra declaration text inserted into class objects */
- int extraType; /* Last public:, protected: or private: in zExtraDecl */
- struct Include *pInclude; /* #includes that come before this declaration */
- int flags; /* See the "Properties" below */
- Token *pComment; /* A block comment associated with this declaration */
- Token tokenCode; /* Implementation of functions and procedures */
- Decl *pSameName; /* Next declaration with the same "zName" */
- Decl *pSameHash; /* Next declaration with same hash but different zName */
- Decl *pNext; /* Next declaration with a different name */
-};
-
-/*
-** Properties associated with declarations.
-**
-** DP_Forward and DP_Declared are used during the generation of a single
-** header file in order to prevent duplicate declarations and definitions.
-** DP_Forward is set after the object has been given a forward declaration
-** and DP_Declared is set after the object gets a full declarations.
-** (Example: A forward declaration is "typedef struct Abc Abc;" and the
-** full declaration is "struct Abc { int a; float b; };".)
-**
-** The DP_Export and DP_Local flags are more permanent. They mark objects
-** that have EXPORT scope and LOCAL scope respectively. If both of these
-** marks are missing, then the object has library scope. The meanings of
-** the scopes are as follows:
-**
-** LOCAL scope The object is only usable within the file in
-** which it is declared.
-**
-** library scope The object is visible and usable within other
-** files in the same project. By if the project is
-** a library, then the object is not visible to users
-** of the library. (i.e. the object does not appear
-** in the output when using the -H option.)
-**
-** EXPORT scope The object is visible and usable everywhere.
-**
-** The DP_Flag is a temporary use flag that is used during processing to
-** prevent an infinite loop. It's use is localized.
-**
-** The DP_Cplusplus, DP_ExternCReqd and DP_ExternReqd flags are permanent
-** and are used to specify what type of declaration the object requires.
-*/
-#define DP_Forward 0x001 /* Has a forward declaration in this file */
-#define DP_Declared 0x002 /* Has a full declaration in this file */
-#define DP_Export 0x004 /* Export this declaration */
-#define DP_Local 0x008 /* Declare in its home file only */
-#define DP_Flag 0x010 /* Use to mark a subset of a Decl list
- ** for special processing */
-#define DP_Cplusplus 0x020 /* Has C++ linkage and cannot appear in a
- ** C header file */
-#define DP_ExternCReqd 0x040 /* Prepend 'extern "C"' in a C++ header.
- ** Prepend nothing in a C header */
-#define DP_ExternReqd 0x080 /* Prepend 'extern "C"' in a C++ header if
- ** DP_Cplusplus is not also set. If DP_Cplusplus
- ** is set or this is a C header then
- ** prepend 'extern' */
-
-/*
-** Convenience macros for dealing with declaration properties
-*/
-#define DeclHasProperty(D,P) (((D)->flags&(P))==(P))
-#define DeclHasAnyProperty(D,P) (((D)->flags&(P))!=0)
-#define DeclSetProperty(D,P) (D)->flags |= (P)
-#define DeclClearProperty(D,P) (D)->flags &= ~(P)
-
-/*
-** These are state properties of the parser. Each of the values is
-** distinct from the DP_ values above so that both can be used in
-** the same "flags" field.
-**
-** Be careful not to confuse PS_Export with DP_Export or
-** PS_Local with DP_Local. Their names are similar, but the meanings
-** of these flags are very different.
-*/
-#define PS_Extern 0x000800 /* "extern" has been seen */
-#define PS_Export 0x001000 /* If between "#if EXPORT_INTERFACE"
- ** and "#endif" */
-#define PS_Export2 0x002000 /* If "EXPORT" seen */
-#define PS_Typedef 0x004000 /* If "typedef" has been seen */
-#define PS_Static 0x008000 /* If "static" has been seen */
-#define PS_Interface 0x010000 /* If within #if INTERFACE..#endif */
-#define PS_Method 0x020000 /* If "::" token has been seen */
-#define PS_Local 0x040000 /* If within #if LOCAL_INTERFACE..#endif */
-#define PS_Local2 0x080000 /* If "LOCAL" seen. */
-#define PS_Public 0x100000 /* If "PUBLIC" seen. */
-#define PS_Protected 0x200000 /* If "PROTECTED" seen. */
-#define PS_Private 0x400000 /* If "PRIVATE" seen. */
-#define PS_PPP 0x700000 /* If any of PUBLIC, PRIVATE, PROTECTED */
-
-/*
-** The following set of flags are ORed into the "flags" field of
-** a Decl in order to identify what type of object is being
-** declared.
-*/
-#define TY_Class 0x00100000
-#define TY_Subroutine 0x00200000
-#define TY_Macro 0x00400000
-#define TY_Typedef 0x00800000
-#define TY_Variable 0x01000000
-#define TY_Structure 0x02000000
-#define TY_Union 0x04000000
-#define TY_Enumeration 0x08000000
-#define TY_Defunct 0x10000000 /* Used to erase a declaration */
-
-/*
-** Each nested #if (or #ifdef or #ifndef) is stored in a stack of
-** instances of the following structure.
-*/
-typedef struct Ifmacro Ifmacro;
-struct Ifmacro {
- int nLine; /* Line number where this macro occurs */
- char *zCondition; /* Text of the condition for this macro */
- Ifmacro *pNext; /* Next down in the stack */
- int flags; /* Can hold PS_Export, PS_Interface or PS_Local flags */
-};
-
-/*
-** When parsing a file, we need to keep track of what other files have
-** be #include-ed. For each #include found, we create an instance of
-** the following structure.
-*/
-typedef struct Include Include;
-struct Include {
- char *zFile; /* The name of file include. Includes "" or <> */
- char *zIf; /* If not NULL, #include should be enclosed in #if */
- char *zLabel; /* A unique label used to test if this #include has
- * appeared already in a file or not */
- Include *pNext; /* Previous include file, or NULL if this is the first */
-};
-
-/*
-** Identifiers found in a source file that might be used later to provoke
-** the copying of a declaration into the corresponding header file are
-** stored in a hash table as instances of the following structure.
-*/
-typedef struct Ident Ident;
-struct Ident {
- char *zName; /* The text of this identifier */
- Ident *pCollide; /* Next identifier with the same hash */
- Ident *pNext; /* Next identifier in a list of them all */
-};
-
-/*
-** A complete table of identifiers is stored in an instance of
-** the next structure.
-*/
-#define IDENT_HASH_SIZE 2237
-typedef struct IdentTable IdentTable;
-struct IdentTable {
- Ident *pList; /* List of all identifiers in this table */
- Ident *apTable[IDENT_HASH_SIZE]; /* The hash table */
-};
-
-/*
-** The following structure holds all information for a single
-** source file named on the command line of this program.
-*/
-typedef struct InFile InFile;
-struct InFile {
- char *zSrc; /* Name of input file */
- char *zHdr; /* Name of the generated .h file for this input.
- ** Will be NULL if input is to be scanned only */
- int flags; /* One or more DP_, PS_ and/or TY_ flags */
- InFile *pNext; /* Next input file in the list of them all */
- IdentTable idTable; /* All identifiers in this input file */
-};
-
-/*
-** An unbounded string is able to grow without limit. We use these
-** to construct large in-memory strings from lots of smaller components.
-*/
-typedef struct String String;
-struct String {
- int nAlloc; /* Number of bytes allocated */
- int nUsed; /* Number of bytes used (not counting null terminator) */
- char *zText; /* Text of the string */
-};
-
-/*
-** The following structure contains a lot of state information used
-** while generating a .h file. We put the information in this structure
-** and pass around a pointer to this structure, rather than pass around
-** all of the information separately. This helps reduce the number of
-** arguments to generator functions.
-*/
-typedef struct GenState GenState;
-struct GenState {
- String *pStr; /* Write output to this string */
- IdentTable *pTable; /* A table holding the zLabel of every #include that
- * has already been generated. Used to avoid
- * generating duplicate #includes. */
- const char *zIf; /* If not NULL, then we are within a #if with
- * this argument. */
- int nErr; /* Number of errors */
- const char *zFilename; /* Name of the source file being scanned */
- int flags; /* Various flags (DP_ and PS_ flags above) */
-};
-
-/*
-** The following text line appears at the top of every file generated
-** by this program. By recognizing this line, the program can be sure
-** never to read a file that it generated itself.
-**
-** The "#undef INTERFACE" part is a hack to work around a name collision
-** in MSVC 2008.
-*/
-const char zTopLine[] =
- "/* \aThis file was automatically generated. Do not edit! */\n"
- "#undef INTERFACE\n";
-#define nTopLine (sizeof(zTopLine)-1)
-
-/*
-** The name of the file currently being parsed.
-*/
-static const char *zFilename;
-
-/*
-** The stack of #if macros for the file currently being parsed.
-*/
-static Ifmacro *ifStack = 0;
-
-/*
-** A list of all files that have been #included so far in a file being
-** parsed.
-*/
-static Include *includeList = 0;
-
-/*
-** The last block comment seen.
-*/
-static Token *blockComment = 0;
-
-/*
-** The following flag is set if the -doc flag appears on the
-** command line.
-*/
-static int doc_flag = 0;
-
-/*
-** If the following flag is set, then makeheaders will attempt to
-** generate prototypes for static functions and procedures.
-*/
-static int proto_static = 0;
-
-/*
-** A list of all declarations. The list is held together using the
-** pNext field of the Decl structure.
-*/
-static Decl *pDeclFirst; /* First on the list */
-static Decl *pDeclLast; /* Last on the list */
-
-/*
-** A hash table of all declarations
-*/
-#define DECL_HASH_SIZE 3371
-static Decl *apTable[DECL_HASH_SIZE];
-
-/*
-** The TEST macro must be defined to something. Make sure this is the
-** case.
-*/
-#ifndef TEST
-# define TEST 0
-#endif
-
-#ifdef NOT_USED
-/*
-** We do our own assertion macro so that we can have more control
-** over debugging.
-*/
-#define Assert(X) if(!(X)){ CantHappen(__LINE__); }
-#define CANT_HAPPEN CantHappen(__LINE__)
-static void CantHappen(int iLine){
- fprintf(stderr,"Assertion failed on line %d\n",iLine);
- *(char*)1 = 0; /* Force a core-dump */
-}
-#endif
-
-/*
-** Memory allocation functions that are guaranteed never to return NULL.
-*/
-static void *SafeMalloc(int nByte){
- void *p = malloc( nByte );
- if( p==0 ){
- fprintf(stderr,"Out of memory. Can't allocate %d bytes.\n",nByte);
- exit(1);
- }
- return p;
-}
-static void SafeFree(void *pOld){
- if( pOld ){
- free(pOld);
- }
-}
-static void *SafeRealloc(void *pOld, int nByte){
- void *p;
- if( pOld==0 ){
- p = SafeMalloc(nByte);
- }else{
- p = realloc(pOld, nByte);
- if( p==0 ){
- fprintf(stderr,
- "Out of memory. Can't enlarge an allocation to %d bytes\n",nByte);
- exit(1);
- }
- }
- return p;
-}
-static char *StrDup(const char *zSrc, int nByte){
- char *zDest;
- if( nByte<=0 ){
- nByte = strlen(zSrc);
- }
- zDest = SafeMalloc( nByte + 1 );
- strncpy(zDest,zSrc,nByte);
- zDest[nByte] = 0;
- return zDest;
-}
-
-/*
-** Return TRUE if the character X can be part of an identifier
-*/
-#define ISALNUM(X) ((X)=='_' || isalnum(X))
-
-/*
-** Routines for dealing with unbounded strings.
-*/
-static void StringInit(String *pStr){
- pStr->nAlloc = 0;
- pStr->nUsed = 0;
- pStr->zText = 0;
-}
-static void StringReset(String *pStr){
- SafeFree(pStr->zText);
- StringInit(pStr);
-}
-static void StringAppend(String *pStr, const char *zText, int nByte){
- if( nByte<=0 ){
- nByte = strlen(zText);
- }
- if( pStr->nUsed + nByte >= pStr->nAlloc ){
- if( pStr->nAlloc==0 ){
- pStr->nAlloc = nByte + 100;
- pStr->zText = SafeMalloc( pStr->nAlloc );
- }else{
- pStr->nAlloc = pStr->nAlloc*2 + nByte;
- pStr->zText = SafeRealloc(pStr->zText, pStr->nAlloc);
- }
- }
- strncpy(&pStr->zText[pStr->nUsed],zText,nByte);
- pStr->nUsed += nByte;
- pStr->zText[pStr->nUsed] = 0;
-}
-#define StringGet(S) ((S)->zText?(S)->zText:"")
-
-/*
-** Compute a hash on a string. The number returned is a non-negative
-** value between 0 and 2**31 - 1
-*/
-static int Hash(const char *z, int n){
- int h = 0;
- if( n<=0 ){
- n = strlen(z);
- }
- while( n-- ){
- h = h ^ (h<<5) ^ *z++;
- }
- return h & 0x7fffffff;
-}
-
-/*
-** Given an identifier name, try to find a declaration for that
-** identifier in the hash table. If found, return a pointer to
-** the Decl structure. If not found, return 0.
-*/
-static Decl *FindDecl(const char *zName, int len){
- int h;
- Decl *p;
-
- if( len<=0 ){
- len = strlen(zName);
- }
- h = Hash(zName,len) % DECL_HASH_SIZE;
- p = apTable[h];
- while( p && (strncmp(p->zName,zName,len)!=0 || p->zName[len]!=0) ){
- p = p->pSameHash;
- }
- return p;
-}
-
-/*
-** Install the given declaration both in the hash table and on
-** the list of all declarations.
-*/
-static void InstallDecl(Decl *pDecl){
- int h;
- Decl *pOther;
-
- h = Hash(pDecl->zName,0) % DECL_HASH_SIZE;
- pOther = apTable[h];
- while( pOther && strcmp(pDecl->zName,pOther->zName)!=0 ){
- pOther = pOther->pSameHash;
- }
- if( pOther ){
- pDecl->pSameName = pOther->pSameName;
- pOther->pSameName = pDecl;
- }else{
- pDecl->pSameName = 0;
- pDecl->pSameHash = apTable[h];
- apTable[h] = pDecl;
- }
- pDecl->pNext = 0;
- if( pDeclFirst==0 ){
- pDeclFirst = pDeclLast = pDecl;
- }else{
- pDeclLast->pNext = pDecl;
- pDeclLast = pDecl;
- }
-}
-
-/*
-** Look at the current ifStack. If anything declared at the current
-** position must be surrounded with
-**
-** #if STUFF
-** #endif
-**
-** Then this routine computes STUFF and returns a pointer to it. Memory
-** to hold the value returned is obtained from malloc().
-*/
-static char *GetIfString(void){
- Ifmacro *pIf;
- char *zResult = 0;
- int hasIf = 0;
- String str;
-
- for(pIf = ifStack; pIf; pIf=pIf->pNext){
- if( pIf->zCondition==0 || *pIf->zCondition==0 ) continue;
- if( !hasIf ){
- hasIf = 1;
- StringInit(&str);
- }else{
- StringAppend(&str," && ",4);
- }
- StringAppend(&str,pIf->zCondition,0);
- }
- if( hasIf ){
- zResult = StrDup(StringGet(&str),0);
- StringReset(&str);
- }else{
- zResult = 0;
- }
- return zResult;
-}
-
-/*
-** Create a new declaration and put it in the hash table. Also
-** return a pointer to it so that we can fill in the zFwd and zDecl
-** fields, and so forth.
-*/
-static Decl *CreateDecl(
- const char *zName, /* Name of the object being declared. */
- int nName /* Length of the name */
-){
- Decl *pDecl;
-
- pDecl = SafeMalloc( sizeof(Decl) + nName + 1);
- memset(pDecl,0,sizeof(Decl));
- pDecl->zName = (char*)&pDecl[1];
- sprintf(pDecl->zName,"%.*s",nName,zName);
- pDecl->zFile = zFilename;
- pDecl->pInclude = includeList;
- pDecl->zIf = GetIfString();
- InstallDecl(pDecl);
- return pDecl;
-}
-
-/*
-** Insert a new identifier into an table of identifiers. Return TRUE if
-** a new identifier was inserted and return FALSE if the identifier was
-** already in the table.
-*/
-static int IdentTableInsert(
- IdentTable *pTable, /* The table into which we will insert */
- const char *zId, /* Name of the identifiers */
- int nId /* Length of the identifier name */
-){
- int h;
- Ident *pId;
-
- if( nId<=0 ){
- nId = strlen(zId);
- }
- h = Hash(zId,nId) % IDENT_HASH_SIZE;
- for(pId = pTable->apTable[h]; pId; pId=pId->pCollide){
- if( strncmp(zId,pId->zName,nId)==0 && pId->zName[nId]==0 ){
- /* printf("Already in table: %.*s\n",nId,zId); */
- return 0;
- }
- }
- pId = SafeMalloc( sizeof(Ident) + nId + 1 );
- pId->zName = (char*)&pId[1];
- sprintf(pId->zName,"%.*s",nId,zId);
- pId->pNext = pTable->pList;
- pTable->pList = pId;
- pId->pCollide = pTable->apTable[h];
- pTable->apTable[h] = pId;
- /* printf("Add to table: %.*s\n",nId,zId); */
- return 1;
-}
-
-/*
-** Check to see if the given value is in the given IdentTable. Return
-** true if it is and false if it is not.
-*/
-static int IdentTableTest(
- IdentTable *pTable, /* The table in which to search */
- const char *zId, /* Name of the identifiers */
- int nId /* Length of the identifier name */
-){
- int h;
- Ident *pId;
-
- if( nId<=0 ){
- nId = strlen(zId);
- }
- h = Hash(zId,nId) % IDENT_HASH_SIZE;
- for(pId = pTable->apTable[h]; pId; pId=pId->pCollide){
- if( strncmp(zId,pId->zName,nId)==0 && pId->zName[nId]==0 ){
- return 1;
- }
- }
- return 0;
-}
-
-/*
-** Remove every identifier from the given table. Reset the table to
-** its initial state.
-*/
-static void IdentTableReset(IdentTable *pTable){
- Ident *pId, *pNext;
-
- for(pId = pTable->pList; pId; pId = pNext){
- pNext = pId->pNext;
- SafeFree(pId);
- }
- memset(pTable,0,sizeof(IdentTable));
-}
-
-#ifdef DEBUG
-/*
-** Print the name of every identifier in the given table, one per line
-*/
-static void IdentTablePrint(IdentTable *pTable, FILE *pOut){
- Ident *pId;
-
- for(pId = pTable->pList; pId; pId = pId->pNext){
- fprintf(pOut,"%s\n",pId->zName);
- }
-}
-#endif
-
-/*
-** Read an entire file into memory. Return a pointer to the memory.
-**
-** The memory is obtained from SafeMalloc and must be freed by the
-** calling function.
-**
-** If the read fails for any reason, 0 is returned.
-*/
-static char *ReadFile(const char *zFilename){
- struct stat sStat;
- FILE *pIn;
- char *zBuf;
- int n;
-
- if( stat(zFilename,&sStat)!=0
-#ifndef WIN32
- || !S_ISREG(sStat.st_mode)
-#endif
- ){
- return 0;
- }
- pIn = fopen(zFilename,"r");
- if( pIn==0 ){
- return 0;
- }
- zBuf = SafeMalloc( sStat.st_size + 1 );
- n = fread(zBuf,1,sStat.st_size,pIn);
- zBuf[n] = 0;
- fclose(pIn);
- return zBuf;
-}
-
-/*
-** Write the contents of a string into a file. Return the number of
-** errors
-*/
-static int WriteFile(const char *zFilename, const char *zOutput){
- FILE *pOut;
- pOut = fopen(zFilename,"w");
- if( pOut==0 ){
- return 1;
- }
- fwrite(zOutput,1,strlen(zOutput),pOut);
- fclose(pOut);
- return 0;
-}
-
-/*
-** Major token types
-*/
-#define TT_Space 1 /* Contiguous white space */
-#define TT_Id 2 /* An identifier */
-#define TT_Preprocessor 3 /* Any C preprocessor directive */
-#define TT_Comment 4 /* Either C or C++ style comment */
-#define TT_Number 5 /* Any numeric constant */
-#define TT_String 6 /* String or character constants. ".." or '.' */
-#define TT_Braces 7 /* All text between { and a matching } */
-#define TT_EOF 8 /* End of file */
-#define TT_Error 9 /* An error condition */
-#define TT_BlockComment 10 /* A C-Style comment at the left margin that
- * spans multiple lines */
-#define TT_Other 0 /* None of the above */
-
-/*
-** Get a single low-level token from the input file. Update the
-** file pointer so that it points to the first character beyond the
-** token.
-**
-** A "low-level token" is any token except TT_Braces. A TT_Braces token
-** consists of many smaller tokens and is assembled by a routine that
-** calls this one.
-**
-** The function returns the number of errors. An error is an
-** unterminated string or character literal or an unterminated
-** comment.
-**
-** Profiling shows that this routine consumes about half the
-** CPU time on a typical run of makeheaders.
-*/
-static int GetToken(InStream *pIn, Token *pToken){
- int i;
- const char *z;
- int cStart;
- int c;
- int startLine; /* Line on which a structure begins */
- int nlisc = 0; /* True if there is a new-line in a ".." or '..' */
- int nErr = 0; /* Number of errors seen */
-
- z = pIn->z;
- i = pIn->i;
- pToken->nLine = pIn->nLine;
- pToken->zText = &z[i];
- switch( z[i] ){
- case 0:
- pToken->eType = TT_EOF;
- pToken->nText = 0;
- break;
-
- case '#':
- if( i==0 || z[i-1]=='\n' || (i>1 && z[i-1]=='\r' && z[i-2]=='\n')){
- /* We found a preprocessor statement */
- pToken->eType = TT_Preprocessor;
- i++;
- while( z[i]!=0 && z[i]!='\n' ){
- if( z[i]=='\\' ){
- i++;
- if( z[i]=='\n' ) pIn->nLine++;
- }
- i++;
- }
- pToken->nText = i - pIn->i;
- }else{
- /* Just an operator */
- pToken->eType = TT_Other;
- pToken->nText = 1;
- }
- break;
-
- case ' ':
- case '\t':
- case '\r':
- case '\f':
- case '\n':
- while( isspace(z[i]) ){
- if( z[i]=='\n' ) pIn->nLine++;
- i++;
- }
- pToken->eType = TT_Space;
- pToken->nText = i - pIn->i;
- break;
-
- case '\\':
- pToken->nText = 2;
- pToken->eType = TT_Other;
- if( z[i+1]=='\n' ){
- pIn->nLine++;
- pToken->eType = TT_Space;
- }else if( z[i+1]==0 ){
- pToken->nText = 1;
- }
- break;
-
- case '\'':
- case '\"':
- cStart = z[i];
- startLine = pIn->nLine;
- do{
- i++;
- c = z[i];
- if( c=='\n' ){
- if( !nlisc ){
- fprintf(stderr,
- "%s:%d: (warning) Newline in string or character literal.\n",
- zFilename, pIn->nLine);
- nlisc = 1;
- }
- pIn->nLine++;
- }
- if( c=='\\' ){
- i++;
- c = z[i];
- if( c=='\n' ){
- pIn->nLine++;
- }
- }else if( c==cStart ){
- i++;
- c = 0;
- }else if( c==0 ){
- fprintf(stderr, "%s:%d: Unterminated string or character literal.\n",
- zFilename, startLine);
- nErr++;
- }
- }while( c );
- pToken->eType = TT_String;
- pToken->nText = i - pIn->i;
- break;
-
- case '/':
- if( z[i+1]=='/' ){
- /* C++ style comment */
- while( z[i] && z[i]!='\n' ){ i++; }
- pToken->eType = TT_Comment;
- pToken->nText = i - pIn->i;
- }else if( z[i+1]=='*' ){
- /* C style comment */
- int isBlockComment = i==0 || z[i-1]=='\n';
- i += 2;
- startLine = pIn->nLine;
- while( z[i] && (z[i]!='*' || z[i+1]!='/') ){
- if( z[i]=='\n' ){
- pIn->nLine++;
- if( isBlockComment ){
- if( z[i+1]=='*' || z[i+2]=='*' ){
- isBlockComment = 2;
- }else{
- isBlockComment = 0;
- }
- }
- }
- i++;
- }
- if( z[i] ){
- i += 2;
- }else{
- isBlockComment = 0;
- fprintf(stderr,"%s:%d: Unterminated comment\n",
- zFilename, startLine);
- nErr++;
- }
- pToken->eType = isBlockComment==2 ? TT_BlockComment : TT_Comment;
- pToken->nText = i - pIn->i;
- }else{
- /* A divide operator */
- pToken->eType = TT_Other;
- pToken->nText = 1 + (z[i+1]=='+');
- }
- break;
-
- case '0':
- if( z[i+1]=='x' || z[i+1]=='X' ){
- /* A hex constant */
- i += 2;
- while( isxdigit(z[i]) ){ i++; }
- }else{
- /* An octal constant */
- while( isdigit(z[i]) ){ i++; }
- }
- pToken->eType = TT_Number;
- pToken->nText = i - pIn->i;
- break;
-
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- while( isdigit(z[i]) ){ i++; }
- if( (c=z[i])=='.' ){
- i++;
- while( isdigit(z[i]) ){ i++; }
- c = z[i];
- if( c=='e' || c=='E' ){
- i++;
- if( ((c=z[i])=='+' || c=='-') && isdigit(z[i+1]) ){ i++; }
- while( isdigit(z[i]) ){ i++; }
- c = z[i];
- }
- if( c=='f' || c=='F' || c=='l' || c=='L' ){ i++; }
- }else if( c=='e' || c=='E' ){
- i++;
- if( ((c=z[i])=='+' || c=='-') && isdigit(z[i+1]) ){ i++; }
- while( isdigit(z[i]) ){ i++; }
- }else if( c=='L' || c=='l' ){
- i++;
- c = z[i];
- if( c=='u' || c=='U' ){ i++; }
- }else if( c=='u' || c=='U' ){
- i++;
- c = z[i];
- if( c=='l' || c=='L' ){ i++; }
- }
- pToken->eType = TT_Number;
- pToken->nText = i - pIn->i;
- break;
-
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
- case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
- case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
- case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
- case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P':
- case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W':
- case 'X': case 'Y': case 'Z': case '_':
- while( isalnum(z[i]) || z[i]=='_' ){ i++; };
- pToken->eType = TT_Id;
- pToken->nText = i - pIn->i;
- break;
-
- case ':':
- pToken->eType = TT_Other;
- pToken->nText = 1 + (z[i+1]==':');
- break;
-
- case '=':
- case '<':
- case '>':
- case '+':
- case '-':
- case '*':
- case '%':
- case '^':
- case '&':
- case '|':
- pToken->eType = TT_Other;
- pToken->nText = 1 + (z[i+1]=='=');
- break;
-
- default:
- pToken->eType = TT_Other;
- pToken->nText = 1;
- break;
- }
- pIn->i += pToken->nText;
- return nErr;
-}
-
-/*
-** This routine recovers the next token from the input file which is
-** not a space or a comment or any text between an "#if 0" and "#endif".
-**
-** This routine returns the number of errors encountered. An error
-** is an unterminated token or unmatched "#if 0".
-**
-** Profiling shows that this routine uses about a quarter of the
-** CPU time in a typical run.
-*/
-static int GetNonspaceToken(InStream *pIn, Token *pToken){
- int nIf = 0;
- int inZero = 0;
- const char *z;
- int value;
- int startLine;
- int nErr = 0;
-
- startLine = pIn->nLine;
- while( 1 ){
- nErr += GetToken(pIn,pToken);
- /* printf("%04d: Type=%d nIf=%d [%.*s]\n",
- pToken->nLine,pToken->eType,nIf,pToken->nText,
- pToken->eType!=TT_Space ? pToken->zText : "<space>"); */
- pToken->pComment = blockComment;
- switch( pToken->eType ){
- case TT_Comment: /*0123456789 12345678 */
- if( strncmp(pToken->zText, "/*MAKEHEADERS-STOP", 18)==0 ) return nErr;
- break;
-
- case TT_Space:
- break;
-
- case TT_BlockComment:
- if( doc_flag ){
- blockComment = SafeMalloc( sizeof(Token) );
- *blockComment = *pToken;
- }
- break;
-
- case TT_EOF:
- if( nIf ){
- fprintf(stderr,"%s:%d: Unterminated \"#if\"\n",
- zFilename, startLine);
- nErr++;
- }
- return nErr;
-
- case TT_Preprocessor:
- z = &pToken->zText[1];
- while( *z==' ' || *z=='\t' ) z++;
- if( sscanf(z,"if %d",&value)==1 && value==0 ){
- nIf++;
- inZero = 1;
- }else if( inZero ){
- if( strncmp(z,"if",2)==0 ){
- nIf++;
- }else if( strncmp(z,"endif",5)==0 ){
- nIf--;
- if( nIf==0 ) inZero = 0;
- }
- }else{
- return nErr;
- }
- break;
-
- default:
- if( !inZero ){
- return nErr;
- }
- break;
- }
- }
- /* NOT REACHED */
-}
-
-/*
-** This routine looks for identifiers (strings of contiguous alphanumeric
-** characters) within a preprocessor directive and adds every such string
-** found to the given identifier table
-*/
-static void FindIdentifiersInMacro(Token *pToken, IdentTable *pTable){
- Token sToken;
- InStream sIn;
- int go = 1;
-
- sIn.z = pToken->zText;
- sIn.i = 1;
- sIn.nLine = 1;
- while( go && sIn.i < pToken->nText ){
- GetToken(&sIn,&sToken);
- switch( sToken.eType ){
- case TT_Id:
- IdentTableInsert(pTable,sToken.zText,sToken.nText);
- break;
-
- case TT_EOF:
- go = 0;
- break;
-
- default:
- break;
- }
- }
-}
-
-/*
-** This routine gets the next token. Everything contained within
-** {...} is collapsed into a single TT_Braces token. Whitespace is
-** omitted.
-**
-** If pTable is not NULL, then insert every identifier seen into the
-** IdentTable. This includes any identifiers seen inside of {...}.
-**
-** The number of errors encountered is returned. An error is an
-** unterminated token.
-*/
-static int GetBigToken(InStream *pIn, Token *pToken, IdentTable *pTable){
- const char *zStart;
- int iStart;
- int nBrace;
- int c;
- int nLine;
- int nErr;
-
- nErr = GetNonspaceToken(pIn,pToken);
- switch( pToken->eType ){
- case TT_Id:
- if( pTable!=0 ){
- IdentTableInsert(pTable,pToken->zText,pToken->nText);
- }
- return nErr;
-
- case TT_Preprocessor:
- if( pTable!=0 ){
- FindIdentifiersInMacro(pToken,pTable);
- }
- return nErr;
-
- case TT_Other:
- if( pToken->zText[0]=='{' ) break;
- return nErr;
-
- default:
- return nErr;
- }
-
- iStart = pIn->i;
- zStart = pToken->zText;
- nLine = pToken->nLine;
- nBrace = 1;
- while( nBrace ){
- nErr += GetNonspaceToken(pIn,pToken);
- /* printf("%04d: nBrace=%d [%.*s]\n",pToken->nLine,nBrace,
- pToken->nText,pToken->zText); */
- switch( pToken->eType ){
- case TT_EOF:
- fprintf(stderr,"%s:%d: Unterminated \"{\"\n",
- zFilename, nLine);
- nErr++;
- pToken->eType = TT_Error;
- return nErr;
-
- case TT_Id:
- if( pTable ){
- IdentTableInsert(pTable,pToken->zText,pToken->nText);
- }
- break;
-
- case TT_Preprocessor:
- if( pTable!=0 ){
- FindIdentifiersInMacro(pToken,pTable);
- }
- break;
-
- case TT_Other:
- if( (c = pToken->zText[0])=='{' ){
- nBrace++;
- }else if( c=='}' ){
- nBrace--;
- }
- break;
-
- default:
- break;
- }
- }
- pToken->eType = TT_Braces;
- pToken->nText = 1 + pIn->i - iStart;
- pToken->zText = zStart;
- pToken->nLine = nLine;
- return nErr;
-}
-
-/*
-** This routine frees up a list of Tokens. The pComment tokens are
-** not cleared by this. So we leak a little memory when using the -doc
-** option. So what.
-*/
-static void FreeTokenList(Token *pList){
- Token *pNext;
- while( pList ){
- pNext = pList->pNext;
- SafeFree(pList);
- pList = pNext;
- }
-}
-
-/*
-** Tokenize an entire file. Return a pointer to the list of tokens.
-**
-** Space for each token is obtained from a separate malloc() call. The
-** calling function is responsible for freeing this space.
-**
-** If pTable is not NULL, then fill the table with all identifiers seen in
-** the input file.
-*/
-static Token *TokenizeFile(const char *zFile, IdentTable *pTable){
- InStream sIn;
- Token *pFirst = 0, *pLast = 0, *pNew;
- int nErr = 0;
-
- sIn.z = zFile;
- sIn.i = 0;
- sIn.nLine = 1;
- blockComment = 0;
-
- while( sIn.z[sIn.i]!=0 ){
- pNew = SafeMalloc( sizeof(Token) );
- nErr += GetBigToken(&sIn,pNew,pTable);
- debug3(TOKENIZER, "Token on line %d: [%.*s]\n",
- pNew->nLine, pNew->nText<50 ? pNew->nText : 50, pNew->zText);
- if( pFirst==0 ){
- pFirst = pLast = pNew;
- pNew->pPrev = 0;
- }else{
- pLast->pNext = pNew;
- pNew->pPrev = pLast;
- pLast = pNew;
- }
- if( pNew->eType==TT_EOF ) break;
- }
- if( pLast ) pLast->pNext = 0;
- blockComment = 0;
- if( nErr ){
- FreeTokenList(pFirst);
- pFirst = 0;
- }
-
- return pFirst;
-}
-
-#if TEST==1
-/*
-** Use the following routine to test or debug the tokenizer.
-*/
-void main(int argc, char **argv){
- char *zFile;
- Token *pList, *p;
- IdentTable sTable;
-
- if( argc!=2 ){
- fprintf(stderr,"Usage: %s filename\n",*argv);
- exit(1);
- }
- memset(&sTable,0,sizeof(sTable));
- zFile = ReadFile(argv[1]);
- if( zFile==0 ){
- fprintf(stderr,"Can't read file \"%s\"\n",argv[1]);
- exit(1);
- }
- pList = TokenizeFile(zFile,&sTable);
- for(p=pList; p; p=p->pNext){
- int j;
- switch( p->eType ){
- case TT_Space:
- printf("%4d: Space\n",p->nLine);
- break;
- case TT_Id:
- printf("%4d: Id %.*s\n",p->nLine,p->nText,p->zText);
- break;
- case TT_Preprocessor:
- printf("%4d: Preprocessor %.*s\n",p->nLine,p->nText,p->zText);
- break;
- case TT_Comment:
- printf("%4d: Comment\n",p->nLine);
- break;
- case TT_BlockComment:
- printf("%4d: Block Comment\n",p->nLine);
- break;
- case TT_Number:
- printf("%4d: Number %.*s\n",p->nLine,p->nText,p->zText);
- break;
- case TT_String:
- printf("%4d: String %.*s\n",p->nLine,p->nText,p->zText);
- break;
- case TT_Other:
- printf("%4d: Other %.*s\n",p->nLine,p->nText,p->zText);
- break;
- case TT_Braces:
- for(j=0; j<p->nText && j<30 && p->zText[j]!='\n'; j++){}
- printf("%4d: Braces %.*s...}\n",p->nLine,j,p->zText);
- break;
- case TT_EOF:
- printf("%4d: End of file\n",p->nLine);
- break;
- default:
- printf("%4d: type %d\n",p->nLine,p->eType);
- break;
- }
- }
- FreeTokenList(pList);
- SafeFree(zFile);
- IdentTablePrint(&sTable,stdout);
-}
-#endif
-
-#ifdef DEBUG
-/*
-** For debugging purposes, write out a list of tokens.
-*/
-static void PrintTokens(Token *pFirst, Token *pLast){
- int needSpace = 0;
- int c;
-
- pLast = pLast->pNext;
- while( pFirst!=pLast ){
- switch( pFirst->eType ){
- case TT_Preprocessor:
- printf("\n%.*s\n",pFirst->nText,pFirst->zText);
- needSpace = 0;
- break;
-
- case TT_Id:
- case TT_Number:
- printf("%s%.*s", needSpace ? " " : "", pFirst->nText, pFirst->zText);
- needSpace = 1;
- break;
-
- default:
- c = pFirst->zText[0];
- printf("%s%.*s",
- (needSpace && (c=='*' || c=='{')) ? " " : "",
- pFirst->nText, pFirst->zText);
- needSpace = pFirst->zText[0]==',';
- break;
- }
- pFirst = pFirst->pNext;
- }
-}
-#endif
-
-/*
-** Convert a sequence of tokens into a string and return a pointer
-** to that string. Space to hold the string is obtained from malloc()
-** and must be freed by the calling function.
-**
-** Certain keywords (EXPORT, PRIVATE, PUBLIC, PROTECTED) are always
-** skipped.
-**
-** If pSkip!=0 then skip over nSkip tokens beginning with pSkip.
-**
-** If zTerm!=0 then append the text to the end.
-*/
-static char *TokensToString(
- Token *pFirst, /* First token in the string */
- Token *pLast, /* Last token in the string */
- char *zTerm, /* Terminate the string with this text if not NULL */
- Token *pSkip, /* Skip this token if not NULL */
- int nSkip /* Skip a total of this many tokens */
-){
- char *zReturn;
- String str;
- int needSpace = 0;
- int c;
- int iSkip = 0;
- int skipOne = 0;
-
- StringInit(&str);
- pLast = pLast->pNext;
- while( pFirst!=pLast ){
- if( pFirst==pSkip ){ iSkip = nSkip; }
- if( iSkip>0 ){
- iSkip--;
- pFirst=pFirst->pNext;
- continue;
- }
- switch( pFirst->eType ){
- case TT_Preprocessor:
- StringAppend(&str,"\n",1);
- StringAppend(&str,pFirst->zText,pFirst->nText);
- StringAppend(&str,"\n",1);
- needSpace = 0;
- break;
-
- case TT_Id:
- switch( pFirst->zText[0] ){
- case 'E':
- if( pFirst->nText==6 && strncmp(pFirst->zText,"EXPORT",6)==0 ){
- skipOne = 1;
- }
- break;
- case 'P':
- switch( pFirst->nText ){
- case 6: skipOne = !strncmp(pFirst->zText,"PUBLIC", 6); break;
- case 7: skipOne = !strncmp(pFirst->zText,"PRIVATE",7); break;
- case 9: skipOne = !strncmp(pFirst->zText,"PROTECTED",9); break;
- default: break;
- }
- break;
- default:
- break;
- }
- if( skipOne ){
- pFirst = pFirst->pNext;
- continue;
- }
- /* Fall thru to the next case */
- case TT_Number:
- if( needSpace ){
- StringAppend(&str," ",1);
- }
- StringAppend(&str,pFirst->zText,pFirst->nText);
- needSpace = 1;
- break;
-
- default:
- c = pFirst->zText[0];
- if( needSpace && (c=='*' || c=='{') ){
- StringAppend(&str," ",1);
- }
- StringAppend(&str,pFirst->zText,pFirst->nText);
- /* needSpace = pFirst->zText[0]==','; */
- needSpace = 0;
- break;
- }
- pFirst = pFirst->pNext;
- }
- if( zTerm && *zTerm ){
- StringAppend(&str,zTerm,strlen(zTerm));
- }
- zReturn = StrDup(StringGet(&str),0);
- StringReset(&str);
- return zReturn;
-}
-
-/*
-** This routine is called when we see one of the keywords "struct",
-** "enum", "union" or "class". This might be the beginning of a
-** type declaration. This routine will process the declaration and
-** remove the declaration tokens from the input stream.
-**
-** If this is a type declaration that is immediately followed by a
-** semicolon (in other words it isn't also a variable definition)
-** then set *pReset to ';'. Otherwise leave *pReset at 0. The
-** *pReset flag causes the parser to skip ahead to the next token
-** that begins with the value placed in the *pReset flag, if that
-** value is different from 0.
-*/
-static int ProcessTypeDecl(Token *pList, int flags, int *pReset){
- Token *pName, *pEnd;
- Decl *pDecl;
- String str;
- int need_to_collapse = 1;
- int type = 0;
-
- *pReset = 0;
- if( pList==0 || pList->pNext==0 || pList->pNext->eType!=TT_Id ){
- return 0;
- }
- pName = pList->pNext;
-
- /* Catch the case of "struct Foo;" and skip it. */
- if( pName->pNext && pName->pNext->zText[0]==';' ){
- *pReset = ';';
- return 0;
- }
-
- for(pEnd=pName->pNext; pEnd && pEnd->eType!=TT_Braces; pEnd=pEnd->pNext){
- switch( pEnd->zText[0] ){
- case '(':
- case ')':
- case '*':
- case '[':
- case '=':
- case ';':
- return 0;
- }
- }
- if( pEnd==0 ){
- return 0;
- }
-
- /*
- ** At this point, we know we have a type declaration that is bounded
- ** by pList and pEnd and has the name pName.
- */
-
- /*
- ** If the braces are followed immediately by a semicolon, then we are
- ** dealing a type declaration only. There is not variable definition
- ** following the type declaration. So reset...
- */
- if( pEnd->pNext==0 || pEnd->pNext->zText[0]==';' ){
- *pReset = ';';
- need_to_collapse = 0;
- }else{
- need_to_collapse = 1;
- }
-
- if( proto_static==0 && (flags & (PS_Local|PS_Export|PS_Interface))==0 ){
- /* Ignore these objects unless they are explicitly declared as interface,
- ** or unless the "-local" command line option was specified. */
- *pReset = ';';
- return 0;
- }
-
-#ifdef DEBUG
- if( debugMask & PARSER ){
- printf("**** Found type: %.*s %.*s...\n",
- pList->nText, pList->zText, pName->nText, pName->zText);
- PrintTokens(pList,pEnd);
- printf(";\n");
- }
-#endif
-
- /*
- ** Create a new Decl object for this definition. Actually, if this
- ** is a C++ class definition, then the Decl object might already exist,
- ** so check first for that case before creating a new one.
- */
- switch( *pList->zText ){
- case 'c': type = TY_Class; break;
- case 's': type = TY_Structure; break;
- case 'e': type = TY_Enumeration; break;
- case 'u': type = TY_Union; break;
- default: /* Can't Happen */ break;
- }
- if( type!=TY_Class ){
- pDecl = 0;
- }else{
- pDecl = FindDecl(pName->zText, pName->nText);
- if( pDecl && (pDecl->flags & type)!=type ) pDecl = 0;
- }
- if( pDecl==0 ){
- pDecl = CreateDecl(pName->zText,pName->nText);
- }
- if( (flags & PS_Static) || !(flags & (PS_Interface|PS_Export)) ){
- DeclSetProperty(pDecl,DP_Local);
- }
- DeclSetProperty(pDecl,type);
-
- /* The object has a full declaration only if it is contained within
- ** "#if INTERFACE...#endif" or "#if EXPORT_INTERFACE...#endif" or
- ** "#if LOCAL_INTERFACE...#endif". Otherwise, we only give it a
- ** forward declaration.
- */
- if( flags & (PS_Local | PS_Export | PS_Interface) ){
- pDecl->zDecl = TokensToString(pList,pEnd,";\n",0,0);
- }else{
- pDecl->zDecl = 0;
- }
- pDecl->pComment = pList->pComment;
- StringInit(&str);
- StringAppend(&str,"typedef ",0);
- StringAppend(&str,pList->zText,pList->nText);
- StringAppend(&str," ",0);
- StringAppend(&str,pName->zText,pName->nText);
- StringAppend(&str," ",0);
- StringAppend(&str,pName->zText,pName->nText);
- StringAppend(&str,";\n",2);
- pDecl->zFwd = StrDup(StringGet(&str),0);
- StringReset(&str);
- StringInit(&str);
- StringAppend(&str,pList->zText,pList->nText);
- StringAppend(&str," ",0);
- StringAppend(&str,pName->zText,pName->nText);
- StringAppend(&str,";\n",2);
- pDecl->zFwdCpp = StrDup(StringGet(&str),0);
- StringReset(&str);
- if( flags & PS_Export ){
- DeclSetProperty(pDecl,DP_Export);
- }else if( flags & PS_Local ){
- DeclSetProperty(pDecl,DP_Local);
- }
-
- /* Here's something weird. ANSI-C doesn't allow a forward declaration
- ** of an enumeration. So we have to build the typedef into the
- ** definition.
- */
- if( pDecl->zDecl && DeclHasProperty(pDecl, TY_Enumeration) ){
- StringInit(&str);
- StringAppend(&str,pDecl->zDecl,0);
- StringAppend(&str,pDecl->zFwd,0);
- SafeFree(pDecl->zDecl);
- SafeFree(pDecl->zFwd);
- pDecl->zFwd = 0;
- pDecl->zDecl = StrDup(StringGet(&str),0);
- StringReset(&str);
- }
-
- if( pName->pNext->zText[0]==':' ){
- DeclSetProperty(pDecl,DP_Cplusplus);
- }
- if( pName->nText==5 && strncmp(pName->zText,"class",5)==0 ){
- DeclSetProperty(pDecl,DP_Cplusplus);
- }
-
- /*
- ** Remove all but pList and pName from the input stream.
- */
- if( need_to_collapse ){
- while( pEnd!=pName ){
- Token *pPrev = pEnd->pPrev;
- pPrev->pNext = pEnd->pNext;
- pEnd->pNext->pPrev = pPrev;
- SafeFree(pEnd);
- pEnd = pPrev;
- }
- }
- return 0;
-}
-
-/*
-** Given a list of tokens that declare something (a function, procedure,
-** variable or typedef) find the token which contains the name of the
-** thing being declared.
-**
-** Algorithm:
-**
-** The name is:
-**
-** 1. The first identifier that is followed by a "[", or
-**
-** 2. The first identifier that is followed by a "(" where the
-** "(" is followed by another identifier, or
-**
-** 3. The first identifier followed by "::", or
-**
-** 4. If none of the above, then the last identifier.
-**
-** In all of the above, certain reserved words (like "char") are
-** not considered identifiers.
-*/
-static Token *FindDeclName(Token *pFirst, Token *pLast){
- Token *pName = 0;
- Token *p;
- int c;
-
- if( pFirst==0 || pLast==0 ){
- return 0;
- }
- pLast = pLast->pNext;
- for(p=pFirst; p && p!=pLast; p=p->pNext){
- if( p->eType==TT_Id ){
- static IdentTable sReserved;
- static int isInit = 0;
- static const char *aWords[] = { "char", "class",
- "const", "double", "enum", "extern", "EXPORT", "ET_PROC",
- "float", "int", "long",
- "PRIVATE", "PROTECTED", "PUBLIC",
- "register", "static", "struct", "sizeof", "signed", "typedef",
- "union", "volatile", "virtual", "void", };
-
- if( !isInit ){
- int i;
- for(i=0; i<sizeof(aWords)/sizeof(aWords[0]); i++){
- IdentTableInsert(&sReserved,aWords[i],0);
- }
- isInit = 1;
- }
- if( !IdentTableTest(&sReserved,p->zText,p->nText) ){
- pName = p;
- }
- }else if( p==pFirst ){
- continue;
- }else if( (c=p->zText[0])=='[' && pName ){
- break;
- }else if( c=='(' && p->pNext && p->pNext->eType==TT_Id && pName ){
- break;
- }else if( c==':' && p->zText[1]==':' && pName ){
- break;
- }
- }
- return pName;
-}
-
-/*
-** This routine is called when we see a method for a class that begins
-** with the PUBLIC, PRIVATE, or PROTECTED keywords. Such methods are
-** added to their class definitions.
-*/
-static int ProcessMethodDef(Token *pFirst, Token *pLast, int flags){
- Token *pClass;
- char *zDecl;
- Decl *pDecl;
- String str;
- int type;
-
- pLast = pLast->pPrev;
- while( pFirst->zText[0]=='P' ){
- int rc = 1;
- switch( pFirst->nText ){
- case 6: rc = strncmp(pFirst->zText,"PUBLIC",6); break;
- case 7: rc = strncmp(pFirst->zText,"PRIVATE",7); break;
- case 9: rc = strncmp(pFirst->zText,"PROTECTED",9); break;
- default: break;
- }
- if( rc ) break;
- pFirst = pFirst->pNext;
- }
- pClass = FindDeclName(pFirst,pLast);
- if( pClass==0 ){
- fprintf(stderr,"%s:%d: Unable to find the class name for this method\n",
- zFilename, pFirst->nLine);
- return 1;
- }
- pDecl = FindDecl(pClass->zText, pClass->nText);
- if( pDecl==0 || (pDecl->flags & TY_Class)!=TY_Class ){
- pDecl = CreateDecl(pClass->zText, pClass->nText);
- DeclSetProperty(pDecl, TY_Class);
- }
- StringInit(&str);
- if( pDecl->zExtra ){
- StringAppend(&str, pDecl->zExtra, 0);
- SafeFree(pDecl->zExtra);
- pDecl->zExtra = 0;
- }
- type = flags & PS_PPP;
- if( pDecl->extraType!=type ){
- if( type & PS_Public ){
- StringAppend(&str, "public:\n", 0);
- pDecl->extraType = PS_Public;
- }else if( type & PS_Protected ){
- StringAppend(&str, "protected:\n", 0);
- pDecl->extraType = PS_Protected;
- }else if( type & PS_Private ){
- StringAppend(&str, "private:\n", 0);
- pDecl->extraType = PS_Private;
- }
- }
- StringAppend(&str, " ", 0);
- zDecl = TokensToString(pFirst, pLast, ";\n", pClass, 2);
- StringAppend(&str, zDecl, 0);
- SafeFree(zDecl);
- pDecl->zExtra = StrDup(StringGet(&str), 0);
- StringReset(&str);
- return 0;
-}
-
-/*
-** This routine is called when we see a function or procedure definition.
-** We make an entry in the declaration table that is a prototype for this
-** function or procedure.
-*/
-static int ProcessProcedureDef(Token *pFirst, Token *pLast, int flags){
- Token *pName;
- Decl *pDecl;
- Token *pCode;
-
- if( pFirst==0 || pLast==0 ){
- return 0;
- }
- if( flags & PS_Method ){
- if( flags & PS_PPP ){
- return ProcessMethodDef(pFirst, pLast, flags);
- }else{
- return 0;
- }
- }
- if( (flags & PS_Static)!=0 && !proto_static ){
- return 0;
- }
- pCode = pLast;
- while( pLast && pLast!=pFirst && pLast->zText[0]!=')' ){
- pLast = pLast->pPrev;
- }
- if( pLast==0 || pLast==pFirst || pFirst->pNext==pLast ){
- fprintf(stderr,"%s:%d: Unrecognized syntax.\n",
- zFilename, pFirst->nLine);
- return 1;
- }
- if( flags & (PS_Interface|PS_Export|PS_Local) ){
- fprintf(stderr,"%s:%d: Missing \"inline\" on function or procedure.\n",
- zFilename, pFirst->nLine);
- return 1;
- }
- pName = FindDeclName(pFirst,pLast);
- if( pName==0 ){
- fprintf(stderr,"%s:%d: Malformed function or procedure definition.\n",
- zFilename, pFirst->nLine);
- return 1;
- }
-
- /*
- ** At this point we've isolated a procedure declaration between pFirst
- ** and pLast with the name pName.
- */
-#ifdef DEBUG
- if( debugMask & PARSER ){
- printf("**** Found routine: %.*s on line %d...\n", pName->nText,
- pName->zText, pFirst->nLine);
- PrintTokens(pFirst,pLast);
- printf(";\n");
- }
-#endif
- pDecl = CreateDecl(pName->zText,pName->nText);
- pDecl->pComment = pFirst->pComment;
- if( pCode && pCode->eType==TT_Braces ){
- pDecl->tokenCode = *pCode;
- }
- DeclSetProperty(pDecl,TY_Subroutine);
- pDecl->zDecl = TokensToString(pFirst,pLast,";\n",0,0);
- if( (flags & (PS_Static|PS_Local2))!=0 ){
- DeclSetProperty(pDecl,DP_Local);
- }else if( (flags & (PS_Export2))!=0 ){
- DeclSetProperty(pDecl,DP_Export);
- }
-
- if( flags & DP_Cplusplus ){
- DeclSetProperty(pDecl,DP_Cplusplus);
- }else{
- DeclSetProperty(pDecl,DP_ExternCReqd);
- }
-
- return 0;
-}
-
-/*
-** This routine is called whenever we see the "inline" keyword. We
-** need to seek-out the inline function or procedure and make a
-** declaration out of the entire definition.
-*/
-static int ProcessInlineProc(Token *pFirst, int flags, int *pReset){
- Token *pName;
- Token *pEnd;
- Decl *pDecl;
-
- for(pEnd=pFirst; pEnd; pEnd = pEnd->pNext){
- if( pEnd->zText[0]=='{' || pEnd->zText[0]==';' ){
- *pReset = pEnd->zText[0];
- break;
- }
- }
- if( pEnd==0 ){
- *pReset = ';';
- fprintf(stderr,"%s:%d: incomplete inline procedure definition\n",
- zFilename, pFirst->nLine);
- return 1;
- }
- pName = FindDeclName(pFirst,pEnd);
- if( pName==0 ){
- fprintf(stderr,"%s:%d: malformed inline procedure definition\n",
- zFilename, pFirst->nLine);
- return 1;
- }
-
-#ifdef DEBUG
- if( debugMask & PARSER ){
- printf("**** Found inline routine: %.*s on line %d...\n",
- pName->nText, pName->zText, pFirst->nLine);
- PrintTokens(pFirst,pEnd);
- printf("\n");
- }
-#endif
- pDecl = CreateDecl(pName->zText,pName->nText);
- pDecl->pComment = pFirst->pComment;
- DeclSetProperty(pDecl,TY_Subroutine);
- pDecl->zDecl = TokensToString(pFirst,pEnd,";\n",0,0);
- if( (flags & (PS_Static|PS_Local|PS_Local2)) ){
- DeclSetProperty(pDecl,DP_Local);
- }else if( flags & (PS_Export|PS_Export2) ){
- DeclSetProperty(pDecl,DP_Export);
- }
-
- if( flags & DP_Cplusplus ){
- DeclSetProperty(pDecl,DP_Cplusplus);
- }else{
- DeclSetProperty(pDecl,DP_ExternCReqd);
- }
-
- return 0;
-}
-
-/*
-** Determine if the tokens between pFirst and pEnd form a variable
-** definition or a function prototype. Return TRUE if we are dealing
-** with a variable defintion and FALSE for a prototype.
-**
-** pEnd is the token that ends the object. It can be either a ';' or
-** a '='. If it is '=', then assume we have a variable definition.
-**
-** If pEnd is ';', then the determination is more difficult. We have
-** to search for an occurrence of an ID followed immediately by '('.
-** If found, we have a prototype. Otherwise we are dealing with a
-** variable definition.
-*/
-static int isVariableDef(Token *pFirst, Token *pEnd){
- if( pEnd && pEnd->zText[0]=='=' &&
- (pEnd->pPrev->nText!=8 || strncmp(pEnd->pPrev->zText,"operator",8)!=0)
- ){
- return 1;
- }
- while( pFirst && pFirst!=pEnd && pFirst->pNext && pFirst->pNext!=pEnd ){
- if( pFirst->eType==TT_Id && pFirst->pNext->zText[0]=='(' ){
- return 0;
- }
- pFirst = pFirst->pNext;
- }
- return 1;
-}
-
-/*
-** Return TRUE if pFirst is the first token of a static assert.
-*/
-static int isStaticAssert(Token *pFirst){
- if( (pFirst->nText==13 && strncmp(pFirst->zText, "static_assert", 13)==0)
- || (pFirst->nText==14 && strncmp(pFirst->zText, "_Static_assert", 14)==0)
- ){
- return 1;
- }else{
- return 0;
- }
-}
-
-/*
-** This routine is called whenever we encounter a ";" or "=". The stuff
-** between pFirst and pLast constitutes either a typedef or a global
-** variable definition. Do the right thing.
-*/
-static int ProcessDecl(Token *pFirst, Token *pEnd, int flags){
- Token *pName;
- Decl *pDecl;
- int isLocal = 0;
- int isVar;
- int nErr = 0;
-
- if( pFirst==0 || pEnd==0 ){
- return 0;
- }
- if( flags & PS_Typedef ){
- if( (flags & (PS_Export2|PS_Local2))!=0 ){
- fprintf(stderr,"%s:%d: \"EXPORT\" or \"LOCAL\" ignored before typedef.\n",
- zFilename, pFirst->nLine);
- nErr++;
- }
- if( (flags & (PS_Interface|PS_Export|PS_Local|DP_Cplusplus))==0 ){
- /* It is illegal to duplicate a typedef in C (but OK in C++).
- ** So don't record typedefs that aren't within a C++ file or
- ** within #if INTERFACE..#endif */
- return nErr;
- }
- if( (flags & (PS_Interface|PS_Export|PS_Local))==0 && proto_static==0 ){
- /* Ignore typedefs that are not with "#if INTERFACE..#endif" unless
- ** the "-local" command line option is used. */
- return nErr;
- }
- if( (flags & (PS_Interface|PS_Export))==0 ){
- /* typedefs are always local, unless within #if INTERFACE..#endif */
- isLocal = 1;
- }
- }else if( flags & (PS_Static|PS_Local2) ){
- if( proto_static==0 && (flags & PS_Local2)==0 ){
- /* Don't record static variables unless the "-local" command line
- ** option was specified or the "LOCAL" keyword is used. */
- return nErr;
- }
- while( pFirst!=0 && pFirst->pNext!=pEnd &&
- ((pFirst->nText==6 && strncmp(pFirst->zText,"static",6)==0)
- || (pFirst->nText==5 && strncmp(pFirst->zText,"LOCAL",6)==0))
- ){
- /* Lose the initial "static" or local from local variables.
- ** We'll prepend "extern" later. */
- pFirst = pFirst->pNext;
- isLocal = 1;
- }
- if( pFirst==0 || !isLocal ){
- return nErr;
- }
- }else if( flags & PS_Method ){
- /* Methods are declared by their class. Don't declare separately. */
- return nErr;
- }else if( isStaticAssert(pFirst) ){
- return 0;
- }
- isVar = (flags & (PS_Typedef|PS_Method))==0 && isVariableDef(pFirst,pEnd);
- if( isVar && (flags & (PS_Interface|PS_Export|PS_Local))!=0
- && (flags & PS_Extern)==0 ){
- fprintf(stderr,"%s:%d: Can't define a variable in this context\n",
- zFilename, pFirst->nLine);
- nErr++;
- }
- pName = FindDeclName(pFirst,pEnd->pPrev);
- if( pName==0 ){
- if( pFirst->nText==4 && strncmp(pFirst->zText,"enum",4)==0 ){
- /* Ignore completely anonymous enums. See documentation section 3.8.1. */
- return nErr;
- }else{
- fprintf(stderr,"%s:%d: Can't find a name for the object declared here.\n",
- zFilename, pFirst->nLine);
- return nErr+1;
- }
- }
-
-#ifdef DEBUG
- if( debugMask & PARSER ){
- if( flags & PS_Typedef ){
- printf("**** Found typedef %.*s at line %d...\n",
- pName->nText, pName->zText, pName->nLine);
- }else if( isVar ){
- printf("**** Found variable %.*s at line %d...\n",
- pName->nText, pName->zText, pName->nLine);
- }else{
- printf("**** Found prototype %.*s at line %d...\n",
- pName->nText, pName->zText, pName->nLine);
- }
- PrintTokens(pFirst,pEnd->pPrev);
- printf(";\n");
- }
-#endif
-
- pDecl = CreateDecl(pName->zText,pName->nText);
- if( (flags & PS_Typedef) ){
- DeclSetProperty(pDecl, TY_Typedef);
- }else if( isVar ){
- DeclSetProperty(pDecl,DP_ExternReqd | TY_Variable);
- if( !(flags & DP_Cplusplus) ){
- DeclSetProperty(pDecl,DP_ExternCReqd);
- }
- }else{
- DeclSetProperty(pDecl, TY_Subroutine);
- if( !(flags & DP_Cplusplus) ){
- DeclSetProperty(pDecl,DP_ExternCReqd);
- }
- }
- pDecl->pComment = pFirst->pComment;
- pDecl->zDecl = TokensToString(pFirst,pEnd->pPrev,";\n",0,0);
- if( isLocal || (flags & (PS_Local|PS_Local2))!=0 ){
- DeclSetProperty(pDecl,DP_Local);
- }else if( flags & (PS_Export|PS_Export2) ){
- DeclSetProperty(pDecl,DP_Export);
- }
- if( flags & DP_Cplusplus ){
- DeclSetProperty(pDecl,DP_Cplusplus);
- }
- return nErr;
-}
-
-/*
-** Push an if condition onto the if stack
-*/
-static void PushIfMacro(
- const char *zPrefix, /* A prefix, like "define" or "!" */
- const char *zText, /* The condition */
- int nText, /* Number of characters in zText */
- int nLine, /* Line number where this macro occurs */
- int flags /* Either 0, PS_Interface, PS_Export or PS_Local */
-){
- Ifmacro *pIf;
- int nByte;
-
- nByte = sizeof(Ifmacro);
- if( zText ){
- if( zPrefix ){
- nByte += strlen(zPrefix) + 2;
- }
- nByte += nText + 1;
- }
- pIf = SafeMalloc( nByte );
- if( zText ){
- pIf->zCondition = (char*)&pIf[1];
- if( zPrefix ){
- sprintf(pIf->zCondition,"%s(%.*s)",zPrefix,nText,zText);
- }else{
- sprintf(pIf->zCondition,"%.*s",nText,zText);
- }
- }else{
- pIf->zCondition = 0;
- }
- pIf->nLine = nLine;
- pIf->flags = flags;
- pIf->pNext = ifStack;
- ifStack = pIf;
-}
-
-/*
-** This routine is called to handle all preprocessor directives.
-**
-** This routine will recompute the value of *pPresetFlags to be the
-** logical or of all flags on all nested #ifs. The #ifs that set flags
-** are as follows:
-**
-** conditional flag set
-** ------------------------ --------------------
-** #if INTERFACE PS_Interface
-** #if EXPORT_INTERFACE PS_Export
-** #if LOCAL_INTERFACE PS_Local
-**
-** For example, if after processing the preprocessor token given
-** by pToken there is an "#if INTERFACE" on the preprocessor
-** stack, then *pPresetFlags will be set to PS_Interface.
-*/
-static int ParsePreprocessor(Token *pToken, int flags, int *pPresetFlags){
- const char *zCmd;
- int nCmd;
- const char *zArg;
- int nArg;
- int nErr = 0;
- Ifmacro *pIf;
-
- zCmd = &pToken->zText[1];
- while( isspace(*zCmd) && *zCmd!='\n' ){
- zCmd++;
- }
- if( !isalpha(*zCmd) ){
- return 0;
- }
- nCmd = 1;
- while( isalpha(zCmd[nCmd]) ){
- nCmd++;
- }
-
- if( nCmd==5 && strncmp(zCmd,"endif",5)==0 ){
- /*
- ** Pop the if stack
- */
- pIf = ifStack;
- if( pIf==0 ){
- fprintf(stderr,"%s:%d: extra '#endif'.\n",zFilename,pToken->nLine);
- return 1;
- }
- ifStack = pIf->pNext;
- SafeFree(pIf);
- }else if( nCmd==6 && strncmp(zCmd,"define",6)==0 ){
- /*
- ** Record a #define if we are in PS_Interface or PS_Export
- */
- Decl *pDecl;
- if( !(flags & (PS_Local|PS_Interface|PS_Export)) ){ return 0; }
- zArg = &zCmd[6];
- while( *zArg && isspace(*zArg) && *zArg!='\n' ){
- zArg++;
- }
- if( *zArg==0 || *zArg=='\n' ){ return 0; }
- for(nArg=0; ISALNUM(zArg[nArg]); nArg++){}
- if( nArg==0 ){ return 0; }
- pDecl = CreateDecl(zArg,nArg);
- pDecl->pComment = pToken->pComment;
- DeclSetProperty(pDecl,TY_Macro);
- pDecl->zDecl = SafeMalloc( pToken->nText + 2 );
- sprintf(pDecl->zDecl,"%.*s\n",pToken->nText,pToken->zText);
- if( flags & PS_Export ){
- DeclSetProperty(pDecl,DP_Export);
- }else if( flags & PS_Local ){
- DeclSetProperty(pDecl,DP_Local);
- }
- }else if( nCmd==7 && strncmp(zCmd,"include",7)==0 ){
- /*
- ** Record an #include if we are in PS_Interface or PS_Export
- */
- Include *pInclude;
- char *zIf;
-
- if( !(flags & (PS_Interface|PS_Export)) ){ return 0; }
- zArg = &zCmd[7];
- while( *zArg && isspace(*zArg) ){ zArg++; }
- for(nArg=0; !isspace(zArg[nArg]); nArg++){}
- if( (zArg[0]=='"' && zArg[nArg-1]!='"')
- ||(zArg[0]=='<' && zArg[nArg-1]!='>')
- ){
- fprintf(stderr,"%s:%d: malformed #include statement.\n",
- zFilename,pToken->nLine);
- return 1;
- }
- zIf = GetIfString();
- if( zIf ){
- pInclude = SafeMalloc( sizeof(Include) + nArg*2 + strlen(zIf) + 10 );
- pInclude->zFile = (char*)&pInclude[1];
- pInclude->zLabel = &pInclude->zFile[nArg+1];
- sprintf(pInclude->zFile,"%.*s",nArg,zArg);
- sprintf(pInclude->zLabel,"%.*s:%s",nArg,zArg,zIf);
- pInclude->zIf = &pInclude->zLabel[nArg+1];
- SafeFree(zIf);
- }else{
- pInclude = SafeMalloc( sizeof(Include) + nArg + 1 );
- pInclude->zFile = (char*)&pInclude[1];
- sprintf(pInclude->zFile,"%.*s",nArg,zArg);
- pInclude->zIf = 0;
- pInclude->zLabel = pInclude->zFile;
- }
- pInclude->pNext = includeList;
- includeList = pInclude;
- }else if( nCmd==2 && strncmp(zCmd,"if",2)==0 ){
- /*
- ** Push an #if. Watch for the special cases of INTERFACE
- ** and EXPORT_INTERFACE and LOCAL_INTERFACE
- */
- zArg = &zCmd[2];
- while( *zArg && isspace(*zArg) && *zArg!='\n' ){
- zArg++;
- }
- if( *zArg==0 || *zArg=='\n' ){ return 0; }
- nArg = pToken->nText + (int)(pToken->zText - zArg);
- if( nArg==9 && strncmp(zArg,"INTERFACE",9)==0 ){
- PushIfMacro(0,0,0,pToken->nLine,PS_Interface);
- }else if( nArg==16 && strncmp(zArg,"EXPORT_INTERFACE",16)==0 ){
- PushIfMacro(0,0,0,pToken->nLine,PS_Export);
- }else if( nArg==15 && strncmp(zArg,"LOCAL_INTERFACE",15)==0 ){
- PushIfMacro(0,0,0,pToken->nLine,PS_Local);
- }else if( nArg==15 && strncmp(zArg,"MAKEHEADERS_STOPLOCAL_INTERFACE",15)==0 ){
- PushIfMacro(0,0,0,pToken->nLine,PS_Local);
- }else{
- PushIfMacro(0,zArg,nArg,pToken->nLine,0);
- }
- }else if( nCmd==5 && strncmp(zCmd,"ifdef",5)==0 ){
- /*
- ** Push an #ifdef.
- */
- zArg = &zCmd[5];
- while( *zArg && isspace(*zArg) && *zArg!='\n' ){
- zArg++;
- }
- if( *zArg==0 || *zArg=='\n' ){ return 0; }
- nArg = pToken->nText + (int)(pToken->zText - zArg);
- PushIfMacro("defined",zArg,nArg,pToken->nLine,0);
- }else if( nCmd==6 && strncmp(zCmd,"ifndef",6)==0 ){
- /*
- ** Push an #ifndef.
- */
- zArg = &zCmd[6];
- while( *zArg && isspace(*zArg) && *zArg!='\n' ){
- zArg++;
- }
- if( *zArg==0 || *zArg=='\n' ){ return 0; }
- nArg = pToken->nText + (int)(pToken->zText - zArg);
- PushIfMacro("!defined",zArg,nArg,pToken->nLine,0);
- }else if( nCmd==4 && strncmp(zCmd,"else",4)==0 ){
- /*
- ** Invert the #if on the top of the stack
- */
- if( ifStack==0 ){
- fprintf(stderr,"%s:%d: '#else' without an '#if'\n",zFilename,
- pToken->nLine);
- return 1;
- }
- pIf = ifStack;
- if( pIf->zCondition ){
- ifStack = ifStack->pNext;
- PushIfMacro("!",pIf->zCondition,strlen(pIf->zCondition),pIf->nLine,0);
- SafeFree(pIf);
- }else{
- pIf->flags = 0;
- }
- }else{
- /*
- ** This directive can be safely ignored
- */
- return 0;
- }
-
- /*
- ** Recompute the preset flags
- */
- *pPresetFlags = 0;
- for(pIf = ifStack; pIf; pIf=pIf->pNext){
- *pPresetFlags |= pIf->flags;
- }
-
- return nErr;
-}
-
-/*
-** Parse an entire file. Return the number of errors.
-**
-** pList is a list of tokens in the file. Whitespace tokens have been
-** eliminated, and text with {...} has been collapsed into a
-** single TT_Brace token.
-**
-** initFlags are a set of parse flags that should always be set for this
-** file. For .c files this is normally 0. For .h files it is PS_Interface.
-*/
-static int ParseFile(Token *pList, int initFlags){
- int nErr = 0;
- Token *pStart = 0;
- int flags = initFlags;
- int presetFlags = initFlags;
- int resetFlag = 0;
-
- includeList = 0;
- while( pList ){
- switch( pList->eType ){
- case TT_EOF:
- goto end_of_loop;
-
- case TT_Preprocessor:
- nErr += ParsePreprocessor(pList,flags,&presetFlags);
- pStart = 0;
- presetFlags |= initFlags;
- flags = presetFlags;
- break;
-
- case TT_Other:
- switch( pList->zText[0] ){
- case ';':
- nErr += ProcessDecl(pStart,pList,flags);
- pStart = 0;
- flags = presetFlags;
- break;
-
- case '=':
- if( pList->pPrev->nText==8
- && strncmp(pList->pPrev->zText,"operator",8)==0 ){
- break;
- }
- nErr += ProcessDecl(pStart,pList,flags);
- pStart = 0;
- while( pList && pList->zText[0]!=';' ){
- pList = pList->pNext;
- }
- if( pList==0 ) goto end_of_loop;
- flags = presetFlags;
- break;
-
- case ':':
- if( pList->zText[1]==':' ){
- flags |= PS_Method;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case TT_Braces:
- nErr += ProcessProcedureDef(pStart,pList,flags);
- pStart = 0;
- flags = presetFlags;
- break;
-
- case TT_Id:
- if( pStart==0 ){
- pStart = pList;
- flags = presetFlags;
- }
- resetFlag = 0;
- switch( pList->zText[0] ){
- case 'c':
- if( pList->nText==5 && strncmp(pList->zText,"class",5)==0 ){
- nErr += ProcessTypeDecl(pList,flags,&resetFlag);
- }
- break;
-
- case 'E':
- if( pList->nText==6 && strncmp(pList->zText,"EXPORT",6)==0 ){
- flags |= PS_Export2;
- /* pStart = 0; */
- }
- break;
-
- case 'e':
- if( pList->nText==4 && strncmp(pList->zText,"enum",4)==0 ){
- if( pList->pNext && pList->pNext->eType==TT_Braces ){
- pList = pList->pNext;
- }else{
- nErr += ProcessTypeDecl(pList,flags,&resetFlag);
- }
- }else if( pList->nText==6 && strncmp(pList->zText,"extern",6)==0 ){
- pList = pList->pNext;
- if( pList && pList->nText==3 && strncmp(pList->zText,"\"C\"",3)==0 ){
- pList = pList->pNext;
- flags &= ~DP_Cplusplus;
- }else{
- flags |= PS_Extern;
- }
- pStart = pList;
- }
- break;
-
- case 'i':
- if( pList->nText==6 && strncmp(pList->zText,"inline",6)==0
- && (flags & PS_Static)==0
- ){
- nErr += ProcessInlineProc(pList,flags,&resetFlag);
- }
- break;
-
- case 'L':
- if( pList->nText==5 && strncmp(pList->zText,"LOCAL",5)==0 ){
- flags |= PS_Local2;
- pStart = pList;
- }
- break;
-
- case 'P':
- if( pList->nText==6 && strncmp(pList->zText, "PUBLIC",6)==0 ){
- flags |= PS_Public;
- pStart = pList;
- }else if( pList->nText==7 && strncmp(pList->zText, "PRIVATE",7)==0 ){
- flags |= PS_Private;
- pStart = pList;
- }else if( pList->nText==9 && strncmp(pList->zText,"PROTECTED",9)==0 ){
- flags |= PS_Protected;
- pStart = pList;
- }
- break;
-
- case 's':
- if( pList->nText==6 && strncmp(pList->zText,"struct",6)==0 ){
- if( pList->pNext && pList->pNext->eType==TT_Braces ){
- pList = pList->pNext;
- }else{
- nErr += ProcessTypeDecl(pList,flags,&resetFlag);
- }
- }else if( pList->nText==6 && strncmp(pList->zText,"static",6)==0 ){
- flags |= PS_Static;
- }
- break;
-
- case 't':
- if( pList->nText==7 && strncmp(pList->zText,"typedef",7)==0 ){
- flags |= PS_Typedef;
- }
- break;
-
- case 'u':
- if( pList->nText==5 && strncmp(pList->zText,"union",5)==0 ){
- if( pList->pNext && pList->pNext->eType==TT_Braces ){
- pList = pList->pNext;
- }else{
- nErr += ProcessTypeDecl(pList,flags,&resetFlag);
- }
- }
- break;
-
- default:
- break;
- }
- if( resetFlag!=0 ){
- while( pList && pList->zText[0]!=resetFlag ){
- pList = pList->pNext;
- }
- if( pList==0 ) goto end_of_loop;
- pStart = 0;
- flags = presetFlags;
- }
- break;
-
- case TT_String:
- case TT_Number:
- break;
-
- default:
- pStart = pList;
- flags = presetFlags;
- break;
- }
- pList = pList->pNext;
- }
- end_of_loop:
-
- /* Verify that all #ifs have a matching "#endif" */
- while( ifStack ){
- Ifmacro *pIf = ifStack;
- ifStack = pIf->pNext;
- fprintf(stderr,"%s:%d: This '#if' has no '#endif'\n",zFilename,
- pIf->nLine);
- SafeFree(pIf);
- }
-
- return nErr;
-}
-
-/*
-** If the given Decl object has a non-null zExtra field, then the text
-** of that zExtra field needs to be inserted in the middle of the
-** zDecl field before the last "}" in the zDecl. This routine does that.
-** If the zExtra is NULL, this routine is a no-op.
-**
-** zExtra holds extra method declarations for classes. The declarations
-** have to be inserted into the class definition.
-*/
-static void InsertExtraDecl(Decl *pDecl){
- int i;
- String str;
-
- if( pDecl==0 || pDecl->zExtra==0 || pDecl->zDecl==0 ) return;
- i = strlen(pDecl->zDecl) - 1;
- while( i>0 && pDecl->zDecl[i]!='}' ){ i--; }
- StringInit(&str);
- StringAppend(&str, pDecl->zDecl, i);
- StringAppend(&str, pDecl->zExtra, 0);
- StringAppend(&str, &pDecl->zDecl[i], 0);
- SafeFree(pDecl->zDecl);
- SafeFree(pDecl->zExtra);
- pDecl->zDecl = StrDup(StringGet(&str), 0);
- StringReset(&str);
- pDecl->zExtra = 0;
-}
-
-/*
-** Reset the DP_Forward and DP_Declared flags on all Decl structures.
-** Set both flags for anything that is tagged as local and isn't
-** in the file zFilename so that it won't be printing in other files.
-*/
-static void ResetDeclFlags(char *zFilename){
- Decl *pDecl;
-
- for(pDecl = pDeclFirst; pDecl; pDecl = pDecl->pNext){
- DeclClearProperty(pDecl,DP_Forward|DP_Declared);
- if( DeclHasProperty(pDecl,DP_Local) && pDecl->zFile!=zFilename ){
- DeclSetProperty(pDecl,DP_Forward|DP_Declared);
- }
- }
-}
-
-/*
-** Forward declaration of the ScanText() function.
-*/
-static void ScanText(const char*, GenState *pState);
-
-/*
-** The output in pStr is currently within an #if CONTEXT where context
-** is equal to *pzIf. (*pzIf might be NULL to indicate that we are
-** not within any #if at the moment.) We are getting ready to output
-** some text that needs to be within the context of "#if NEW" where
-** NEW is zIf. Make an appropriate change to the context.
-*/
-static void ChangeIfContext(
- const char *zIf, /* The desired #if context */
- GenState *pState /* Current state of the code generator */
-){
- if( zIf==0 ){
- if( pState->zIf==0 ) return;
- StringAppend(pState->pStr,"#endif\n",0);
- pState->zIf = 0;
- }else{
- if( pState->zIf ){
- if( strcmp(zIf,pState->zIf)==0 ) return;
- StringAppend(pState->pStr,"#endif\n",0);
- pState->zIf = 0;
- }
- ScanText(zIf, pState);
- if( pState->zIf!=0 ){
- StringAppend(pState->pStr,"#endif\n",0);
- }
- StringAppend(pState->pStr,"#if ",0);
- StringAppend(pState->pStr,zIf,0);
- StringAppend(pState->pStr,"\n",0);
- pState->zIf = zIf;
- }
-}
-
-/*
-** Add to the string pStr a #include of every file on the list of
-** include files pInclude. The table pTable contains all files that
-** have already been #included at least once. Don't add any
-** duplicates. Update pTable with every new #include that is added.
-*/
-static void AddIncludes(
- Include *pInclude, /* Write every #include on this list */
- GenState *pState /* Current state of the code generator */
-){
- if( pInclude ){
- if( pInclude->pNext ){
- AddIncludes(pInclude->pNext,pState);
- }
- if( IdentTableInsert(pState->pTable,pInclude->zLabel,0) ){
- ChangeIfContext(pInclude->zIf,pState);
- StringAppend(pState->pStr,"#include ",0);
- StringAppend(pState->pStr,pInclude->zFile,0);
- StringAppend(pState->pStr,"\n",1);
- }
- }
-}
-
-/*
-** Add to the string pStr a declaration for the object described
-** in pDecl.
-**
-** If pDecl has already been declared in this file, detect that
-** fact and abort early. Do not duplicate a declaration.
-**
-** If the needFullDecl flag is false and this object has a forward
-** declaration, then supply the forward declaration only. A later
-** call to CompleteForwardDeclarations() will finish the declaration
-** for us. But if needFullDecl is true, we must supply the full
-** declaration now. Some objects do not have a forward declaration.
-** For those objects, we must print the full declaration now.
-**
-** Because it is illegal to duplicate a typedef in C, care is taken
-** to insure that typedefs for the same identifier are only issued once.
-*/
-static void DeclareObject(
- Decl *pDecl, /* The thing to be declared */
- GenState *pState, /* Current state of the code generator */
- int needFullDecl /* Must have the full declaration. A forward
- * declaration isn't enough */
-){
- Decl *p; /* The object to be declared */
- int flag;
- int isCpp; /* True if generating C++ */
- int doneTypedef = 0; /* True if a typedef has been done for this object */
-
- /* printf("BEGIN %s of %s\n",needFullDecl?"FULL":"PROTOTYPE",pDecl->zName);*/
- /*
- ** For any object that has a forward declaration, go ahead and do the
- ** forward declaration first.
- */
- isCpp = (pState->flags & DP_Cplusplus) != 0;
- for(p=pDecl; p; p=p->pSameName){
- if( p->zFwd ){
- if( !DeclHasProperty(p,DP_Forward) ){
- DeclSetProperty(p,DP_Forward);
- if( strncmp(p->zFwd,"typedef",7)==0 ){
- if( doneTypedef ) continue;
- doneTypedef = 1;
- }
- ChangeIfContext(p->zIf,pState);
- StringAppend(pState->pStr,isCpp ? p->zFwdCpp : p->zFwd,0);
- }
- }
- }
-
- /*
- ** Early out if everything is already suitably declared.
- **
- ** This is a very important step because it prevents us from
- ** executing the code the follows in a recursive call to this
- ** function with the same value for pDecl.
- */
- flag = needFullDecl ? DP_Declared|DP_Forward : DP_Forward;
- for(p=pDecl; p; p=p->pSameName){
- if( !DeclHasProperty(p,flag) ) break;
- }
- if( p==0 ){
- return;
- }
-
- /*
- ** Make sure we have all necessary #includes
- */
- for(p=pDecl; p; p=p->pSameName){
- AddIncludes(p->pInclude,pState);
- }
-
- /*
- ** Go ahead an mark everything as being declared, to prevent an
- ** infinite loop thru the ScanText() function. At the same time,
- ** we decide which objects need a full declaration and mark them
- ** with the DP_Flag bit. We are only able to use DP_Flag in this
- ** way because we know we'll never execute this far into this
- ** function on a recursive call with the same pDecl. Hence, recursive
- ** calls to this function (through ScanText()) can never change the
- ** value of DP_Flag out from under us.
- */
- for(p=pDecl; p; p=p->pSameName){
- if( !DeclHasProperty(p,DP_Declared)
- && (p->zFwd==0 || needFullDecl)
- && p->zDecl!=0
- ){
- DeclSetProperty(p,DP_Forward|DP_Declared|DP_Flag);
- }else{
- DeclClearProperty(p,DP_Flag);
- }
- }
-
- /*
- ** Call ScanText() recursively (this routine is called from ScanText())
- ** to include declarations required to come before these declarations.
- */
- for(p=pDecl; p; p=p->pSameName){
- if( DeclHasProperty(p,DP_Flag) ){
- if( p->zDecl[0]=='#' ){
- ScanText(&p->zDecl[1],pState);
- }else{
- InsertExtraDecl(p);
- ScanText(p->zDecl,pState);
- }
- }
- }
-
- /*
- ** Output the declarations. Do this in two passes. First
- ** output everything that isn't a typedef. Then go back and
- ** get the typedefs by the same name.
- */
- for(p=pDecl; p; p=p->pSameName){
- if( DeclHasProperty(p,DP_Flag) && !DeclHasProperty(p,TY_Typedef) ){
- if( DeclHasAnyProperty(p,TY_Enumeration) ){
- if( doneTypedef ) continue;
- doneTypedef = 1;
- }
- ChangeIfContext(p->zIf,pState);
- if( !isCpp && DeclHasAnyProperty(p,DP_ExternReqd) ){
- StringAppend(pState->pStr,"extern ",0);
- }else if( isCpp && DeclHasProperty(p,DP_Cplusplus|DP_ExternReqd) ){
- StringAppend(pState->pStr,"extern ",0);
- }else if( isCpp && DeclHasAnyProperty(p,DP_ExternCReqd|DP_ExternReqd) ){
- StringAppend(pState->pStr,"extern \"C\" ",0);
- }
- InsertExtraDecl(p);
- StringAppend(pState->pStr,p->zDecl,0);
- if( !isCpp && DeclHasProperty(p,DP_Cplusplus) ){
- fprintf(stderr,
- "%s: C code ought not reference the C++ object \"%s\"\n",
- pState->zFilename, p->zName);
- pState->nErr++;
- }
- DeclClearProperty(p,DP_Flag);
- }
- }
- for(p=pDecl; p && !doneTypedef; p=p->pSameName){
- if( DeclHasProperty(p,DP_Flag) ){
- /* This has to be a typedef */
- doneTypedef = 1;
- ChangeIfContext(p->zIf,pState);
- InsertExtraDecl(p);
- StringAppend(pState->pStr,p->zDecl,0);
- }
- }
-}
-
-/*
-** This routine scans the input text given, and appends to the
-** string in pState->pStr the text of any declarations that must
-** occur before the text in zText.
-**
-** If an identifier in zText is immediately followed by '*', then
-** only forward declarations are needed for that identifier. If the
-** identifier name is not followed immediately by '*', we must supply
-** a full declaration.
-*/
-static void ScanText(
- const char *zText, /* The input text to be scanned */
- GenState *pState /* Current state of the code generator */
-){
- int nextValid = 0; /* True is sNext contains valid data */
- InStream sIn; /* The input text */
- Token sToken; /* The current token being examined */
- Token sNext; /* The next non-space token */
-
- /* printf("BEGIN SCAN TEXT on %s\n", zText); */
-
- sIn.z = zText;
- sIn.i = 0;
- sIn.nLine = 1;
- while( sIn.z[sIn.i]!=0 ){
- if( nextValid ){
- sToken = sNext;
- nextValid = 0;
- }else{
- GetNonspaceToken(&sIn,&sToken);
- }
- if( sToken.eType==TT_Id ){
- int needFullDecl; /* True if we need to provide the full declaration,
- ** not just the forward declaration */
- Decl *pDecl; /* The declaration having the name in sToken */
-
- /*
- ** See if there is a declaration in the database with the name given
- ** by sToken.
- */
- pDecl = FindDecl(sToken.zText,sToken.nText);
- if( pDecl==0 ) continue;
-
- /*
- ** If we get this far, we've found an identifier that has a
- ** declaration in the database. Now see if we the full declaration
- ** or just a forward declaration.
- */
- GetNonspaceToken(&sIn,&sNext);
- if( sNext.zText[0]=='*' ){
- needFullDecl = 0;
- }else{
- needFullDecl = 1;
- nextValid = sNext.eType==TT_Id;
- }
-
- /*
- ** Generate the needed declaration.
- */
- DeclareObject(pDecl,pState,needFullDecl);
- }else if( sToken.eType==TT_Preprocessor ){
- sIn.i -= sToken.nText - 1;
- }
- }
- /* printf("END SCANTEXT\n"); */
-}
-
-/*
-** Provide a full declaration to any object which so far has had only
-** a forward declaration.
-*/
-static void CompleteForwardDeclarations(GenState *pState){
- Decl *pDecl;
- int progress;
-
- do{
- progress = 0;
- for(pDecl=pDeclFirst; pDecl; pDecl=pDecl->pNext){
- if( DeclHasProperty(pDecl,DP_Forward)
- && !DeclHasProperty(pDecl,DP_Declared)
- ){
- DeclareObject(pDecl,pState,1);
- progress = 1;
- assert( DeclHasProperty(pDecl,DP_Declared) );
- }
- }
- }while( progress );
-}
-
-/*
-** Generate an include file for the given source file. Return the number
-** of errors encountered.
-**
-** if nolocal_flag is true, then we do not generate declarations for
-** objected marked DP_Local.
-*/
-static int MakeHeader(InFile *pFile, FILE *report, int nolocal_flag){
- int nErr = 0;
- GenState sState;
- String outStr;
- IdentTable includeTable;
- Ident *pId;
- char *zNewVersion;
- char *zOldVersion;
-
- if( pFile->zHdr==0 || *pFile->zHdr==0 ) return 0;
- sState.pStr = &outStr;
- StringInit(&outStr);
- StringAppend(&outStr,zTopLine,nTopLine);
- sState.pTable = &includeTable;
- memset(&includeTable,0,sizeof(includeTable));
- sState.zIf = 0;
- sState.nErr = 0;
- sState.zFilename = pFile->zSrc;
- sState.flags = pFile->flags & DP_Cplusplus;
- ResetDeclFlags(nolocal_flag ? "no" : pFile->zSrc);
- for(pId = pFile->idTable.pList; pId; pId=pId->pNext){
- Decl *pDecl = FindDecl(pId->zName,0);
- if( pDecl ){
- DeclareObject(pDecl,&sState,1);
- }
- }
- CompleteForwardDeclarations(&sState);
- ChangeIfContext(0,&sState);
- nErr += sState.nErr;
- zOldVersion = ReadFile(pFile->zHdr);
- zNewVersion = StringGet(&outStr);
- if( report ) fprintf(report,"%s: ",pFile->zHdr);
- if( zOldVersion==0 ){
- if( report ) fprintf(report,"updated\n");
- if( WriteFile(pFile->zHdr,zNewVersion) ){
- fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr);
- nErr++;
- }
- }else if( strncmp(zOldVersion,zTopLine,nTopLine)!=0 ){
- if( report ) fprintf(report,"error!\n");
- fprintf(stderr,
- "%s: Can't overwrite this file because it wasn't previously\n"
- "%*s generated by 'makeheaders'.\n",
- pFile->zHdr, (int)strlen(pFile->zHdr), "");
- nErr++;
- }else if( strcmp(zOldVersion,zNewVersion)!=0 ){
- if( report ) fprintf(report,"updated\n");
- if( WriteFile(pFile->zHdr,zNewVersion) ){
- fprintf(stderr,"%s: Can't write to file\n",pFile->zHdr);
- nErr++;
- }
- }else if( report ){
- fprintf(report,"unchanged\n");
- }
- SafeFree(zOldVersion);
- IdentTableReset(&includeTable);
- StringReset(&outStr);
- return nErr;
-}
-
-/*
-** Generate a global header file -- a header file that contains all
-** declarations. If the forExport flag is true, then only those
-** objects that are exported are included in the header file.
-*/
-static int MakeGlobalHeader(int forExport){
- GenState sState;
- String outStr;
- IdentTable includeTable;
- Decl *pDecl;
-
- sState.pStr = &outStr;
- StringInit(&outStr);
- /* StringAppend(&outStr,zTopLine,nTopLine); */
- sState.pTable = &includeTable;
- memset(&includeTable,0,sizeof(includeTable));
- sState.zIf = 0;
- sState.nErr = 0;
- sState.zFilename = "(all)";
- sState.flags = 0;
- ResetDeclFlags(0);
- for(pDecl=pDeclFirst; pDecl; pDecl=pDecl->pNext){
- if( forExport==0 || DeclHasProperty(pDecl,DP_Export) ){
- DeclareObject(pDecl,&sState,1);
- }
- }
- ChangeIfContext(0,&sState);
- printf("%s",StringGet(&outStr));
- IdentTableReset(&includeTable);
- StringReset(&outStr);
- return 0;
-}
-
-#ifdef DEBUG
-/*
-** Return the number of characters in the given string prior to the
-** first newline.
-*/
-static int ClipTrailingNewline(char *z){
- int n = strlen(z);
- while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ){ n--; }
- return n;
-}
-
-/*
-** Dump the entire declaration list for debugging purposes
-*/
-static void DumpDeclList(void){
- Decl *pDecl;
-
- for(pDecl = pDeclFirst; pDecl; pDecl=pDecl->pNext){
- printf("**** %s from file %s ****\n",pDecl->zName,pDecl->zFile);
- if( pDecl->zIf ){
- printf("If: [%.*s]\n",ClipTrailingNewline(pDecl->zIf),pDecl->zIf);
- }
- if( pDecl->zFwd ){
- printf("Decl: [%.*s]\n",ClipTrailingNewline(pDecl->zFwd),pDecl->zFwd);
- }
- if( pDecl->zDecl ){
- InsertExtraDecl(pDecl);
- printf("Def: [%.*s]\n",ClipTrailingNewline(pDecl->zDecl),pDecl->zDecl);
- }
- if( pDecl->flags ){
- static struct {
- int mask;
- char *desc;
- } flagSet[] = {
- { TY_Class, "class" },
- { TY_Enumeration, "enum" },
- { TY_Structure, "struct" },
- { TY_Union, "union" },
- { TY_Variable, "variable" },
- { TY_Subroutine, "function" },
- { TY_Typedef, "typedef" },
- { TY_Macro, "macro" },
- { DP_Export, "export" },
- { DP_Local, "local" },
- { DP_Cplusplus, "C++" },
- };
- int i;
- printf("flags:");
- for(i=0; i<sizeof(flagSet)/sizeof(flagSet[0]); i++){
- if( flagSet[i].mask & pDecl->flags ){
- printf(" %s", flagSet[i].desc);
- }
- }
- printf("\n");
- }
- if( pDecl->pInclude ){
- Include *p;
- printf("includes:");
- for(p=pDecl->pInclude; p; p=p->pNext){
- printf(" %s",p->zFile);
- }
- printf("\n");
- }
- }
-}
-#endif
-
-/*
-** When the "-doc" command-line option is used, this routine is called
-** to print all of the database information to standard output.
-*/
-static void DocumentationDump(void){
- Decl *pDecl;
- static struct {
- int mask;
- char flag;
- } flagSet[] = {
- { TY_Class, 'c' },
- { TY_Enumeration, 'e' },
- { TY_Structure, 's' },
- { TY_Union, 'u' },
- { TY_Variable, 'v' },
- { TY_Subroutine, 'f' },
- { TY_Typedef, 't' },
- { TY_Macro, 'm' },
- { DP_Export, 'x' },
- { DP_Local, 'l' },
- { DP_Cplusplus, '+' },
- };
-
- for(pDecl = pDeclFirst; pDecl; pDecl=pDecl->pNext){
- int i;
- int nLabel = 0;
- char *zDecl;
- char zLabel[50];
- for(i=0; i<sizeof(flagSet)/sizeof(flagSet[0]); i++){
- if( DeclHasProperty(pDecl,flagSet[i].mask) ){
- zLabel[nLabel++] = flagSet[i].flag;
- }
- }
- if( nLabel==0 ) continue;
- zLabel[nLabel] = 0;
- InsertExtraDecl(pDecl);
- zDecl = pDecl->zDecl;
- if( zDecl==0 ) zDecl = pDecl->zFwd;
- printf("%s %s %s %p %d %d %d %d %d\n",
- pDecl->zName,
- zLabel,
- pDecl->zFile,
- pDecl->pComment,
- pDecl->pComment ? pDecl->pComment->nText+1 : 0,
- pDecl->zIf ? (int)strlen(pDecl->zIf)+1 : 0,
- zDecl ? (int)strlen(zDecl) : 0,
- pDecl->pComment ? pDecl->pComment->nLine : 0,
- pDecl->tokenCode.nText ? pDecl->tokenCode.nText+1 : 0
- );
- if( pDecl->pComment ){
- printf("%.*s\n",pDecl->pComment->nText, pDecl->pComment->zText);
- }
- if( pDecl->zIf ){
- printf("%s\n",pDecl->zIf);
- }
- if( zDecl ){
- printf("%s",zDecl);
- }
- if( pDecl->tokenCode.nText ){
- printf("%.*s\n",pDecl->tokenCode.nText, pDecl->tokenCode.zText);
- }
- }
-}
-
-/*
-** Given the complete text of an input file, this routine prints a
-** documentation record for the header comment at the beginning of the
-** file (if the file has a header comment.)
-*/
-void PrintModuleRecord(const char *zFile, const char *zFilename){
- int i;
- static int addr = 5;
- while( isspace(*zFile) ){ zFile++; }
- if( *zFile!='/' || zFile[1]!='*' ) return;
- for(i=2; zFile[i] && (zFile[i-1]!='/' || zFile[i-2]!='*'); i++){}
- if( zFile[i]==0 ) return;
- printf("%s M %s %d %d 0 0 0 0\n%.*s\n",
- zFilename, zFilename, addr, i+1, i, zFile);
- addr += 4;
-}
-
-
-/*
-** Given an input argument to the program, construct a new InFile
-** object.
-*/
-static InFile *CreateInFile(char *zArg, int *pnErr){
- int nSrc;
- char *zSrc;
- InFile *pFile;
- int i;
-
- /*
- ** Get the name of the input file to be scanned. The input file is
- ** everything before the first ':' or the whole file if no ':' is seen.
- **
- ** Except, on windows, ignore any ':' that occurs as the second character
- ** since it might be part of the drive specifier. So really, the ":' has
- ** to be the 3rd or later character in the name. This precludes 1-character
- ** file names, which really should not be a problem.
- */
- zSrc = zArg;
- for(nSrc=2; zSrc[nSrc] && zArg[nSrc]!=':'; nSrc++){}
- pFile = SafeMalloc( sizeof(InFile) );
- memset(pFile,0,sizeof(InFile));
- pFile->zSrc = StrDup(zSrc,nSrc);
-
- /* Figure out if we are dealing with C or C++ code. Assume any
- ** file with ".c" or ".h" is C code and all else is C++.
- */
- if( nSrc>2 && zSrc[nSrc-2]=='.' && (zSrc[nSrc-1]=='c' || zSrc[nSrc-1]=='h')){
- pFile->flags &= ~DP_Cplusplus;
- }else{
- pFile->flags |= DP_Cplusplus;
- }
-
- /*
- ** If a separate header file is specified, use it
- */
- if( zSrc[nSrc]==':' ){
- int nHdr;
- char *zHdr;
- zHdr = &zSrc[nSrc+1];
- for(nHdr=0; zHdr[nHdr]; nHdr++){}
- pFile->zHdr = StrDup(zHdr,nHdr);
- }
-
- /* Look for any 'c' or 'C' in the suffix of the file name and change
- ** that character to 'h' or 'H' respectively. If no 'c' or 'C' is found,
- ** then assume we are dealing with a header.
- */
- else{
- int foundC = 0;
- pFile->zHdr = StrDup(zSrc,nSrc);
- for(i = nSrc-1; i>0 && pFile->zHdr[i]!='.'; i--){
- if( pFile->zHdr[i]=='c' ){
- foundC = 1;
- pFile->zHdr[i] = 'h';
- }else if( pFile->zHdr[i]=='C' ){
- foundC = 1;
- pFile->zHdr[i] = 'H';
- }
- }
- if( !foundC ){
- SafeFree(pFile->zHdr);
- pFile->zHdr = 0;
- }
- }
-
- /*
- ** If pFile->zSrc contains no 'c' or 'C' in its extension, it
- ** must be a header file. In that case, we need to set the
- ** PS_Interface flag.
- */
- pFile->flags |= PS_Interface;
- for(i=nSrc-1; i>0 && zSrc[i]!='.'; i--){
- if( zSrc[i]=='c' || zSrc[i]=='C' ){
- pFile->flags &= ~PS_Interface;
- break;
- }
- }
-
- /* Done!
- */
- return pFile;
-}
-
-/* MS-Windows and MS-DOS both have the following serious OS bug: the
-** length of a command line is severely restricted. But this program
-** occasionally requires long command lines. Hence the following
-** work around.
-**
-** If the parameters "-f FILENAME" appear anywhere on the command line,
-** then the named file is scanned for additional command line arguments.
-** These arguments are substituted in place of the "FILENAME" argument
-** in the original argument list.
-**
-** This first parameter to this routine is the index of the "-f"
-** parameter in the argv[] array. The argc and argv are passed by
-** pointer so that they can be changed.
-**
-** Parsing of the parameters in the file is very simple. Parameters
-** can be separated by any amount of white-space (including newlines
-** and carriage returns.) There are now quoting characters of any
-** kind. The length of a token is limited to about 1000 characters.
-*/
-static void AddParameters(int index, int *pArgc, char ***pArgv){
- int argc = *pArgc; /* The original argc value */
- char **argv = *pArgv; /* The original argv value */
- int newArgc; /* Value for argc after inserting new arguments */
- char **zNew = 0; /* The new argv after this routine is done */
- char *zFile; /* Name of the input file */
- int nNew = 0; /* Number of new entries in the argv[] file */
- int nAlloc = 0; /* Space allocated for zNew[] */
- int i; /* Loop counter */
- int n; /* Number of characters in a new argument */
- int c; /* Next character of input */
- int startOfLine = 1; /* True if we are where '#' can start a comment */
- FILE *in; /* The input file */
- char zBuf[1000]; /* A single argument is accumulated here */
-
- if( index+1==argc ) return;
- zFile = argv[index+1];
- in = fopen(zFile,"r");
- if( in==0 ){
- fprintf(stderr,"Can't open input file \"%s\"\n",zFile);
- exit(1);
- }
- c = ' ';
- while( c!=EOF ){
- while( c!=EOF && isspace(c) ){
- if( c=='\n' ){
- startOfLine = 1;
- }
- c = getc(in);
- if( startOfLine && c=='#' ){
- while( c!=EOF && c!='\n' ){
- c = getc(in);
- }
- }
- }
- n = 0;
- while( c!=EOF && !isspace(c) ){
- if( n<sizeof(zBuf)-1 ){ zBuf[n++] = c; }
- startOfLine = 0;
- c = getc(in);
- }
- zBuf[n] = 0;
- if( n>0 ){
- nNew++;
- if( nNew + argc > nAlloc ){
- if( nAlloc==0 ){
- nAlloc = 100 + argc;
- zNew = malloc( sizeof(char*) * nAlloc );
- }else{
- nAlloc *= 2;
- zNew = realloc( zNew, sizeof(char*) * nAlloc );
- }
- }
- if( zNew ){
- int j = nNew + index;
- zNew[j] = malloc( n + 1 );
- if( zNew[j] ){
- strcpy( zNew[j], zBuf );
- }
- }
- }
- }
- newArgc = argc + nNew - 1;
- for(i=0; i<=index; i++){
- zNew[i] = argv[i];
- }
- for(i=nNew + index + 1; i<newArgc; i++){
- zNew[i] = argv[i + 1 - nNew];
- }
- zNew[newArgc] = 0;
- *pArgc = newArgc;
- *pArgv = zNew;
-}
-
-#ifdef NOT_USED
-/*
-** Return the time that the given file was last modified. If we can't
-** locate the file (because, for example, it doesn't exist), then
-** return 0.
-*/
-static unsigned int ModTime(const char *zFilename){
- unsigned int mTime = 0;
- struct stat sStat;
- if( stat(zFilename,&sStat)==0 ){
- mTime = sStat.st_mtime;
- }
- return mTime;
-}
-#endif
-
-/*
-** Print a usage comment for this program.
-*/
-static void Usage(const char *argv0, const char *argvN){
- fprintf(stderr,"%s: Illegal argument \"%s\"\n",argv0,argvN);
- fprintf(stderr,"Usage: %s [options] filename...\n"
- "Options:\n"
- " -h Generate a single .h to standard output.\n"
- " -H Like -h, but only output EXPORT declarations.\n"
- " -v (verbose) Write status information to the screen.\n"
- " -doc Generate no header files. Instead, output information\n"
- " that can be used by an automatic program documentation\n"
- " and cross-reference generator.\n"
- " -local Generate prototypes for \"static\" functions and\n"
- " procedures.\n"
- " -f FILE Read additional command-line arguments from the file named\n"
- " \"FILE\".\n"
-#ifdef DEBUG
- " -! MASK Set the debugging mask to the number \"MASK\".\n"
-#endif
- " -- Treat all subsequent comment-line parameters as filenames,\n"
- " even if they begin with \"-\".\n",
- argv0
- );
-}
-
-/*
-** The following text contains a few simple #defines that we want
-** to be available to every file.
-*/
-static const char zInit[] =
- "#define INTERFACE 0\n"
- "#define EXPORT_INTERFACE 0\n"
- "#define LOCAL_INTERFACE 0\n"
- "#define EXPORT\n"
- "#define LOCAL static\n"
- "#define PUBLIC\n"
- "#define PRIVATE\n"
- "#define PROTECTED\n"
-;
-
-#if TEST==0
-int main(int argc, char **argv){
- int i; /* Loop counter */
- int nErr = 0; /* Number of errors encountered */
- Token *pList; /* List of input tokens for one file */
- InFile *pFileList = 0;/* List of all input files */
- InFile *pTail = 0; /* Last file on the list */
- InFile *pFile; /* for looping over the file list */
- int h_flag = 0; /* True if -h is present. Output unified header */
- int H_flag = 0; /* True if -H is present. Output EXPORT header */
- int v_flag = 0; /* Verbose */
- int noMoreFlags; /* True if -- has been seen. */
- FILE *report; /* Send progress reports to this, if not NULL */
-
- noMoreFlags = 0;
- for(i=1; i<argc; i++){
- if( argv[i][0]=='-' && !noMoreFlags ){
- switch( argv[i][1] ){
- case 'h': h_flag = 1; break;
- case 'H': H_flag = 1; break;
- case 'v': v_flag = 1; break;
- case 'd': doc_flag = 1; proto_static = 1; break;
- case 'l': proto_static = 1; break;
- case 'f': AddParameters(i, &argc, &argv); break;
- case '-': noMoreFlags = 1; break;
-#ifdef DEBUG
- case '!': i++; debugMask = strtol(argv[i],0,0); break;
-#endif
- default: Usage(argv[0],argv[i]); return 1;
- }
- }else{
- pFile = CreateInFile(argv[i],&nErr);
- if( pFile ){
- if( pFileList ){
- pTail->pNext = pFile;
- pTail = pFile;
- }else{
- pFileList = pTail = pFile;
- }
- }
- }
- }
- if( h_flag && H_flag ){
- h_flag = 0;
- }
- if( v_flag ){
- report = (h_flag || H_flag) ? stderr : stdout;
- }else{
- report = 0;
- }
- if( nErr>0 ){
- return nErr;
- }
- for(pFile=pFileList; pFile; pFile=pFile->pNext){
- char *zFile;
-
- zFilename = pFile->zSrc;
- if( zFilename==0 ) continue;
- zFile = ReadFile(zFilename);
- if( zFile==0 ){
- fprintf(stderr,"Can't read input file \"%s\"\n",zFilename);
- nErr++;
- continue;
- }
- if( strncmp(zFile,zTopLine,nTopLine)==0 ){
- pFile->zSrc = 0;
- }else{
- if( report ) fprintf(report,"Reading %s...\n",zFilename);
- pList = TokenizeFile(zFile,&pFile->idTable);
- if( pList ){
- nErr += ParseFile(pList,pFile->flags);
- FreeTokenList(pList);
- }else if( zFile[0]==0 ){
- fprintf(stderr,"Input file \"%s\" is empty.\n", zFilename);
- nErr++;
- }else{
- fprintf(stderr,"Errors while processing \"%s\"\n", zFilename);
- nErr++;
- }
- }
- if( !doc_flag ) SafeFree(zFile);
- if( doc_flag ) PrintModuleRecord(zFile,zFilename);
- }
- if( nErr>0 ){
- return nErr;
- }
-#ifdef DEBUG
- if( debugMask & DECL_DUMP ){
- DumpDeclList();
- return nErr;
- }
-#endif
- if( doc_flag ){
- DocumentationDump();
- return nErr;
- }
- zFilename = "--internal--";
- pList = TokenizeFile(zInit,0);
- if( pList==0 ){
- return nErr+1;
- }
- ParseFile(pList,PS_Interface);
- FreeTokenList(pList);
- if( h_flag || H_flag ){
- nErr += MakeGlobalHeader(H_flag);
- }else{
- for(pFile=pFileList; pFile; pFile=pFile->pNext){
- if( pFile->zSrc==0 ) continue;
- nErr += MakeHeader(pFile,report,0);
- }
- }
- return nErr;
-}
-#endif
-
-
-
-
-
-
-
-
-
-
diff --git a/try/SUDO_USER_1.sh b/try/SUDO_USER_1.sh
deleted file mode 100755
index 9a988ed..0000000
--- a/try/SUDO_USER_1.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/bash
-#
-
-echo "The SUDO USER is: " $SUDO_USER
-
-
-
-
diff --git a/try/libuser b/try/libuser
deleted file mode 100755
index c936654..0000000
--- a/try/libuser
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/python
-
-import libuser
-import os
-import time
-
-print("--------- Initializing.")
-admin = libuser.admin()
-
-print("--------- Listing.")
-for item in sorted(admin.enumerateUsers("l*")):
- print("Found a user named \"" + item + "\".")
-
-print("--------- Lookup.")
-ldap = admin.lookupUserByName("ldap")
-
-print("--------- Reading attribute (get).")
-print(ldap.get(libuser.LOGINSHELL))
-print("--------- Reading attribute (map).")
-print(ldap[libuser.LOGINSHELL])
-print("--------- Reading keys.")
-print(list(ldap.keys()))
-
-print("--------- Setting attribute.")
-ldap.set(libuser.LOGINSHELL, ["/bin/true"])
-ldap[libuser.LOGINSHELL] = "/bin/true"
-ldap[libuser.LOGINSHELL] = ["/bin/true"]
-
-print("--------- Reading attribute (get).")
-print(ldap.get(libuser.LOGINSHELL))
-print("--------- Reading attribute (map).")
-print(ldap[libuser.LOGINSHELL])
-
-print("--------- Getting directory list.")
-dir(ldap)
-
-print("--------- Modifying user.")
-admin.modifyUser(ldap)
-
-print("--------- Enumerating members of the wheel group.")
-print(admin.enumerateUsersByGroup("wheel"))
-
-print("--------- Looking up the wheel group.")
-wheel = admin.lookupGroupByName("wheel")
-
-print("--------- Reading attribute (memberUid).")
-print(wheel[libuser.MEMBERNAME])
-
-print("--------- Creating a new user (jimbo).")
-jimbo = admin.initUser("jimbo")
-for attr in jimbo.keys():
- print(" " + attr + ":", jimbo.get(attr))
-
-print("--------- Adding the user.")
-jimbo[libuser.HOMEDIRECTORY] = '/var/jimbo-home'
-print("Set home directory to " + jimbo[libuser.HOMEDIRECTORY][0])
-admin.addUser(jimbo)
-
-print("--------- Grepping for the user.")
-os.system("grep jimbo /etc/passwd /etc/group /etc/shadow /etc/gshadow")
-
-try:
- dir = jimbo.get(libuser.HOMEDIRECTORY)
- print("--------- Looking at user's directory.")
- os.system("ls " + dir[0])
- print("--------- Looking at mail spool directory.")
- os.system("ls -l /var/mail/*")
-except:
- pass
-
-print("--------- Removing the user.")
-admin.deleteUser(jimbo)
-admin.removeHome(jimbo)
-admin.removeMail(jimbo)
-print("--------- Grepping for the user.")
-os.system("grep jimbo /etc/passwd /etc/group /etc/shadow /etc/gshadow")
-
-print("--------- Getting a list of all users.")
-users = admin.enumerateUsersFull()
-for user in users:
- print(" User `" + user[libuser.USERNAME][0] + "' has uid ", user[libuser.UIDNUMBER][0])
diff --git a/try/mh_main_prob/command1.c b/try/mh_main_prob/command1.c
deleted file mode 100644
index 637df55..0000000
--- a/try/mh_main_prob/command1.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "command1.h"
-#include
-int main(int argc, char **argv){
- printf("command1 %d\n", f());
- return 0;
-}
diff --git a/try/mh_main_prob/command2.c b/try/mh_main_prob/command2.c
deleted file mode 100644
index 5d8c612..0000000
--- a/try/mh_main_prob/command2.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "command2.h"
-#include
-int main(int argc, char **argv){
- printf("command2 %d\n", f() + argc);
- return 0;
-}
diff --git a/try/mh_main_prob/just_fun.c b/try/mh_main_prob/just_fun.c
deleted file mode 100644
index 67625f4..0000000
--- a/try/mh_main_prob/just_fun.c
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "just_fun.h"
-int f(){
- return 5;
-}
diff --git a/try/mh_main_prob/transcript1.txt b/try/mh_main_prob/transcript1.txt
deleted file mode 100644
index c5511fe..0000000
--- a/try/mh_main_prob/transcript1.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Various commmand files each with its own main for testing a library. makeheaders gets confused and puts all the
-declarations in the headers, leading to a failure.
-
-
-> ls
-command1.c command2.c just_fun.c
-> cat just_fun.c
-#include "just_fun.h"
-int f(){
- return 5;
-}
-> cat command1.c
-#include "command1.h"
-#include
-int main(){
- printf("command1 %d\n", f());
- return 0;
-}
-> cat command2.c
-#include "command2.h"
-#include
-int main(int argc, char **argv){
- printf("command2 %d\n", f() + argc);
- return 0;
-}
-> makeheaders *.c
-> gcc -o command1 command1.c
-command1.c: In function âmainâ:
-command1.c:3:1: error: number of arguments doesnât match prototype
- int main(){
- ^~~
-In file included from command1.c:1:
-command1.h:5:5: error: prototype declaration
- int main(int argc,char **argv);
- ^~~~
->
diff --git a/try/mh_main_prob/transcript2.txt b/try/mh_main_prob/transcript2.txt
deleted file mode 100644
index 77ec819..0000000
--- a/try/mh_main_prob/transcript2.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Making each main call static so it won't be in the header. gcc can't find main.
-
-> cat command1.c
-#include "command1.h"
-#include
-static int main(){
- printf("command1 %d\n", f());
- return 0;
-}
-> cat command2.c
-#include "command2.h"
-#include
-static int main(int argc, char **argv){
- printf("command2 %d\n", f() + argc);
- return 0;
-}
-> gcc -o command1 command1.c just_fun.c
-/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/8/../../../../lib64/crt1.o: in function `_start':
-(.text+0x24): undefined reference to `main'
-collect2: error: ld returned 1 exit status
diff --git a/try/mh_main_prob/transcript3.txt b/try/mh_main_prob/transcript3.txt
deleted file mode 100644
index b3a00b7..0000000
--- a/try/mh_main_prob/transcript3.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-This time making each main definition have the same prototype. Still end up with multiple main declarations,
-it is just that they agree.
-
-> rm *.h
-> makeheaders *.c
-> cat command1.c
-#include "command1.h"
-#include
-int main(int argc, char **argv){
- printf("command1 %d\n", f());
- return 0;
-}
-> cat command1.h
-/* This file was automatically generated. Do not edit! */
-#undef INTERFACE
-int f();
-int main(int argc,char **argv);
-int main(int argc,char **argv);
-> cat command2.c
-#include "command2.h"
-#include
-int main(int argc, char **argv){
- printf("command2 %d\n", f() + argc);
- return 0;
-}
-> gcc -o command1 command1.c just_fun.c
-> .. worked
diff --git a/try/phony_general_targets_fail/makefile b/try/phony_general_targets_fail/makefile
deleted file mode 100644
index 07604b4..0000000
--- a/try/phony_general_targets_fail/makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-.PHONY: lib version
-
-version:
- @echo "version 0.1"
-
-%::
- @echo $@
-
-
diff --git a/try/phony_general_targets_fail/transcript.txt b/try/phony_general_targets_fail/transcript.txt
deleted file mode 100644
index 47589ed..0000000
--- a/try/phony_general_targets_fail/transcript.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-GNU Make 4.2.1
-Built for x86_64-redhat-linux-gnu
-Copyright (C) 1988-2016 Free Software Foundation, Inc.
-License GPLv3+: GNU GPL version 3 or later
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law.
-
-2019-04-02T10:48:22Z
-user@host§~/subu_land/subu/try/phony_general_targets§
-> cat makefile
-
-
-.PHONY: lib version
-
-version:
- @echo "version 0.1"
-
-%::
- @echo $@
-
-
-
-2019-04-02T10:48:27Z
-user@host§~/subu_land/subu/try/phony_general_targets§
-> mkdir version lib
-
-2019-04-02T10:48:38Z
-user@host§~/subu_land/subu/try/phony_general_targets§
-> ls
-lib makefile version
-
-2019-04-02T10:48:42Z
-user@host§~/subu_land/subu/try/phony_general_targets§
-> make version
-version 0.1
-
-2019-04-02T10:48:50Z
-user@host§~/subu_land/subu/try/phony_general_targets§
-> make code
-code
-
-2019-04-02T10:48:57Z
-user@host§~/subu_land/subu/try/phony_general_targets§
-> make lib
-make: Nothing to be done for 'lib'.
-
-2019-04-02T10:49:00Z
-user@host§~/subu_land/subu/try/phony_general_targets§
->
diff --git a/try/print_env.py b/try/print_env.py
deleted file mode 100755
index 87ebd37..0000000
--- a/try/print_env.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python
-
-import getpass
-import os
-
-username = getpass.getuser()
-print "my username is: " + username
-
-sudo_caller_username = os.environ.get('SUDO_USER')
-if sudo_caller_username:
- print "the sudo caller's username is: " + sudo_caller_username
-else:
- print "there is no sudo caller"
-
-print "uid: " + str(os.getuid())
-print "euid: " + str(os.geteuid())
-print "resuid: " + str(os.getresuid())
-
-null_lookup = os.environ.get('X3841232341')
-if null_lookup:
- print "very surprising, found X3841232341 in the environment"
-elif null_lookup == None:
- print "null lookup result: None"
-else:
- print "null lookup result evaluates to false, but it is not None"
-
-for k,v in os.environ.items():
- print (k, v)
-
-
diff --git a/try/print_id.sh b/try/print_id.sh
deleted file mode 100755
index 41d6b5b..0000000
--- a/try/print_id.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-#
-
-echo "real id: " $(id -u)
-echo "effective id: " $(id -r -u)
diff --git a/try/real_id b/try/real_id
deleted file mode 100755
index e19be49..0000000
Binary files a/try/real_id and /dev/null differ
diff --git a/try/real_id.c b/try/real_id.c
deleted file mode 100644
index 2437336..0000000
--- a/try/real_id.c
+++ /dev/null
@@ -1,11 +0,0 @@
-
-#include
-#include
-#include
-
-int main(){
- int uid = getuid();
- int euid = geteuid();
- printf("real_id: %u effective_id: %u\n",uid,euid);
- return 0;
-}
diff --git a/try/real_id_suid_root b/try/real_id_suid_root
deleted file mode 100755
index e19be49..0000000
Binary files a/try/real_id_suid_root and /dev/null differ
diff --git a/try/set_SUDO_USER.sh b/try/set_SUDO_USER.sh
deleted file mode 100755
index 713d24d..0000000
--- a/try/set_SUDO_USER.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/bash
-#
-# Shows that a regular user can set environment variables with the same names as
-# sudo does. Hence it is possible to confuse a script that relies upon the sudo
-# variables.
-#
-
-export SUDO_USER=jones
-./SUDO_USER_1.sh
-
-
-
diff --git a/try/sss_cache_probs/dbprintf.aux.c b/try/sss_cache_probs/dbprintf.aux.c
deleted file mode 100644
index edea747..0000000
--- a/try/sss_cache_probs/dbprintf.aux.c
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#include
-#include
-#include "dbprintf.aux.h"
-
-int dbprintf(const char *format, ...){
- va_list args;
- va_start(args,format);
- int ret = vfprintf(stdout, format, args);
- fflush(stdout);
- va_end(args);
- return ret;
-}
diff --git a/try/sss_cache_probs/dbprintf.aux.h b/try/sss_cache_probs/dbprintf.aux.h
deleted file mode 100644
index 967fdae..0000000
--- a/try/sss_cache_probs/dbprintf.aux.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef DBPRINTF_AUX_H
-#define DBPRINTF_AUX_H
-
-int dbprintf(const char *format, ...);
-
-#endif
diff --git a/try/sss_cache_probs/dispatch.lib.c b/try/sss_cache_probs/dispatch.lib.c
deleted file mode 100644
index fcad514..0000000
--- a/try/sss_cache_probs/dispatch.lib.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-fork/exec/wait a command
-
-if the error values returned by the exec'd program
-are less than 1 << 16, then
-
-*/
-
-// without this #define execvpe is undefined
-#define _GNU_SOURCE
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include "local_common.h"
-#include "dispatch.lib.h"
-
-
-
-/*
- Execs the command passed in argv[0];
- Returns -1 upon failure.
-
- The wstatus returned from wait() might be either the error we returned when
- exec failed, or the return value from the command. An arbitary command is
- passed in, so we don't know what its return values might be. Consquently, we
- have no way of multiplexing a unique exec error code with the command return
- value within wstatus. If the prorgrammer knows the return values of the command
- passed in, and wants better behavior, he or she can spin a special version of
- dispatch for that command.
-*/
-int dispatch(char **argv, char **envp){
- if( !argv || !argv[0] ){
- fprintf(stderr, "argv[0] null. Null command passed into dispatch().\n");
- return -1;
- }
- #ifdef DEBUG
- dbprintf("dispatching:\n");
- char **arg = argv;
- while( *arg ){
- dbprintf("arg: %p", arg);
- dbprintf(" %s\n",*arg);
- arg++;
- }
- dbprintf("\n");
- #endif
- char *command = argv[0];
- pid_t pid = fork();
- if( pid == -1 ){
- fprintf(stderr, "fork() failed in dispatch().\n");
- return -1;
- }
- if( pid == 0 ){ // we are the child
- execvpe(command, argv, envp);
- // exec will only return if it has an error ..
- perror(command);
- return -1;
- }else{ // we are the parent
- int wstatus;
- waitpid(pid, &wstatus, 0);
- if(wstatus)
- return -1;
- else
- return 0;
- }
-}
diff --git a/try/sss_cache_probs/dispatch.lib.h b/try/sss_cache_probs/dispatch.lib.h
deleted file mode 100644
index 620c6f9..0000000
--- a/try/sss_cache_probs/dispatch.lib.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef DISPATCH_LIB_H
-#define DISPATCH_LIB_H
-#include "local_common.h"
-
-int dispatch(char **argv, char **envp);
-
-#endif
-
-
diff --git a/try/sss_cache_probs/example.txt b/try/sss_cache_probs/example.txt
deleted file mode 100644
index d40b0be..0000000
--- a/try/sss_cache_probs/example.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-> ./sss_cache
-Checking we are running from a user and are setuid root.
-uid 49972, gid 49972, euid 0 egid 49972
-yes, uid is not zero, and euid is zero, so we are setuid to the root user.
-dispatching sss_cache -U to clear users
-dispatching:
-arg: 0x7ffdbebdf6f0 /usr/sbin/sss_cache
-arg: 0x7ffdbebdf6f8 -U
-
-/usr/sbin/sss_cache must be run as root
-sss_cache failed
-
diff --git a/try/sss_cache_probs/local_common.h b/try/sss_cache_probs/local_common.h
deleted file mode 100644
index 4df5bcf..0000000
--- a/try/sss_cache_probs/local_common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef LOCAL_COMMON_H
-#define LOCAL_COMMON_H
-
-#include
-#include
-#include
-#include "dbprintf.aux.h"
-
-#define DEBUG
-typedef unsigned int uint;
-
-#endif
diff --git a/try/sss_cache_probs/makefile b/try/sss_cache_probs/makefile
deleted file mode 100644
index 233007a..0000000
--- a/try/sss_cache_probs/makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-
-src = $(wildcard *.c)
-obj = $(src:.c=.o)
-CC=gcc
-
-all: sss_cache
-
-sss_cache: $(obj)
- $(CC) -o $@ $^
-
-.PHONY: clean
-clean:
- rm -rf $(obj) sss_cache
-
-
-
-
diff --git a/try/sss_cache_probs/setuid_root.sh b/try/sss_cache_probs/setuid_root.sh
deleted file mode 100755
index 436fa79..0000000
--- a/try/sss_cache_probs/setuid_root.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-# type these things from a sudo prompt:
-#
-
-chown root sss_cache
-chmod u+rsx,u-w,go+rx-s-w sss_cache
-
-
diff --git a/try/sss_cache_probs/sss_cache.cli.c b/try/sss_cache_probs/sss_cache.cli.c
deleted file mode 100644
index 39fee15..0000000
--- a/try/sss_cache_probs/sss_cache.cli.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-
-*/
-
-#include
-#include "sss_cache.lib.h"
-
-int main(int argc, char **argv, char **env){
- char *command = argv[0];
- if( argc != 1 ){
- fprintf(stderr, "usage: %s", command);
- return 1;
- }
- return user_mk(argv[1]);
-}
diff --git a/try/sss_cache_probs/sss_cache.lib.c b/try/sss_cache_probs/sss_cache.lib.c
deleted file mode 100644
index 0db485a..0000000
--- a/try/sss_cache_probs/sss_cache.lib.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Makes a new subu user.
-
- According to the man page, we are not alloed to free the memory allocated by getpwid().
-
-
-setfacl -m d:u:masteru:rwX,u:masteru:rwX subuname
-
-*/
-// without this #define we get the warning: implicit declaration of function âseteuidâ/âsetegidâ
-#define _GNU_SOURCE
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "dispatch.lib.h"
-#include "sss_cache.lib.h"
-
-typedef unsigned int uint;
-
-int user_mk(char *username){
-
- //--------------------------------------------------------------------------------
- #ifdef DEBUG
- dbprintf("Checking we are running from a user and are setuid root.\n");
- #endif
- uid_t uid = getuid();
- uid_t euid = geteuid();
- gid_t gid = getgid();
- gid_t egid = getegid();
- #ifdef DEBUG
- dbprintf("uid %u, gid %u, euid %u egid %u\n", uid, gid, euid, egid);
- #endif
- if( uid == 0 || euid != 0 ){
- fprintf(stderr, "this program must be run setuid root from a user account\n");
- return -1;
- }
- #ifdef DEBUG
- dbprintf("yes, uid is not zero, and euid is zero, so we are setuid to the root user.\n");
- #endif
-
- /*--------------------------------------------------------------------------------
- */
- uid_t useruid;
- gid_t usergid;
- {
- #ifdef DEBUG
- dbprintf("dispatching sss_cache -U to clear users\n");
- #endif
- char *command = "/usr/sbin/sss_cache";
- char *argv[3];
- argv[0] = command;
- argv[1] = "-U";
- argv[2] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- int ret = dispatch(argv, envp);
- if(ret == -1){
- fprintf(stderr, "sss_cache failed\n");
- return -1;
- }
- }
-
- #ifdef DEBUG
- dbprintf("finished sss_cache without errors\n", username);
- #endif
- return 0;
-}
diff --git a/try/sss_cache_probs/sss_cache.lib.h b/try/sss_cache_probs/sss_cache.lib.h
deleted file mode 100644
index 11ab8ee..0000000
--- a/try/sss_cache_probs/sss_cache.lib.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef SUBU_MK_0_LIB_H
-#define SUBU_MK_0_LIB_H
-
-int user_mk(char *subuname);
-
-#endif
diff --git a/try/subu-mk-0.lib.c b/try/subu-mk-0.lib.c
deleted file mode 100644
index 46bce70..0000000
--- a/try/subu-mk-0.lib.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- Makes a new subu user.
-
- According to the man page, we are not alloed to free the memory allocated by getpwid().
-
-
-setfacl -m d:u:masteru:rwX,u:masteru:rwX subuname
-
-*/
-// without this #define we get the warning: implicit declaration of function âseteuidâ/âsetegidâ
-#define _GNU_SOURCE
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "dispatch.lib.h"
-#include "dispatch_useradd.lib.h"
-#include "subu-mk-0.lib.h"
-
-typedef unsigned int uint;
-
-int subu_mk_0(char *subuname){
-
- //--------------------------------------------------------------------------------
- #ifdef DEBUG
- dbprintf("Checking we are running from a user and are setuid root.\n");
- #endif
- uid_t uid = getuid();
- uid_t euid = geteuid();
- gid_t gid = getgid();
- gid_t egid = getegid();
- #ifdef DEBUG
- dbprintf("uid %u, gid %u, euid %u egid %u\n", uid, gid, euid, egid);
- #endif
- if( uid == 0 || euid != 0 ){
- fprintf(stderr, "this program must be run setuid root from a user account\n");
- return ERR_SETUID_ROOT;
- }
-
- //--------------------------------------------------------------------------------
- size_t subuname_len;
- char *masteru_name;
- size_t masteru_name_len;
- struct passwd *masteru_pw_record_pt;
- {
- #ifdef DEBUG
- dbprintf("looking up masteru_name (i.e. uid %u) in /etc/passwd\n",uid);
- #endif
- // subuname is the first argument passed in
- // verify that subuname is legal! --> code goes here ...
- subuname_len = strlen(subuname);
- masteru_pw_record_pt = getpwuid(uid);
- masteru_name = masteru_pw_record_pt->pw_name;
- masteru_name_len = strlen(masteru_name);
- }
- #ifdef DEBUG
- dbprintf("subuname \"%s\" masteru_name: \"%s\"\n", subuname, masteru_name);
- #endif
-
- //--------------------------------------------------------------------------------
- char *masteru_home;
- size_t masteru_home_len;
- char *subuland;
- size_t subuland_len;
- {
- #ifdef DEBUG
- dbprintf("building the subuland path\n");
- #endif
- masteru_home = masteru_pw_record_pt->pw_dir;
- masteru_home_len = strlen(masteru_home);
- if( masteru_home_len == 0 || masteru_home[0] == '(' ){
- fprintf(stderr,"strange, %s has no home directory\n", masteru_name);
- return ERR_BAD_MASTERU_HOME;
- }
- char *subuland_extension = "/subuland/";
- size_t subuland_extension_len = strlen(subuland_extension);
- subuland = (char *)malloc( masteru_home_len + subuland_extension_len + 1 );
- strcpy(subuland, masteru_home);
- strcpy(subuland + masteru_home_len, subuland_extension);
- subuland_len = masteru_home_len + subuland_extension_len;
- }
- #ifdef DEBUG
- dbprintf("masteru_home: \"%s\"\n", masteru_home);
- dbprintf("The path to subuland: \"%s\".\n", subuland);
- #endif
-
- //--------------------------------------------------------------------------------
- // Just because masteru_home is referenced in /etc/passwd does not mean it exists.
- // We also require that the subuland sub directory exists.
- {
- #ifdef DEBUG
- dbprintf("checking that masteru_home and subuland exist\n");
- #endif
- struct stat st;
- if( stat(masteru_home, &st) == -1) {
- fprintf(stderr, "Strange, masteru home does not exist, \"%s\".", masteru_home);
- free(subuland);
- return ERR_NOT_EXIST_MASTERU_HOME;
- }
- if( stat(subuland, &st) == -1) {
- fprintf(stderr, "$masteru_home/subuland/ does not exist");
- free(subuland);
- return ERR_NOT_EXIST_SUBULAND;
- }
- }
-
- //--------------------------------------------------------------------------------
- // the name for the subu home directory, which is $(masteru_home)/subuland/subuname
- char *subuhome;
- size_t subuhome_len;
- {
- #ifdef DEBUG
- dbprintf("making the name for subuhome\n");
- #endif
- subuhome_len = subuland_len + subuname_len;
- subuhome = (char *)malloc(subuhome_len + 1);
- if( !subuhome ){
- perror("subu_mk_0");
- free(subuland);
- return ERR_MALLOC;
- }
- strcpy (subuhome, subuland);
- strcpy (subuhome + subuland_len, subuname);
- }
- #ifdef DEBUG
- dbprintf("subuhome %s\n", subuhome);
- #endif
-
- /*--------------------------------------------------------------------------------
- We need to add execute access rights to masteru home and subuland so that
- the subu user can cd to subuhome.
-
- Ok to specify the new home directory in useradd, because it doesn't make it.
- From the man page:
-
- -d, --home-dir HOME_DIR The new user will be created using HOME_DIR
- as the value for the user's login directory. ... The directory HOME_DIR
- does not have to exist but will not be created if it is missing.
- */
- uid_t subuuid;
- gid_t subugid;
- {
- #ifdef DEBUG
- dbprintf("making subu\n");
- #endif
- char *command = "/usr/sbin/useradd";
- char *argv[5];
- argv[0] = command;
- argv[1] = subuname;
- argv[2] = "-d";
- argv[3] = subuhome;
- argv[4] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- struct dispatch_useradd_ret_t ret;
- ret = dispatch_useradd(argv, envp);
- if(ret.error){
- fprintf(stderr, "%u useradd failed\n", ret.error);
- free(subuland);
- free(subuhome);
- return ERR_FAILED_USERADD;
- }
- subuuid = ret.pw_record->pw_uid;
- subugid = ret.pw_record->pw_gid;
- #ifdef DEBUG
- dbprintf("subu made without errors\n", command, subuname, subuhome);
- #endif
- }
-
- //--------------------------------------------------------------------------------
- {
- #ifdef DEBUG
- dbprintf("give subu x access to masteru and subuland\n");
- #endif
- char *command = "/usr/bin/setfacl";
- char access[2 + subuname_len + 2 + 1];
- strcpy(access, "u:");
- strcpy(access + 2, subuname);
- strcpy(access + 2 + subuname_len, ":x");
- char *argv[5];
- argv[0] = command;
- argv[1] = "-m";
- argv[2] = access;
- argv[3] = masteru_home;
- argv[4] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- if( dispatch(argv, envp) == -1 ){
- fprintf(stderr, "'setfacl -m u:%s:x %s' returned an error.\n", subuname, masteru_home);
- free(subuland);
- free(subuhome);
- return ERR_SETFACL;
- }
- argv[3] = subuland;
- if( dispatch(argv, envp) == -1 ){
- fprintf(stderr, "'setfacl -m u:%s:x %s' returned an error.\n", subuname, subuland);
- free(subuland);
- free(subuhome);
- return ERR_SETFACL;
- }
- }
-
- //--------------------------------------------------------------------------------
- // create subuhome directory
- {
- #ifdef DEBUG
- dbprintf("mkdir(%s, 0x0700)\n", subuhome);
- #endif
- int ret = mkdir(subuhome, 0x0700);
- if( ret == -1 ){
- perror("subu_mk_0");
- free(subuland);
- free(subuhome);
- return ERR_MK_SUBUHOME;
- }
- ret = chown(subuhome, subuuid, subugid);
- if( ret == -1 ){
- perror("subu_mk_0");
- free(subuland);
- free(subuhome);
- return ERR_MK_SUBUHOME;
- }
- }
-
- //--------------------------------------------------------------------------------
- {
- #ifdef DEBUG
- dbprintf("give masteru access to the subuhome/...");
- #endif
- char *command = "/usr/bin/setfacl";
- char access[4 + masteru_name_len + 7 + masteru_name_len + 5 + subuhome_len + 1];
- strcpy(access, "d:u:");
- strcpy(access + 4, masteru_name);
- strcpy(access + 4 + masteru_name_len, ":rwX,u:");
- strcpy(access + 4 + masteru_name_len + 7, masteru_name);
- strcpy(access + 4 + masteru_name_len + 7 + masteru_name_len, ":rwX ");
- strcpy(access + 4 + masteru_name_len + 7 + masteru_name_len + 5, subuhome);
- char *argv[6];
- argv[0] = command;
- argv[1] = "-R"; // just in case the dir already existed with stuff in it
- argv[2] = "-m";
- argv[3] = access;
- argv[4] = subuhome;
- argv[5] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- if( dispatch(argv, envp) == -1 ){
- fprintf
- (
- stderr,
- "'setfacl -$ -m d:u:%s:rwX,u:%s:rwX %s' returned an error.\n",
- masteru_name,
- masteru_name,
- subuhome
- );
- free(subuland);
- free(subuhome);
- return ERR_SETFACL;
- }
- }
-
- #ifdef DEBUG
- dbprintf("finished subu-mk-0(%s) without error\n", subuname);
- #endif
- free(subuland);
- free(subuhome);
- return 0;
-}
diff --git a/try/sudo_script_leak/README.txt b/try/sudo_script_leak/README.txt
deleted file mode 100644
index 6a009c0..0000000
--- a/try/sudo_script_leak/README.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-If root does not set the PS1 prompt, and the sudo target uses a prompt, for
-example sudo su, then this method can be used to trick sudo into running any
-script as root as a side effect.
-
-In this example run_this.sh is the test script. target.sh is the script we
-would like to run as a side effect.
-
-1. remove prompt setting from root, say comment out the PS1= line if there is one.
-2. run 'run_this.sh'
-3. notice that now the prompt says 'target_running'.
-
-For example:
-
-§host§/home/user/src/sudo_script_leak
-> ./run_this.sh
-\n$(/home/user/src/sudo_script_leak/target.sh)\n§\h§\w\n>
-
-target running
-§host§/home/user/src/sudo_script_leak
->
diff --git a/try/sudo_script_leak/build/test_env/Analysis-00.toc b/try/sudo_script_leak/build/test_env/Analysis-00.toc
deleted file mode 100644
index 4abf14e..0000000
--- a/try/sudo_script_leak/build/test_env/Analysis-00.toc
+++ /dev/null
@@ -1,383 +0,0 @@
-(['/home/twl/Documents/subuser/test_env.py'],
- ['/home/twl/Documents/subuser', '/home/twl/Documents/subuser'],
- ['codecs'],
- [],
- [],
- [],
- False,
- False,
- '2.7.15+ (default, Nov 28 2018, 16:27:22) \n[GCC 8.2.0]',
- [('test_env', '/home/twl/Documents/subuser/test_env.py', 'PYSOURCE')],
- [('encodings.aliases',
- '/usr/lib/python2.7/encodings/aliases.py',
- 'PYMODULE'),
- ('encodings', '/usr/lib/python2.7/encodings/__init__.py', 'PYMODULE'),
- ('encodings.idna', '/usr/lib/python2.7/encodings/idna.py', 'PYMODULE'),
- ('re', '/usr/lib/python2.7/re.py', 'PYMODULE'),
- ('sre_constants', '/usr/lib/python2.7/sre_constants.py', 'PYMODULE'),
- ('sre', '/usr/lib/python2.7/sre.py', 'PYMODULE'),
- ('warnings', '/usr/lib/python2.7/warnings.py', 'PYMODULE'),
- ('types', '/usr/lib/python2.7/types.py', 'PYMODULE'),
- ('linecache', '/usr/lib/python2.7/linecache.py', 'PYMODULE'),
- ('string', '/usr/lib/python2.7/string.py', 'PYMODULE'),
- ('copy', '/usr/lib/python2.7/copy.py', 'PYMODULE'),
- ('repr', '/usr/lib/python2.7/repr.py', 'PYMODULE'),
- ('weakref', '/usr/lib/python2.7/weakref.py', 'PYMODULE'),
- ('_weakrefset', '/usr/lib/python2.7/_weakrefset.py', 'PYMODULE'),
- ('UserDict', '/usr/lib/python2.7/UserDict.py', 'PYMODULE'),
- ('_abcoll', '/usr/lib/python2.7/_abcoll.py', 'PYMODULE'),
- ('abc', '/usr/lib/python2.7/abc.py', 'PYMODULE'),
- ('copy_reg', '/usr/lib/python2.7/copy_reg.py', 'PYMODULE'),
- ('sre_parse', '/usr/lib/python2.7/sre_parse.py', 'PYMODULE'),
- ('sre_compile', '/usr/lib/python2.7/sre_compile.py', 'PYMODULE'),
- ('stringprep', '/usr/lib/python2.7/stringprep.py', 'PYMODULE'),
- ('encodings.mbcs', '/usr/lib/python2.7/encodings/mbcs.py', 'PYMODULE'),
- ('encodings.raw_unicode_escape',
- '/usr/lib/python2.7/encodings/raw_unicode_escape.py',
- 'PYMODULE'),
- ('encodings.gb18030',
- '/usr/lib/python2.7/encodings/gb18030.py',
- 'PYMODULE'),
- ('encodings.shift_jisx0213',
- '/usr/lib/python2.7/encodings/shift_jisx0213.py',
- 'PYMODULE'),
- ('encodings.ascii', '/usr/lib/python2.7/encodings/ascii.py', 'PYMODULE'),
- ('encodings.cp861', '/usr/lib/python2.7/encodings/cp861.py', 'PYMODULE'),
- ('encodings.cp860', '/usr/lib/python2.7/encodings/cp860.py', 'PYMODULE'),
- ('encodings.cp863', '/usr/lib/python2.7/encodings/cp863.py', 'PYMODULE'),
- ('encodings.cp862', '/usr/lib/python2.7/encodings/cp862.py', 'PYMODULE'),
- ('encodings.cp865', '/usr/lib/python2.7/encodings/cp865.py', 'PYMODULE'),
- ('encodings.big5hkscs',
- '/usr/lib/python2.7/encodings/big5hkscs.py',
- 'PYMODULE'),
- ('encodings.cp866', '/usr/lib/python2.7/encodings/cp866.py', 'PYMODULE'),
- ('encodings.cp869', '/usr/lib/python2.7/encodings/cp869.py', 'PYMODULE'),
- ('encodings.mac_latin2',
- '/usr/lib/python2.7/encodings/mac_latin2.py',
- 'PYMODULE'),
- ('encodings.hex_codec',
- '/usr/lib/python2.7/encodings/hex_codec.py',
- 'PYMODULE'),
- ('encodings.cp950', '/usr/lib/python2.7/encodings/cp950.py', 'PYMODULE'),
- ('encodings.quopri_codec',
- '/usr/lib/python2.7/encodings/quopri_codec.py',
- 'PYMODULE'),
- ('StringIO', '/usr/lib/python2.7/StringIO.py', 'PYMODULE'),
- ('quopri', '/usr/lib/python2.7/quopri.py', 'PYMODULE'),
- ('getopt', '/usr/lib/python2.7/getopt.py', 'PYMODULE'),
- ('encodings.utf_32_be',
- '/usr/lib/python2.7/encodings/utf_32_be.py',
- 'PYMODULE'),
- ('encodings.string_escape',
- '/usr/lib/python2.7/encodings/string_escape.py',
- 'PYMODULE'),
- ('encodings.cp1250', '/usr/lib/python2.7/encodings/cp1250.py', 'PYMODULE'),
- ('encodings.cp1251', '/usr/lib/python2.7/encodings/cp1251.py', 'PYMODULE'),
- ('encodings.cp1252', '/usr/lib/python2.7/encodings/cp1252.py', 'PYMODULE'),
- ('encodings.cp1253', '/usr/lib/python2.7/encodings/cp1253.py', 'PYMODULE'),
- ('encodings.cp1254', '/usr/lib/python2.7/encodings/cp1254.py', 'PYMODULE'),
- ('encodings.cp1255', '/usr/lib/python2.7/encodings/cp1255.py', 'PYMODULE'),
- ('encodings.cp1256', '/usr/lib/python2.7/encodings/cp1256.py', 'PYMODULE'),
- ('encodings.cp1257', '/usr/lib/python2.7/encodings/cp1257.py', 'PYMODULE'),
- ('encodings.cp1258', '/usr/lib/python2.7/encodings/cp1258.py', 'PYMODULE'),
- ('encodings.euc_jp', '/usr/lib/python2.7/encodings/euc_jp.py', 'PYMODULE'),
- ('encodings.hz', '/usr/lib/python2.7/encodings/hz.py', 'PYMODULE'),
- ('encodings.mac_cyrillic',
- '/usr/lib/python2.7/encodings/mac_cyrillic.py',
- 'PYMODULE'),
- ('encodings.iso2022_kr',
- '/usr/lib/python2.7/encodings/iso2022_kr.py',
- 'PYMODULE'),
- ('encodings.unicode_internal',
- '/usr/lib/python2.7/encodings/unicode_internal.py',
- 'PYMODULE'),
- ('encodings.cp500', '/usr/lib/python2.7/encodings/cp500.py', 'PYMODULE'),
- ('encodings.iso8859_10',
- '/usr/lib/python2.7/encodings/iso8859_10.py',
- 'PYMODULE'),
- ('encodings.iso8859_11',
- '/usr/lib/python2.7/encodings/iso8859_11.py',
- 'PYMODULE'),
- ('encodings.iso8859_13',
- '/usr/lib/python2.7/encodings/iso8859_13.py',
- 'PYMODULE'),
- ('encodings.iso8859_14',
- '/usr/lib/python2.7/encodings/iso8859_14.py',
- 'PYMODULE'),
- ('encodings.cp424', '/usr/lib/python2.7/encodings/cp424.py', 'PYMODULE'),
- ('encodings.iso8859_16',
- '/usr/lib/python2.7/encodings/iso8859_16.py',
- 'PYMODULE'),
- ('encodings.cp1006', '/usr/lib/python2.7/encodings/cp1006.py', 'PYMODULE'),
- ('encodings.hp_roman8',
- '/usr/lib/python2.7/encodings/hp_roman8.py',
- 'PYMODULE'),
- ('encodings.charmap',
- '/usr/lib/python2.7/encodings/charmap.py',
- 'PYMODULE'),
- ('encodings.utf_32', '/usr/lib/python2.7/encodings/utf_32.py', 'PYMODULE'),
- ('encodings.latin_1',
- '/usr/lib/python2.7/encodings/latin_1.py',
- 'PYMODULE'),
- ('encodings.utf_16_be',
- '/usr/lib/python2.7/encodings/utf_16_be.py',
- 'PYMODULE'),
- ('encodings.cp737', '/usr/lib/python2.7/encodings/cp737.py', 'PYMODULE'),
- ('encodings.utf_16', '/usr/lib/python2.7/encodings/utf_16.py', 'PYMODULE'),
- ('encodings.cp437', '/usr/lib/python2.7/encodings/cp437.py', 'PYMODULE'),
- ('encodings.mac_roman',
- '/usr/lib/python2.7/encodings/mac_roman.py',
- 'PYMODULE'),
- ('encodings.mac_centeuro',
- '/usr/lib/python2.7/encodings/mac_centeuro.py',
- 'PYMODULE'),
- ('encodings.mac_croatian',
- '/usr/lib/python2.7/encodings/mac_croatian.py',
- 'PYMODULE'),
- ('encodings.punycode',
- '/usr/lib/python2.7/encodings/punycode.py',
- 'PYMODULE'),
- ('encodings.unicode_escape',
- '/usr/lib/python2.7/encodings/unicode_escape.py',
- 'PYMODULE'),
- ('encodings.bz2_codec',
- '/usr/lib/python2.7/encodings/bz2_codec.py',
- 'PYMODULE'),
- ('encodings.rot_13', '/usr/lib/python2.7/encodings/rot_13.py', 'PYMODULE'),
- ('encodings.cp874', '/usr/lib/python2.7/encodings/cp874.py', 'PYMODULE'),
- ('encodings.cp875', '/usr/lib/python2.7/encodings/cp875.py', 'PYMODULE'),
- ('encodings.cp720', '/usr/lib/python2.7/encodings/cp720.py', 'PYMODULE'),
- ('encodings.tis_620',
- '/usr/lib/python2.7/encodings/tis_620.py',
- 'PYMODULE'),
- ('encodings.zlib_codec',
- '/usr/lib/python2.7/encodings/zlib_codec.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_2004',
- '/usr/lib/python2.7/encodings/iso2022_jp_2004.py',
- 'PYMODULE'),
- ('encodings.euc_jisx0213',
- '/usr/lib/python2.7/encodings/euc_jisx0213.py',
- 'PYMODULE'),
- ('encodings.ptcp154',
- '/usr/lib/python2.7/encodings/ptcp154.py',
- 'PYMODULE'),
- ('encodings.uu_codec',
- '/usr/lib/python2.7/encodings/uu_codec.py',
- 'PYMODULE'),
- ('encodings.utf_16_le',
- '/usr/lib/python2.7/encodings/utf_16_le.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_2',
- '/usr/lib/python2.7/encodings/iso2022_jp_2.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_3',
- '/usr/lib/python2.7/encodings/iso2022_jp_3.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_1',
- '/usr/lib/python2.7/encodings/iso2022_jp_1.py',
- 'PYMODULE'),
- ('encodings.mac_romanian',
- '/usr/lib/python2.7/encodings/mac_romanian.py',
- 'PYMODULE'),
- ('encodings.cp1026', '/usr/lib/python2.7/encodings/cp1026.py', 'PYMODULE'),
- ('encodings.mac_farsi',
- '/usr/lib/python2.7/encodings/mac_farsi.py',
- 'PYMODULE'),
- ('encodings.undefined',
- '/usr/lib/python2.7/encodings/undefined.py',
- 'PYMODULE'),
- ('encodings.mac_turkish',
- '/usr/lib/python2.7/encodings/mac_turkish.py',
- 'PYMODULE'),
- ('encodings.koi8_u', '/usr/lib/python2.7/encodings/koi8_u.py', 'PYMODULE'),
- ('encodings.koi8_r', '/usr/lib/python2.7/encodings/koi8_r.py', 'PYMODULE'),
- ('encodings.utf_8_sig',
- '/usr/lib/python2.7/encodings/utf_8_sig.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp',
- '/usr/lib/python2.7/encodings/iso2022_jp.py',
- 'PYMODULE'),
- ('encodings.palmos', '/usr/lib/python2.7/encodings/palmos.py', 'PYMODULE'),
- ('encodings.mac_greek',
- '/usr/lib/python2.7/encodings/mac_greek.py',
- 'PYMODULE'),
- ('encodings.shift_jis_2004',
- '/usr/lib/python2.7/encodings/shift_jis_2004.py',
- 'PYMODULE'),
- ('encodings.gbk', '/usr/lib/python2.7/encodings/gbk.py', 'PYMODULE'),
- ('encodings.mac_iceland',
- '/usr/lib/python2.7/encodings/mac_iceland.py',
- 'PYMODULE'),
- ('encodings.cp858', '/usr/lib/python2.7/encodings/cp858.py', 'PYMODULE'),
- ('encodings.cp850', '/usr/lib/python2.7/encodings/cp850.py', 'PYMODULE'),
- ('encodings.cp852', '/usr/lib/python2.7/encodings/cp852.py', 'PYMODULE'),
- ('encodings.cp855', '/usr/lib/python2.7/encodings/cp855.py', 'PYMODULE'),
- ('encodings.cp856', '/usr/lib/python2.7/encodings/cp856.py', 'PYMODULE'),
- ('encodings.cp857', '/usr/lib/python2.7/encodings/cp857.py', 'PYMODULE'),
- ('encodings.iso8859_4',
- '/usr/lib/python2.7/encodings/iso8859_4.py',
- 'PYMODULE'),
- ('encodings.iso8859_5',
- '/usr/lib/python2.7/encodings/iso8859_5.py',
- 'PYMODULE'),
- ('encodings.iso8859_6',
- '/usr/lib/python2.7/encodings/iso8859_6.py',
- 'PYMODULE'),
- ('encodings.iso8859_7',
- '/usr/lib/python2.7/encodings/iso8859_7.py',
- 'PYMODULE'),
- ('encodings.iso8859_1',
- '/usr/lib/python2.7/encodings/iso8859_1.py',
- 'PYMODULE'),
- ('encodings.iso8859_2',
- '/usr/lib/python2.7/encodings/iso8859_2.py',
- 'PYMODULE'),
- ('encodings.iso8859_3',
- '/usr/lib/python2.7/encodings/iso8859_3.py',
- 'PYMODULE'),
- ('encodings.gb2312', '/usr/lib/python2.7/encodings/gb2312.py', 'PYMODULE'),
- ('encodings.iso8859_8',
- '/usr/lib/python2.7/encodings/iso8859_8.py',
- 'PYMODULE'),
- ('encodings.iso8859_9',
- '/usr/lib/python2.7/encodings/iso8859_9.py',
- 'PYMODULE'),
- ('encodings.cp949', '/usr/lib/python2.7/encodings/cp949.py', 'PYMODULE'),
- ('encodings.cp864', '/usr/lib/python2.7/encodings/cp864.py', 'PYMODULE'),
- ('encodings.base64_codec',
- '/usr/lib/python2.7/encodings/base64_codec.py',
- 'PYMODULE'),
- ('base64', '/usr/lib/python2.7/base64.py', 'PYMODULE'),
- ('struct', '/usr/lib/python2.7/struct.py', 'PYMODULE'),
- ('encodings.cp037', '/usr/lib/python2.7/encodings/cp037.py', 'PYMODULE'),
- ('encodings.utf_8', '/usr/lib/python2.7/encodings/utf_8.py', 'PYMODULE'),
- ('encodings.mac_arabic',
- '/usr/lib/python2.7/encodings/mac_arabic.py',
- 'PYMODULE'),
- ('encodings.euc_kr', '/usr/lib/python2.7/encodings/euc_kr.py', 'PYMODULE'),
- ('encodings.utf_7', '/usr/lib/python2.7/encodings/utf_7.py', 'PYMODULE'),
- ('encodings.shift_jis',
- '/usr/lib/python2.7/encodings/shift_jis.py',
- 'PYMODULE'),
- ('encodings.utf_32_le',
- '/usr/lib/python2.7/encodings/utf_32_le.py',
- 'PYMODULE'),
- ('encodings.euc_jis_2004',
- '/usr/lib/python2.7/encodings/euc_jis_2004.py',
- 'PYMODULE'),
- ('encodings.cp775', '/usr/lib/python2.7/encodings/cp775.py', 'PYMODULE'),
- ('encodings.cp1140', '/usr/lib/python2.7/encodings/cp1140.py', 'PYMODULE'),
- ('encodings.big5', '/usr/lib/python2.7/encodings/big5.py', 'PYMODULE'),
- ('encodings.iso8859_15',
- '/usr/lib/python2.7/encodings/iso8859_15.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_ext',
- '/usr/lib/python2.7/encodings/iso2022_jp_ext.py',
- 'PYMODULE'),
- ('encodings.johab', '/usr/lib/python2.7/encodings/johab.py', 'PYMODULE'),
- ('encodings.cp932', '/usr/lib/python2.7/encodings/cp932.py', 'PYMODULE'),
- ('codecs', '/usr/lib/python2.7/codecs.py', 'PYMODULE'),
- ('os', '/usr/lib/python2.7/os.py', 'PYMODULE'),
- ('subprocess', '/usr/lib/python2.7/subprocess.py', 'PYMODULE'),
- ('pickle', '/usr/lib/python2.7/pickle.py', 'PYMODULE'),
- ('doctest', '/usr/lib/python2.7/doctest.py', 'PYMODULE'),
- ('collections', '/usr/lib/python2.7/collections.py', 'PYMODULE'),
- ('dummy_thread', '/usr/lib/python2.7/dummy_thread.py', 'PYMODULE'),
- ('heapq', '/usr/lib/python2.7/heapq.py', 'PYMODULE'),
- ('keyword', '/usr/lib/python2.7/keyword.py', 'PYMODULE'),
- ('tempfile', '/usr/lib/python2.7/tempfile.py', 'PYMODULE'),
- ('random', '/usr/lib/python2.7/random.py', 'PYMODULE'),
- ('_strptime', '/usr/lib/python2.7/_strptime.py', 'PYMODULE'),
- ('calendar', '/usr/lib/python2.7/calendar.py', 'PYMODULE'),
- ('optparse', '/usr/lib/python2.7/optparse.py', 'PYMODULE'),
- ('gettext', '/usr/lib/python2.7/gettext.py', 'PYMODULE'),
- ('textwrap', '/usr/lib/python2.7/textwrap.py', 'PYMODULE'),
- ('locale', '/usr/lib/python2.7/locale.py', 'PYMODULE'),
- ('functools', '/usr/lib/python2.7/functools.py', 'PYMODULE'),
- ('hashlib', '/usr/lib/python2.7/hashlib.py', 'PYMODULE'),
- ('logging', '/usr/lib/python2.7/logging/__init__.py', 'PYMODULE'),
- ('atexit', '/usr/lib/python2.7/atexit.py', 'PYMODULE'),
- ('io', '/usr/lib/python2.7/io.py', 'PYMODULE'),
- ('pdb', '/usr/lib/python2.7/pdb.py', 'PYMODULE'),
- ('shlex', '/usr/lib/python2.7/shlex.py', 'PYMODULE'),
- ('pprint', '/usr/lib/python2.7/pprint.py', 'PYMODULE'),
- ('bdb', '/usr/lib/python2.7/bdb.py', 'PYMODULE'),
- ('fnmatch', '/usr/lib/python2.7/fnmatch.py', 'PYMODULE'),
- ('cmd', '/usr/lib/python2.7/cmd.py', 'PYMODULE'),
- ('difflib', '/usr/lib/python2.7/difflib.py', 'PYMODULE'),
- ('unittest', '/usr/lib/python2.7/unittest/__init__.py', 'PYMODULE'),
- ('unittest.signals', '/usr/lib/python2.7/unittest/signals.py', 'PYMODULE'),
- ('unittest.main', '/usr/lib/python2.7/unittest/main.py', 'PYMODULE'),
- ('unittest.runner', '/usr/lib/python2.7/unittest/runner.py', 'PYMODULE'),
- ('unittest.loader', '/usr/lib/python2.7/unittest/loader.py', 'PYMODULE'),
- ('unittest.suite', '/usr/lib/python2.7/unittest/suite.py', 'PYMODULE'),
- ('unittest.case', '/usr/lib/python2.7/unittest/case.py', 'PYMODULE'),
- ('unittest.result', '/usr/lib/python2.7/unittest/result.py', 'PYMODULE'),
- ('unittest.util', '/usr/lib/python2.7/unittest/util.py', 'PYMODULE'),
- ('inspect', '/usr/lib/python2.7/inspect.py', 'PYMODULE'),
- ('tokenize', '/usr/lib/python2.7/tokenize.py', 'PYMODULE'),
- ('token', '/usr/lib/python2.7/token.py', 'PYMODULE'),
- ('dis', '/usr/lib/python2.7/dis.py', 'PYMODULE'),
- ('opcode', '/usr/lib/python2.7/opcode.py', 'PYMODULE'),
- ('__future__', '/usr/lib/python2.7/__future__.py', 'PYMODULE'),
- ('threading', '/usr/lib/python2.7/threading.py', 'PYMODULE'),
- ('_threading_local', '/usr/lib/python2.7/_threading_local.py', 'PYMODULE'),
- ('traceback', '/usr/lib/python2.7/traceback.py', 'PYMODULE'),
- ('os2emxpath', '/usr/lib/python2.7/os2emxpath.py', 'PYMODULE'),
- ('genericpath', '/usr/lib/python2.7/genericpath.py', 'PYMODULE'),
- ('stat', '/usr/lib/python2.7/stat.py', 'PYMODULE'),
- ('ntpath', '/usr/lib/python2.7/ntpath.py', 'PYMODULE'),
- ('posixpath', '/usr/lib/python2.7/posixpath.py', 'PYMODULE'),
- ('getpass', '/usr/lib/python2.7/getpass.py', 'PYMODULE')],
- [('libz.so.1', '/lib/x86_64-linux-gnu/libz.so.1', 'BINARY'),
- ('_multibytecodec',
- '/usr/lib/python2.7/lib-dynload/_multibytecodec.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_cn',
- '/usr/lib/python2.7/lib-dynload/_codecs_cn.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_jp',
- '/usr/lib/python2.7/lib-dynload/_codecs_jp.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_hk',
- '/usr/lib/python2.7/lib-dynload/_codecs_hk.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_tw',
- '/usr/lib/python2.7/lib-dynload/_codecs_tw.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_iso2022',
- '/usr/lib/python2.7/lib-dynload/_codecs_iso2022.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('bz2',
- '/usr/lib/python2.7/lib-dynload/bz2.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_kr',
- '/usr/lib/python2.7/lib-dynload/_codecs_kr.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_hashlib',
- '/usr/lib/python2.7/lib-dynload/_hashlib.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('readline',
- '/usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('resource',
- '/usr/lib/python2.7/lib-dynload/resource.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('termios',
- '/usr/lib/python2.7/lib-dynload/termios.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('libbz2.so.1.0', '/lib/x86_64-linux-gnu/libbz2.so.1.0', 'BINARY'),
- ('libssl.so.1.1', '/usr/lib/x86_64-linux-gnu/libssl.so.1.1', 'BINARY'),
- ('libcrypto.so.1.1',
- '/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1',
- 'BINARY'),
- ('libreadline.so.7', '/lib/x86_64-linux-gnu/libreadline.so.7', 'BINARY'),
- ('libtinfo.so.6', '/lib/x86_64-linux-gnu/libtinfo.so.6', 'BINARY'),
- ('libpython2.7.so.1.0',
- '/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0',
- 'BINARY')],
- [],
- [],
- [],
- [])
diff --git a/try/sudo_script_leak/build/test_env/EXE-00.toc b/try/sudo_script_leak/build/test_env/EXE-00.toc
deleted file mode 100644
index d461f81..0000000
--- a/try/sudo_script_leak/build/test_env/EXE-00.toc
+++ /dev/null
@@ -1,82 +0,0 @@
-('/home/twl/Documents/subuser/dist/test_env',
- True,
- False,
- False,
- None,
- None,
- False,
- False,
- None,
- True,
- 'test_env.pkg',
- [('PYZ-00.pyz',
- '/home/twl/Documents/subuser/build/test_env/PYZ-00.pyz',
- 'PYZ'),
- ('struct', '/usr/lib/python2.7/struct.pyc', 'PYMODULE'),
- ('pyimod01_os_path',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyimod01_os_path.pyc',
- 'PYMODULE'),
- ('pyimod02_archive',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyimod02_archive.pyc',
- 'PYMODULE'),
- ('pyimod03_importers',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyimod03_importers.pyc',
- 'PYMODULE'),
- ('pyiboot01_bootstrap',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyiboot01_bootstrap.py',
- 'PYSOURCE'),
- ('test_env', '/home/twl/Documents/subuser/test_env.py', 'PYSOURCE'),
- ('libz.so.1', '/lib/x86_64-linux-gnu/libz.so.1', 'BINARY'),
- ('_multibytecodec',
- '/usr/lib/python2.7/lib-dynload/_multibytecodec.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_cn',
- '/usr/lib/python2.7/lib-dynload/_codecs_cn.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_jp',
- '/usr/lib/python2.7/lib-dynload/_codecs_jp.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_hk',
- '/usr/lib/python2.7/lib-dynload/_codecs_hk.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_tw',
- '/usr/lib/python2.7/lib-dynload/_codecs_tw.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_iso2022',
- '/usr/lib/python2.7/lib-dynload/_codecs_iso2022.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('bz2',
- '/usr/lib/python2.7/lib-dynload/bz2.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_kr',
- '/usr/lib/python2.7/lib-dynload/_codecs_kr.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_hashlib',
- '/usr/lib/python2.7/lib-dynload/_hashlib.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('readline',
- '/usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('resource',
- '/usr/lib/python2.7/lib-dynload/resource.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('termios',
- '/usr/lib/python2.7/lib-dynload/termios.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('libbz2.so.1.0', '/lib/x86_64-linux-gnu/libbz2.so.1.0', 'BINARY'),
- ('libssl.so.1.1', '/usr/lib/x86_64-linux-gnu/libssl.so.1.1', 'BINARY'),
- ('libcrypto.so.1.1',
- '/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1',
- 'BINARY'),
- ('libreadline.so.7', '/lib/x86_64-linux-gnu/libreadline.so.7', 'BINARY'),
- ('libtinfo.so.6', '/lib/x86_64-linux-gnu/libtinfo.so.6', 'BINARY'),
- ('libpython2.7.so.1.0',
- '/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0',
- 'BINARY')],
- [],
- False,
- True,
- 1548883098,
- [('run',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/bootloader/Linux-64bit/run',
- 'EXECUTABLE')])
diff --git a/try/sudo_script_leak/build/test_env/PKG-00.pkg b/try/sudo_script_leak/build/test_env/PKG-00.pkg
deleted file mode 100644
index faf6da7..0000000
Binary files a/try/sudo_script_leak/build/test_env/PKG-00.pkg and /dev/null differ
diff --git a/try/sudo_script_leak/build/test_env/PKG-00.toc b/try/sudo_script_leak/build/test_env/PKG-00.toc
deleted file mode 100644
index ad23756..0000000
--- a/try/sudo_script_leak/build/test_env/PKG-00.toc
+++ /dev/null
@@ -1,75 +0,0 @@
-('/home/twl/Documents/subuser/build/test_env/PKG-00.pkg',
- {'BINARY': 1,
- 'DATA': 1,
- 'EXECUTABLE': 1,
- 'EXTENSION': 1,
- 'PYMODULE': 1,
- 'PYSOURCE': 1,
- 'PYZ': 0},
- [('PYZ-00.pyz',
- '/home/twl/Documents/subuser/build/test_env/PYZ-00.pyz',
- 'PYZ'),
- ('struct', '/usr/lib/python2.7/struct.pyc', 'PYMODULE'),
- ('pyimod01_os_path',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyimod01_os_path.pyc',
- 'PYMODULE'),
- ('pyimod02_archive',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyimod02_archive.pyc',
- 'PYMODULE'),
- ('pyimod03_importers',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyimod03_importers.pyc',
- 'PYMODULE'),
- ('pyiboot01_bootstrap',
- '/home/twl/.local/lib/python2.7/site-packages/PyInstaller/loader/pyiboot01_bootstrap.py',
- 'PYSOURCE'),
- ('test_env', '/home/twl/Documents/subuser/test_env.py', 'PYSOURCE'),
- ('libz.so.1', '/lib/x86_64-linux-gnu/libz.so.1', 'BINARY'),
- ('_multibytecodec',
- '/usr/lib/python2.7/lib-dynload/_multibytecodec.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_cn',
- '/usr/lib/python2.7/lib-dynload/_codecs_cn.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_jp',
- '/usr/lib/python2.7/lib-dynload/_codecs_jp.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_hk',
- '/usr/lib/python2.7/lib-dynload/_codecs_hk.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_tw',
- '/usr/lib/python2.7/lib-dynload/_codecs_tw.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_iso2022',
- '/usr/lib/python2.7/lib-dynload/_codecs_iso2022.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('bz2',
- '/usr/lib/python2.7/lib-dynload/bz2.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_codecs_kr',
- '/usr/lib/python2.7/lib-dynload/_codecs_kr.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('_hashlib',
- '/usr/lib/python2.7/lib-dynload/_hashlib.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('readline',
- '/usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('resource',
- '/usr/lib/python2.7/lib-dynload/resource.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('termios',
- '/usr/lib/python2.7/lib-dynload/termios.x86_64-linux-gnu.so',
- 'EXTENSION'),
- ('libbz2.so.1.0', '/lib/x86_64-linux-gnu/libbz2.so.1.0', 'BINARY'),
- ('libssl.so.1.1', '/usr/lib/x86_64-linux-gnu/libssl.so.1.1', 'BINARY'),
- ('libcrypto.so.1.1',
- '/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1',
- 'BINARY'),
- ('libreadline.so.7', '/lib/x86_64-linux-gnu/libreadline.so.7', 'BINARY'),
- ('libtinfo.so.6', '/lib/x86_64-linux-gnu/libtinfo.so.6', 'BINARY'),
- ('libpython2.7.so.1.0',
- '/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0',
- 'BINARY')],
- False,
- False,
- True)
diff --git a/try/sudo_script_leak/build/test_env/PYZ-00.pyz b/try/sudo_script_leak/build/test_env/PYZ-00.pyz
deleted file mode 100644
index 6c9ec54..0000000
Binary files a/try/sudo_script_leak/build/test_env/PYZ-00.pyz and /dev/null differ
diff --git a/try/sudo_script_leak/build/test_env/PYZ-00.toc b/try/sudo_script_leak/build/test_env/PYZ-00.toc
deleted file mode 100644
index 16e3b0c..0000000
--- a/try/sudo_script_leak/build/test_env/PYZ-00.toc
+++ /dev/null
@@ -1,323 +0,0 @@
-('/home/twl/Documents/subuser/build/test_env/PYZ-00.pyz',
- [('encodings.aliases',
- '/usr/lib/python2.7/encodings/aliases.py',
- 'PYMODULE'),
- ('encodings', '/usr/lib/python2.7/encodings/__init__.py', 'PYMODULE'),
- ('encodings.idna', '/usr/lib/python2.7/encodings/idna.py', 'PYMODULE'),
- ('re', '/usr/lib/python2.7/re.py', 'PYMODULE'),
- ('sre_constants', '/usr/lib/python2.7/sre_constants.py', 'PYMODULE'),
- ('sre', '/usr/lib/python2.7/sre.py', 'PYMODULE'),
- ('warnings', '/usr/lib/python2.7/warnings.py', 'PYMODULE'),
- ('types', '/usr/lib/python2.7/types.py', 'PYMODULE'),
- ('linecache', '/usr/lib/python2.7/linecache.py', 'PYMODULE'),
- ('string', '/usr/lib/python2.7/string.py', 'PYMODULE'),
- ('copy', '/usr/lib/python2.7/copy.py', 'PYMODULE'),
- ('repr', '/usr/lib/python2.7/repr.py', 'PYMODULE'),
- ('weakref', '/usr/lib/python2.7/weakref.py', 'PYMODULE'),
- ('_weakrefset', '/usr/lib/python2.7/_weakrefset.py', 'PYMODULE'),
- ('UserDict', '/usr/lib/python2.7/UserDict.py', 'PYMODULE'),
- ('_abcoll', '/usr/lib/python2.7/_abcoll.py', 'PYMODULE'),
- ('abc', '/usr/lib/python2.7/abc.py', 'PYMODULE'),
- ('copy_reg', '/usr/lib/python2.7/copy_reg.py', 'PYMODULE'),
- ('sre_parse', '/usr/lib/python2.7/sre_parse.py', 'PYMODULE'),
- ('sre_compile', '/usr/lib/python2.7/sre_compile.py', 'PYMODULE'),
- ('stringprep', '/usr/lib/python2.7/stringprep.py', 'PYMODULE'),
- ('encodings.mbcs', '/usr/lib/python2.7/encodings/mbcs.py', 'PYMODULE'),
- ('encodings.raw_unicode_escape',
- '/usr/lib/python2.7/encodings/raw_unicode_escape.py',
- 'PYMODULE'),
- ('encodings.gb18030',
- '/usr/lib/python2.7/encodings/gb18030.py',
- 'PYMODULE'),
- ('encodings.shift_jisx0213',
- '/usr/lib/python2.7/encodings/shift_jisx0213.py',
- 'PYMODULE'),
- ('encodings.ascii', '/usr/lib/python2.7/encodings/ascii.py', 'PYMODULE'),
- ('encodings.cp861', '/usr/lib/python2.7/encodings/cp861.py', 'PYMODULE'),
- ('encodings.cp860', '/usr/lib/python2.7/encodings/cp860.py', 'PYMODULE'),
- ('encodings.cp863', '/usr/lib/python2.7/encodings/cp863.py', 'PYMODULE'),
- ('encodings.cp862', '/usr/lib/python2.7/encodings/cp862.py', 'PYMODULE'),
- ('encodings.cp865', '/usr/lib/python2.7/encodings/cp865.py', 'PYMODULE'),
- ('encodings.big5hkscs',
- '/usr/lib/python2.7/encodings/big5hkscs.py',
- 'PYMODULE'),
- ('encodings.cp866', '/usr/lib/python2.7/encodings/cp866.py', 'PYMODULE'),
- ('encodings.cp869', '/usr/lib/python2.7/encodings/cp869.py', 'PYMODULE'),
- ('encodings.mac_latin2',
- '/usr/lib/python2.7/encodings/mac_latin2.py',
- 'PYMODULE'),
- ('encodings.hex_codec',
- '/usr/lib/python2.7/encodings/hex_codec.py',
- 'PYMODULE'),
- ('encodings.cp950', '/usr/lib/python2.7/encodings/cp950.py', 'PYMODULE'),
- ('encodings.quopri_codec',
- '/usr/lib/python2.7/encodings/quopri_codec.py',
- 'PYMODULE'),
- ('StringIO', '/usr/lib/python2.7/StringIO.py', 'PYMODULE'),
- ('quopri', '/usr/lib/python2.7/quopri.py', 'PYMODULE'),
- ('getopt', '/usr/lib/python2.7/getopt.py', 'PYMODULE'),
- ('encodings.utf_32_be',
- '/usr/lib/python2.7/encodings/utf_32_be.py',
- 'PYMODULE'),
- ('encodings.string_escape',
- '/usr/lib/python2.7/encodings/string_escape.py',
- 'PYMODULE'),
- ('encodings.cp1250', '/usr/lib/python2.7/encodings/cp1250.py', 'PYMODULE'),
- ('encodings.cp1251', '/usr/lib/python2.7/encodings/cp1251.py', 'PYMODULE'),
- ('encodings.cp1252', '/usr/lib/python2.7/encodings/cp1252.py', 'PYMODULE'),
- ('encodings.cp1253', '/usr/lib/python2.7/encodings/cp1253.py', 'PYMODULE'),
- ('encodings.cp1254', '/usr/lib/python2.7/encodings/cp1254.py', 'PYMODULE'),
- ('encodings.cp1255', '/usr/lib/python2.7/encodings/cp1255.py', 'PYMODULE'),
- ('encodings.cp1256', '/usr/lib/python2.7/encodings/cp1256.py', 'PYMODULE'),
- ('encodings.cp1257', '/usr/lib/python2.7/encodings/cp1257.py', 'PYMODULE'),
- ('encodings.cp1258', '/usr/lib/python2.7/encodings/cp1258.py', 'PYMODULE'),
- ('encodings.euc_jp', '/usr/lib/python2.7/encodings/euc_jp.py', 'PYMODULE'),
- ('encodings.hz', '/usr/lib/python2.7/encodings/hz.py', 'PYMODULE'),
- ('encodings.mac_cyrillic',
- '/usr/lib/python2.7/encodings/mac_cyrillic.py',
- 'PYMODULE'),
- ('encodings.iso2022_kr',
- '/usr/lib/python2.7/encodings/iso2022_kr.py',
- 'PYMODULE'),
- ('encodings.unicode_internal',
- '/usr/lib/python2.7/encodings/unicode_internal.py',
- 'PYMODULE'),
- ('encodings.cp500', '/usr/lib/python2.7/encodings/cp500.py', 'PYMODULE'),
- ('encodings.iso8859_10',
- '/usr/lib/python2.7/encodings/iso8859_10.py',
- 'PYMODULE'),
- ('encodings.iso8859_11',
- '/usr/lib/python2.7/encodings/iso8859_11.py',
- 'PYMODULE'),
- ('encodings.iso8859_13',
- '/usr/lib/python2.7/encodings/iso8859_13.py',
- 'PYMODULE'),
- ('encodings.iso8859_14',
- '/usr/lib/python2.7/encodings/iso8859_14.py',
- 'PYMODULE'),
- ('encodings.cp424', '/usr/lib/python2.7/encodings/cp424.py', 'PYMODULE'),
- ('encodings.iso8859_16',
- '/usr/lib/python2.7/encodings/iso8859_16.py',
- 'PYMODULE'),
- ('encodings.cp1006', '/usr/lib/python2.7/encodings/cp1006.py', 'PYMODULE'),
- ('encodings.hp_roman8',
- '/usr/lib/python2.7/encodings/hp_roman8.py',
- 'PYMODULE'),
- ('encodings.charmap',
- '/usr/lib/python2.7/encodings/charmap.py',
- 'PYMODULE'),
- ('encodings.utf_32', '/usr/lib/python2.7/encodings/utf_32.py', 'PYMODULE'),
- ('encodings.latin_1',
- '/usr/lib/python2.7/encodings/latin_1.py',
- 'PYMODULE'),
- ('encodings.utf_16_be',
- '/usr/lib/python2.7/encodings/utf_16_be.py',
- 'PYMODULE'),
- ('encodings.cp737', '/usr/lib/python2.7/encodings/cp737.py', 'PYMODULE'),
- ('encodings.utf_16', '/usr/lib/python2.7/encodings/utf_16.py', 'PYMODULE'),
- ('encodings.cp437', '/usr/lib/python2.7/encodings/cp437.py', 'PYMODULE'),
- ('encodings.mac_roman',
- '/usr/lib/python2.7/encodings/mac_roman.py',
- 'PYMODULE'),
- ('encodings.mac_centeuro',
- '/usr/lib/python2.7/encodings/mac_centeuro.py',
- 'PYMODULE'),
- ('encodings.mac_croatian',
- '/usr/lib/python2.7/encodings/mac_croatian.py',
- 'PYMODULE'),
- ('encodings.punycode',
- '/usr/lib/python2.7/encodings/punycode.py',
- 'PYMODULE'),
- ('encodings.unicode_escape',
- '/usr/lib/python2.7/encodings/unicode_escape.py',
- 'PYMODULE'),
- ('encodings.bz2_codec',
- '/usr/lib/python2.7/encodings/bz2_codec.py',
- 'PYMODULE'),
- ('encodings.rot_13', '/usr/lib/python2.7/encodings/rot_13.py', 'PYMODULE'),
- ('encodings.cp874', '/usr/lib/python2.7/encodings/cp874.py', 'PYMODULE'),
- ('encodings.cp875', '/usr/lib/python2.7/encodings/cp875.py', 'PYMODULE'),
- ('encodings.cp720', '/usr/lib/python2.7/encodings/cp720.py', 'PYMODULE'),
- ('encodings.tis_620',
- '/usr/lib/python2.7/encodings/tis_620.py',
- 'PYMODULE'),
- ('encodings.zlib_codec',
- '/usr/lib/python2.7/encodings/zlib_codec.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_2004',
- '/usr/lib/python2.7/encodings/iso2022_jp_2004.py',
- 'PYMODULE'),
- ('encodings.euc_jisx0213',
- '/usr/lib/python2.7/encodings/euc_jisx0213.py',
- 'PYMODULE'),
- ('encodings.ptcp154',
- '/usr/lib/python2.7/encodings/ptcp154.py',
- 'PYMODULE'),
- ('encodings.uu_codec',
- '/usr/lib/python2.7/encodings/uu_codec.py',
- 'PYMODULE'),
- ('encodings.utf_16_le',
- '/usr/lib/python2.7/encodings/utf_16_le.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_2',
- '/usr/lib/python2.7/encodings/iso2022_jp_2.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_3',
- '/usr/lib/python2.7/encodings/iso2022_jp_3.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_1',
- '/usr/lib/python2.7/encodings/iso2022_jp_1.py',
- 'PYMODULE'),
- ('encodings.mac_romanian',
- '/usr/lib/python2.7/encodings/mac_romanian.py',
- 'PYMODULE'),
- ('encodings.cp1026', '/usr/lib/python2.7/encodings/cp1026.py', 'PYMODULE'),
- ('encodings.mac_farsi',
- '/usr/lib/python2.7/encodings/mac_farsi.py',
- 'PYMODULE'),
- ('encodings.undefined',
- '/usr/lib/python2.7/encodings/undefined.py',
- 'PYMODULE'),
- ('encodings.mac_turkish',
- '/usr/lib/python2.7/encodings/mac_turkish.py',
- 'PYMODULE'),
- ('encodings.koi8_u', '/usr/lib/python2.7/encodings/koi8_u.py', 'PYMODULE'),
- ('encodings.koi8_r', '/usr/lib/python2.7/encodings/koi8_r.py', 'PYMODULE'),
- ('encodings.utf_8_sig',
- '/usr/lib/python2.7/encodings/utf_8_sig.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp',
- '/usr/lib/python2.7/encodings/iso2022_jp.py',
- 'PYMODULE'),
- ('encodings.palmos', '/usr/lib/python2.7/encodings/palmos.py', 'PYMODULE'),
- ('encodings.mac_greek',
- '/usr/lib/python2.7/encodings/mac_greek.py',
- 'PYMODULE'),
- ('encodings.shift_jis_2004',
- '/usr/lib/python2.7/encodings/shift_jis_2004.py',
- 'PYMODULE'),
- ('encodings.gbk', '/usr/lib/python2.7/encodings/gbk.py', 'PYMODULE'),
- ('encodings.mac_iceland',
- '/usr/lib/python2.7/encodings/mac_iceland.py',
- 'PYMODULE'),
- ('encodings.cp858', '/usr/lib/python2.7/encodings/cp858.py', 'PYMODULE'),
- ('encodings.cp850', '/usr/lib/python2.7/encodings/cp850.py', 'PYMODULE'),
- ('encodings.cp852', '/usr/lib/python2.7/encodings/cp852.py', 'PYMODULE'),
- ('encodings.cp855', '/usr/lib/python2.7/encodings/cp855.py', 'PYMODULE'),
- ('encodings.cp856', '/usr/lib/python2.7/encodings/cp856.py', 'PYMODULE'),
- ('encodings.cp857', '/usr/lib/python2.7/encodings/cp857.py', 'PYMODULE'),
- ('encodings.iso8859_4',
- '/usr/lib/python2.7/encodings/iso8859_4.py',
- 'PYMODULE'),
- ('encodings.iso8859_5',
- '/usr/lib/python2.7/encodings/iso8859_5.py',
- 'PYMODULE'),
- ('encodings.iso8859_6',
- '/usr/lib/python2.7/encodings/iso8859_6.py',
- 'PYMODULE'),
- ('encodings.iso8859_7',
- '/usr/lib/python2.7/encodings/iso8859_7.py',
- 'PYMODULE'),
- ('encodings.iso8859_1',
- '/usr/lib/python2.7/encodings/iso8859_1.py',
- 'PYMODULE'),
- ('encodings.iso8859_2',
- '/usr/lib/python2.7/encodings/iso8859_2.py',
- 'PYMODULE'),
- ('encodings.iso8859_3',
- '/usr/lib/python2.7/encodings/iso8859_3.py',
- 'PYMODULE'),
- ('encodings.gb2312', '/usr/lib/python2.7/encodings/gb2312.py', 'PYMODULE'),
- ('encodings.iso8859_8',
- '/usr/lib/python2.7/encodings/iso8859_8.py',
- 'PYMODULE'),
- ('encodings.iso8859_9',
- '/usr/lib/python2.7/encodings/iso8859_9.py',
- 'PYMODULE'),
- ('encodings.cp949', '/usr/lib/python2.7/encodings/cp949.py', 'PYMODULE'),
- ('encodings.cp864', '/usr/lib/python2.7/encodings/cp864.py', 'PYMODULE'),
- ('encodings.base64_codec',
- '/usr/lib/python2.7/encodings/base64_codec.py',
- 'PYMODULE'),
- ('base64', '/usr/lib/python2.7/base64.py', 'PYMODULE'),
- ('struct', '/usr/lib/python2.7/struct.py', 'PYMODULE'),
- ('encodings.cp037', '/usr/lib/python2.7/encodings/cp037.py', 'PYMODULE'),
- ('encodings.utf_8', '/usr/lib/python2.7/encodings/utf_8.py', 'PYMODULE'),
- ('encodings.mac_arabic',
- '/usr/lib/python2.7/encodings/mac_arabic.py',
- 'PYMODULE'),
- ('encodings.euc_kr', '/usr/lib/python2.7/encodings/euc_kr.py', 'PYMODULE'),
- ('encodings.utf_7', '/usr/lib/python2.7/encodings/utf_7.py', 'PYMODULE'),
- ('encodings.shift_jis',
- '/usr/lib/python2.7/encodings/shift_jis.py',
- 'PYMODULE'),
- ('encodings.utf_32_le',
- '/usr/lib/python2.7/encodings/utf_32_le.py',
- 'PYMODULE'),
- ('encodings.euc_jis_2004',
- '/usr/lib/python2.7/encodings/euc_jis_2004.py',
- 'PYMODULE'),
- ('encodings.cp775', '/usr/lib/python2.7/encodings/cp775.py', 'PYMODULE'),
- ('encodings.cp1140', '/usr/lib/python2.7/encodings/cp1140.py', 'PYMODULE'),
- ('encodings.big5', '/usr/lib/python2.7/encodings/big5.py', 'PYMODULE'),
- ('encodings.iso8859_15',
- '/usr/lib/python2.7/encodings/iso8859_15.py',
- 'PYMODULE'),
- ('encodings.iso2022_jp_ext',
- '/usr/lib/python2.7/encodings/iso2022_jp_ext.py',
- 'PYMODULE'),
- ('encodings.johab', '/usr/lib/python2.7/encodings/johab.py', 'PYMODULE'),
- ('encodings.cp932', '/usr/lib/python2.7/encodings/cp932.py', 'PYMODULE'),
- ('codecs', '/usr/lib/python2.7/codecs.py', 'PYMODULE'),
- ('os', '/usr/lib/python2.7/os.py', 'PYMODULE'),
- ('subprocess', '/usr/lib/python2.7/subprocess.py', 'PYMODULE'),
- ('pickle', '/usr/lib/python2.7/pickle.py', 'PYMODULE'),
- ('doctest', '/usr/lib/python2.7/doctest.py', 'PYMODULE'),
- ('collections', '/usr/lib/python2.7/collections.py', 'PYMODULE'),
- ('dummy_thread', '/usr/lib/python2.7/dummy_thread.py', 'PYMODULE'),
- ('heapq', '/usr/lib/python2.7/heapq.py', 'PYMODULE'),
- ('keyword', '/usr/lib/python2.7/keyword.py', 'PYMODULE'),
- ('tempfile', '/usr/lib/python2.7/tempfile.py', 'PYMODULE'),
- ('random', '/usr/lib/python2.7/random.py', 'PYMODULE'),
- ('_strptime', '/usr/lib/python2.7/_strptime.py', 'PYMODULE'),
- ('calendar', '/usr/lib/python2.7/calendar.py', 'PYMODULE'),
- ('optparse', '/usr/lib/python2.7/optparse.py', 'PYMODULE'),
- ('gettext', '/usr/lib/python2.7/gettext.py', 'PYMODULE'),
- ('textwrap', '/usr/lib/python2.7/textwrap.py', 'PYMODULE'),
- ('locale', '/usr/lib/python2.7/locale.py', 'PYMODULE'),
- ('functools', '/usr/lib/python2.7/functools.py', 'PYMODULE'),
- ('hashlib', '/usr/lib/python2.7/hashlib.py', 'PYMODULE'),
- ('logging', '/usr/lib/python2.7/logging/__init__.py', 'PYMODULE'),
- ('atexit', '/usr/lib/python2.7/atexit.py', 'PYMODULE'),
- ('io', '/usr/lib/python2.7/io.py', 'PYMODULE'),
- ('pdb', '/usr/lib/python2.7/pdb.py', 'PYMODULE'),
- ('shlex', '/usr/lib/python2.7/shlex.py', 'PYMODULE'),
- ('pprint', '/usr/lib/python2.7/pprint.py', 'PYMODULE'),
- ('bdb', '/usr/lib/python2.7/bdb.py', 'PYMODULE'),
- ('fnmatch', '/usr/lib/python2.7/fnmatch.py', 'PYMODULE'),
- ('cmd', '/usr/lib/python2.7/cmd.py', 'PYMODULE'),
- ('difflib', '/usr/lib/python2.7/difflib.py', 'PYMODULE'),
- ('unittest', '/usr/lib/python2.7/unittest/__init__.py', 'PYMODULE'),
- ('unittest.signals', '/usr/lib/python2.7/unittest/signals.py', 'PYMODULE'),
- ('unittest.main', '/usr/lib/python2.7/unittest/main.py', 'PYMODULE'),
- ('unittest.runner', '/usr/lib/python2.7/unittest/runner.py', 'PYMODULE'),
- ('unittest.loader', '/usr/lib/python2.7/unittest/loader.py', 'PYMODULE'),
- ('unittest.suite', '/usr/lib/python2.7/unittest/suite.py', 'PYMODULE'),
- ('unittest.case', '/usr/lib/python2.7/unittest/case.py', 'PYMODULE'),
- ('unittest.result', '/usr/lib/python2.7/unittest/result.py', 'PYMODULE'),
- ('unittest.util', '/usr/lib/python2.7/unittest/util.py', 'PYMODULE'),
- ('inspect', '/usr/lib/python2.7/inspect.py', 'PYMODULE'),
- ('tokenize', '/usr/lib/python2.7/tokenize.py', 'PYMODULE'),
- ('token', '/usr/lib/python2.7/token.py', 'PYMODULE'),
- ('dis', '/usr/lib/python2.7/dis.py', 'PYMODULE'),
- ('opcode', '/usr/lib/python2.7/opcode.py', 'PYMODULE'),
- ('__future__', '/usr/lib/python2.7/__future__.py', 'PYMODULE'),
- ('threading', '/usr/lib/python2.7/threading.py', 'PYMODULE'),
- ('_threading_local', '/usr/lib/python2.7/_threading_local.py', 'PYMODULE'),
- ('traceback', '/usr/lib/python2.7/traceback.py', 'PYMODULE'),
- ('os2emxpath', '/usr/lib/python2.7/os2emxpath.py', 'PYMODULE'),
- ('genericpath', '/usr/lib/python2.7/genericpath.py', 'PYMODULE'),
- ('stat', '/usr/lib/python2.7/stat.py', 'PYMODULE'),
- ('ntpath', '/usr/lib/python2.7/ntpath.py', 'PYMODULE'),
- ('posixpath', '/usr/lib/python2.7/posixpath.py', 'PYMODULE'),
- ('getpass', '/usr/lib/python2.7/getpass.py', 'PYMODULE')])
diff --git a/try/sudo_script_leak/build/test_env/warn-test_env.txt b/try/sudo_script_leak/build/test_env/warn-test_env.txt
deleted file mode 100644
index bd6c59b..0000000
--- a/try/sudo_script_leak/build/test_env/warn-test_env.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-
-This file lists modules PyInstaller was not able to find. This does not
-necessarily mean this module is required for running you program. Python and
-Python 3rd-party packages include a lot of conditional or optional module. For
-example the module 'ntpath' only exists on Windows, whereas the module
-'posixpath' only exists on Posix systems.
-
-Types if import:
-* top-level: imported at the top-level - look at these first
-* conditional: imported within an if-statement
-* delayed: imported from within a function
-* optional: imported within a try-except-statement
-
-IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
- yourself tracking down the missing module. Thanks!
-
-missing module named org - imported by copy (optional)
-missing module named 'org.python' - imported by pickle (optional)
-missing module named _subprocess - imported by subprocess (conditional)
-missing module named msvcrt - imported by subprocess (conditional), getpass (delayed, optional)
-missing module named riscosenviron - imported by os (conditional, optional)
-missing module named riscospath - imported by os (conditional)
-missing module named riscos - imported by os (conditional, optional)
-missing module named ce - imported by os (conditional, optional)
-missing module named _emx_link - imported by os (conditional)
-missing module named os2 - imported by os (conditional, optional)
-missing module named nt - imported by os (conditional, optional), ntpath (optional)
-missing module named EasyDialogs - imported by getpass (optional)
diff --git a/try/sudo_script_leak/build/test_env/xref-test_env.html b/try/sudo_script_leak/build/test_env/xref-test_env.html
deleted file mode 100644
index b356aba..0000000
--- a/try/sudo_script_leak/build/test_env/xref-test_env.html
+++ /dev/null
@@ -1,5039 +0,0 @@
-
-
- modulegraph cross reference for test_env.py
-
-
-
-
-
-
-
diff --git a/try/sudo_script_leak/print_env.py b/try/sudo_script_leak/print_env.py
deleted file mode 100755
index fa07f07..0000000
--- a/try/sudo_script_leak/print_env.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/python
-
-import getpass
-import os
-
-username = getpass.getuser()
-print "my username is: " + username
-
-sudo_caller_username = os.environ.get('SUDO_USER')
-if sudo_caller_username:
- print "the sudo caller's username is: " + sudo_caller_username
-else:
- print "there is no sudo caller"
-
-null_lookup = os.environ.get('X3841232341')
-if null_lookup:
- print "very surprising, found X3841232341 in the environment"
-elif null_lookup == None:
- print "null lookup result: None"
-else:
- print "null lookup result evaluates to false, but it is not None"
-
-for k,v in os.environ.items():
- print (k, v)
-
-
diff --git a/try/sudo_script_leak/run_this.sh b/try/sudo_script_leak/run_this.sh
deleted file mode 100755
index c7ea0ad..0000000
--- a/try/sudo_script_leak/run_this.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-export PS1='\n$(/home/morpheus/src/sudo_script_leak/target.sh)\n§\h§\w\n> '
-echo $PS1
-
-#./print_env.py
-# sudo ./print_env.py
-sudo su
-
-
-
-
-
diff --git a/try/sudo_script_leak/target.sh b/try/sudo_script_leak/target.sh
deleted file mode 100755
index bb9dbce..0000000
--- a/try/sudo_script_leak/target.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#/bin/bash
-
-echo "target running"
diff --git a/try/useradd_probs/dbprintf.aux.c b/try/useradd_probs/dbprintf.aux.c
deleted file mode 100644
index edea747..0000000
--- a/try/useradd_probs/dbprintf.aux.c
+++ /dev/null
@@ -1,13 +0,0 @@
-
-#include
-#include
-#include "dbprintf.aux.h"
-
-int dbprintf(const char *format, ...){
- va_list args;
- va_start(args,format);
- int ret = vfprintf(stdout, format, args);
- fflush(stdout);
- va_end(args);
- return ret;
-}
diff --git a/try/useradd_probs/dbprintf.aux.h b/try/useradd_probs/dbprintf.aux.h
deleted file mode 100644
index 967fdae..0000000
--- a/try/useradd_probs/dbprintf.aux.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef DBPRINTF_AUX_H
-#define DBPRINTF_AUX_H
-
-int dbprintf(const char *format, ...);
-
-#endif
diff --git a/try/useradd_probs/dispatch.lib.c b/try/useradd_probs/dispatch.lib.c
deleted file mode 100644
index fcad514..0000000
--- a/try/useradd_probs/dispatch.lib.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-fork/exec/wait a command
-
-if the error values returned by the exec'd program
-are less than 1 << 16, then
-
-*/
-
-// without this #define execvpe is undefined
-#define _GNU_SOURCE
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include "local_common.h"
-#include "dispatch.lib.h"
-
-
-
-/*
- Execs the command passed in argv[0];
- Returns -1 upon failure.
-
- The wstatus returned from wait() might be either the error we returned when
- exec failed, or the return value from the command. An arbitary command is
- passed in, so we don't know what its return values might be. Consquently, we
- have no way of multiplexing a unique exec error code with the command return
- value within wstatus. If the prorgrammer knows the return values of the command
- passed in, and wants better behavior, he or she can spin a special version of
- dispatch for that command.
-*/
-int dispatch(char **argv, char **envp){
- if( !argv || !argv[0] ){
- fprintf(stderr, "argv[0] null. Null command passed into dispatch().\n");
- return -1;
- }
- #ifdef DEBUG
- dbprintf("dispatching:\n");
- char **arg = argv;
- while( *arg ){
- dbprintf("arg: %p", arg);
- dbprintf(" %s\n",*arg);
- arg++;
- }
- dbprintf("\n");
- #endif
- char *command = argv[0];
- pid_t pid = fork();
- if( pid == -1 ){
- fprintf(stderr, "fork() failed in dispatch().\n");
- return -1;
- }
- if( pid == 0 ){ // we are the child
- execvpe(command, argv, envp);
- // exec will only return if it has an error ..
- perror(command);
- return -1;
- }else{ // we are the parent
- int wstatus;
- waitpid(pid, &wstatus, 0);
- if(wstatus)
- return -1;
- else
- return 0;
- }
-}
diff --git a/try/useradd_probs/dispatch.lib.h b/try/useradd_probs/dispatch.lib.h
deleted file mode 100644
index 620c6f9..0000000
--- a/try/useradd_probs/dispatch.lib.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef DISPATCH_LIB_H
-#define DISPATCH_LIB_H
-#include "local_common.h"
-
-int dispatch(char **argv, char **envp);
-
-#endif
-
-
diff --git a/try/useradd_probs/example.txt b/try/useradd_probs/example.txt
deleted file mode 100644
index 9820a99..0000000
--- a/try/useradd_probs/example.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-2019-02-12T18:46:27Z user@host§~/subu_land/subu/try/useradd_probs§
-> ./user-mk temp6
-Checking we are running from a user and are setuid root.
-uid 49972, gid 49972, euid 0 egid 49972
-yes, uid is not zero, and euid is zero, so we are setuid to the root user.
-making the home dir path
-home dir path: "/home/temp6"
-dispatching useradd to create the user
-dispatching:
-arg: 0x7ffebf3f6800 /usr/sbin/useradd
-arg: 0x7ffebf3f6808 temp6
-arg: 0x7ffebf3f6810 -d
-arg: 0x7ffebf3f6818 /home/temp6
-
-sss_cache must be run as root
-useradd: sss_cache exited with status 1
-useradd: Failed to flush the sssd cache.
-sss_cache must be run as root
-useradd: sss_cache exited with status 1
-useradd: Failed to flush the sssd cache.
-mkdir(/home/temp6, 0x0700)
-user-mk: File exists
-
-2019-02-12T18:46:33Z user@host§~/subu_land/subu/try/useradd_probs§
diff --git a/try/useradd_probs/local_common.h b/try/useradd_probs/local_common.h
deleted file mode 100644
index 4df5bcf..0000000
--- a/try/useradd_probs/local_common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef LOCAL_COMMON_H
-#define LOCAL_COMMON_H
-
-#include
-#include
-#include
-#include "dbprintf.aux.h"
-
-#define DEBUG
-typedef unsigned int uint;
-
-#endif
diff --git a/try/useradd_probs/makefile b/try/useradd_probs/makefile
deleted file mode 100644
index d77bbbd..0000000
--- a/try/useradd_probs/makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-
-src = $(wildcard *.c)
-obj = $(src:.c=.o)
-CC=gcc
-
-all: user-mk
-
-user-mk: $(obj)
- $(CC) -o $@ $^
-
-.PHONY: clean
-clean:
- rm -rf $(obj) user-mk
-
-
diff --git a/try/useradd_probs/setuid_root.sh b/try/useradd_probs/setuid_root.sh
deleted file mode 100755
index ba33bdb..0000000
--- a/try/useradd_probs/setuid_root.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-# type these things from a sudo prompt:
-#
-
-chown root user-mk
-chmod u+rsx,u-w,go+rx-s-w user-mk
-
-
diff --git a/try/useradd_probs/user-mk.cli.c b/try/useradd_probs/user-mk.cli.c
deleted file mode 100644
index ff595f5..0000000
--- a/try/useradd_probs/user-mk.cli.c
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-
-*/
-
-#include
-#include "user-mk.lib.h"
-
-int main(int argc, char **argv, char **env){
- char *command = argv[0];
- if( argc != 2 ){
- fprintf(stderr, "usage: %s subu", command);
- return 1;
- }
- return user_mk(argv[1]);
-}
diff --git a/try/useradd_probs/user-mk.lib.c b/try/useradd_probs/user-mk.lib.c
deleted file mode 100644
index ed8c530..0000000
--- a/try/useradd_probs/user-mk.lib.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- Makes a new subu user.
-
- According to the man page, we are not alloed to free the memory allocated by getpwid().
-
-
-setfacl -m d:u:masteru:rwX,u:masteru:rwX subuname
-
-*/
-// without this #define we get the warning: implicit declaration of function âseteuidâ/âsetegidâ
-#define _GNU_SOURCE
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include "dispatch.lib.h"
-#include "user-mk.lib.h"
-
-typedef unsigned int uint;
-
-int user_mk(char *username){
-
- //--------------------------------------------------------------------------------
- #ifdef DEBUG
- dbprintf("Checking we are running from a user and are setuid root.\n");
- #endif
- uid_t uid = getuid();
- uid_t euid = geteuid();
- gid_t gid = getgid();
- gid_t egid = getegid();
- #ifdef DEBUG
- dbprintf("uid %u, gid %u, euid %u egid %u\n", uid, gid, euid, egid);
- #endif
- if( uid == 0 || euid != 0 ){
- fprintf(stderr, "this program must be run setuid root from a user account\n");
- return -1;
- }
- #ifdef DEBUG
- dbprintf("yes, uid is not zero, and euid is zero, so we are setuid to the root user.\n");
- #endif
-
- //--------------------------------------------------------------------------------
- char *home;
- size_t home_len;
- {
- #ifdef DEBUG
- dbprintf("making the home dir path\n");
- #endif
- char *prefix = "/home/";
- home_len = strlen(prefix) + strlen(username);
- home = (char *)malloc(home_len + 1);
- if( !home ){
- perror("user-mk");
- return -1;
- }
- strcpy (home, prefix);
- strcpy (home + strlen(prefix), username);
- }
- #ifdef DEBUG
- dbprintf("home dir path: \"%s\"\n", home);
- #endif
-
- /*--------------------------------------------------------------------------------
- note this from the man page:
-
- -d, --home-dir HOME_DIR The new user will be created using HOME_DIR
- as the value for the user's login directory. ... The directory HOME_DIR
- does not have to exist but will not be created if it is missing.
- */
- uid_t useruid;
- gid_t usergid;
- {
- #ifdef DEBUG
- dbprintf("dispatching useradd to create the user\n");
- #endif
- char *command = "/usr/sbin/useradd";
- char *argv[5];
- argv[0] = command;
- argv[1] = username;
- argv[2] = "-d";
- argv[3] = home;
- argv[4] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- int ret = dispatch(argv, envp);
- if(ret == -1){
- fprintf(stderr, "useradd failed\n");
- return -1;
- }
- struct passwd *pw_record = getpwnam(username);
- if( pw_record == NULL ){
- fprintf(stderr,"getpwnam failed after useradd for username, %s\n", username);
- }
- useruid = pw_record->pw_uid;
- usergid = pw_record->pw_gid;
- }
-
- //--------------------------------------------------------------------------------
- // create home directory
- // we have our reasons for doing this second (setting facls in different places)
- {
- #ifdef DEBUG
- dbprintf("mkdir(%s, 0x0700)\n", home);
- #endif
- int ret = mkdir(home, 0x0700);
- if( ret == -1 ){
- perror("user-mk");
- return -1;
- }
- ret = chown(home, useruid, usergid);
- if( ret == -1 ){
- perror("user-mk");
- return -1;
- }
- }
-
- #ifdef DEBUG
- dbprintf("finished user-mk without errors\n", username);
- #endif
- return 0;
-}
diff --git a/try/useradd_probs/user-mk.lib.h b/try/useradd_probs/user-mk.lib.h
deleted file mode 100644
index 11ab8ee..0000000
--- a/try/useradd_probs/user-mk.lib.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef SUBU_MK_0_LIB_H
-#define SUBU_MK_0_LIB_H
-
-int user_mk(char *subuname);
-
-#endif
diff --git a/user/LICENSE b/user/LICENSE
new file mode 100644
index 0000000..3cfdbec
--- /dev/null
+++ b/user/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Reasoning Technology
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/user/README b/user/README
new file mode 100644
index 0000000..7af191c
--- /dev/null
+++ b/user/README
@@ -0,0 +1 @@
+Subservient user implementation. Just getting started, not much here yet.
diff --git a/user/cantari/subu b/user/cantari/subu
new file mode 100755
index 0000000..f601bb6
--- /dev/null
+++ b/user/cantari/subu
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+
+# to make audio work will need to do this:
+# > sudo dnf install pulseaudio-utils
+# > pactl load-module module-native-protocol-tcp
+# To load a specific module to the PA server, you add it to /etc/pulse/default.pa:
+# I created the file because it was not there...
+
+#set -x
+
+subu=$1
+stem=$2
+
+
+if [ ! -x "/usr/local/bin/user-stem" ]; then
+ echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
+ exit 1
+fi
+
+if [ -z "$subu" ]; then
+ echo "no subuser name supplied"
+ exit 1
+fi
+
+machine="$(hostname)"
+xkey=$(xauth list | grep "$machine" | head -1 | awk '{print $3}')
+
+if [ -z "$xkey" ]; then
+ echo "xauth key not found"
+ exit 1
+fi
+
+# stem includes all characters up to the first '-'
+if [ -z "$stem" ]; then
+ stem=$(/usr/local/bin/user-stem)
+fi
+
+subu_username="$stem-$subu"
+subu_user_directory=/home/"$stem"/"$subu"/user
+bashrc="$subu_user_directory/.bashrc"
+xauthority="$subu_user_directory/.Xauthority"
+
+read -r -d '' script0 <<-EOF
+ cd "$subu_user_directory" \
+ ;export DISPLAY=$DISPLAY \
+ ;export NO_AT_BRIDGE=1 \
+ ;export PULSE_SERVER=localhost \
+ ;touch "$xauthority" \
+ ;xauth add "$DISPLAY" . "$xkey" \
+ ;gnome-terminal --title="$subu"
+EOF
+
+
+sudo su -l "$subu_username" -c "$script0"
+
+#just hangs
+#sudo -u "$subu_username" sh -c "$script0"
+
+#set +x
diff --git a/user/cantari/subu_add b/user/cantari/subu_add
new file mode 100755
index 0000000..4363865
--- /dev/null
+++ b/user/cantari/subu_add
@@ -0,0 +1,48 @@
+#!/bin/bash
+# must have commands rsync and user-stem
+# user-stem is in the system repo
+#
+# wish we could set the uids and gids so that backups would restore properly on other systems but it is too much trouble
+# to do in a shell script. Perhaps in the python code for the actual release.
+set -x
+
+subu=$1
+stem=$2
+
+if [ ! -x "/usr/local/bin/user-stem" ]; then
+ echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
+ exit 1
+fi
+
+if [ -z "$subu" ]; then
+ echo "no subuser name supplied"
+ exit 1
+fi
+
+# stem includes all characters up to the first '-'
+if [ -z "$stem" ]; then
+ stem=$(/usr/local/bin/user-stem)
+fi
+
+subu_username="$stem-$subu"
+admin_username="$stem-admin"
+
+subu_home="/home/$stem"
+subu_dir="$subu_home/$subu"
+subu_user="$subu_dir"/user
+
+admin_home="/home/$stem/admin"
+subu_initial_files="$admin_home"/user/library/subu_initial_files
+
+sudo useradd --badname --home-dir "$subu_dir" "$subu_username"
+sudo usermod -aG "$subu_username" "$admin_username"
+
+if [[ ! -d "$subu_user" ]]; then
+ sudo mkdir "$subu_user"
+ sudo chown "$subu_username":"$subu_username" "$subu_user"
+fi
+
+subu_initialize "$subu" "$stem"
+
+
+
diff --git a/user/cantari/subu_del b/user/cantari/subu_del
new file mode 100755
index 0000000..a8a7efd
--- /dev/null
+++ b/user/cantari/subu_del
@@ -0,0 +1,67 @@
+#!/bin/bash
+# must have command user-stem
+# user-stem is in the system repo
+#
+# currently this is setup to be run by any user who has sudo - it doesn't have to be run by the user-admin account; though chances are it will be.
+#
+# userdel -r deletes both the /var/spool/mail/user and the user's home directory. We don't want to delete the old data just in case there
+# is something important there. However we can not leve the old /var/spool/mail/user file under /var/spool/mail in case another subu is
+# created later with the same name. Hence we will move the /var/spool/mail/user file into the users home directory. We will give ownership
+# of the old home directory to the admin.
+#
+# I have run into a problem that subu users do not inherit the MAIL variable, I wouldn't trust it anyway. I do not know if userdel -r
+# references the MAIL variable. I will hard code a local variable to /var/sppol/mail. This must be changed for systems that put the mail spool
+# file eleswhere.
+#
+#set -x
+
+subu=$1
+stem=$2
+
+if [ ! -x "/usr/local/bin/user-stem" ]; then
+ echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
+ exit 1
+fi
+
+if [ -z "$subu" ]; then
+ echo "no subuser name supplied"
+ exit 1
+fi
+
+# stem includes all characters up to the first '-'
+if [ -z "$stem" ]; then
+ stem=$(/usr/local/bin/user-stem)
+fi
+
+subu_username="$stem-$subu"
+admin_username="$stem-admin"
+subu_home="/home/$stem/$subu"_root
+archive_suffix=";1"
+archive_home="$subu_home$archive_suffix"
+mail_source_dir="/var/spool/mail"
+mail_source_file="$mail_source_dir/$subu_username"
+mail_target_file="$subu_home/mail_spool"
+
+if [ -e "$archive_home" ]; then
+ echo "there is already a saved directory for a deleted subu with this name, move this out of the way first: $archive_home"
+ exit 1
+fi
+if [ ! -d "$mail_source_dir" ]; then
+ echo "could not find mail spooler directory: $mail_source_dir"
+ exit 1
+fi
+
+if [ -e "$mail_target_file" ]; then
+ echo "there is already file system object where we planned to move the deleted user's mail spool, which is here: $subu_home/mail_spool"
+ exit 1
+fi
+
+sudo killall --signal 5 --wait --user "$subu_username"
+sudo mv "$mail_source_file" "$mail_target_file"
+sudo chmod -R go-rwx "$subu_home"
+sudo chown -R "$admin_username":"$admin_username" "$subu_home"
+mv "$subu_home" "$archive_home"
+sudo groupdel -f "$subu_username"
+sudo userdel "$subu_username"
+
+#set +x
diff --git a/user/cantari/subu_initialize b/user/cantari/subu_initialize
new file mode 100755
index 0000000..8e57407
--- /dev/null
+++ b/user/cantari/subu_initialize
@@ -0,0 +1,59 @@
+#!/bin/bash
+# symbolic links made this complicated
+#set -x
+
+subu=$1
+stem=$2
+
+if [ ! -x "/usr/local/bin/user-stem" ]; then
+ echo "no /usr/local/bin/user-stem program found (it is in the system repo)"
+ exit 1
+fi
+
+if [ -z "$subu" ]; then
+ echo "no subuser name supplied"
+ exit 1
+fi
+
+# stem includes all characters up to the first '-'
+if [ -z "$stem" ]; then
+ stem=$(/usr/local/bin/user-stem)
+fi
+
+subu_username="$stem-$subu"
+subu_home="/home/$stem/$subu"
+subu_initial_files="/home/$stem/subu_initial_files"
+
+# install always derefs sym links ... actually it didn't work at all here
+#shopt -s dotglob
+#sudo install -o "$subu_username" -g "$subu_username" -t "$subu_home" "$subu_initial_files"/*
+
+# free a brief moment, files that appear in the initial subu will have their subu_initial
+# ownership instead of being owned by the subu
+#find "$subu_initial_files" -mindepth 1 -exedir copy({}
+# -execdir cp -a {} "$subu_home" \; \
+# -execdir chown -h "$subu_username":"$subu_username" "$subu_home"/{} \;
+# cp --remove-destination -RP "$1" "$2"
+
+function copy {
+ s0="$1"
+ filename="${s0:2}"
+ destination_directory="$2"
+ username="$3"
+
+ source_directory=$(pwd)
+ source_path="$source_directory"/"$filename"
+ destination_path="$destination_directory"/"$filename"
+ echo "ln -fs" "$source_path" "$destination_path"
+ #ln -f did work when the existing object was a file rather than anotehr link so ..
+ sudo rm -f "$destination_path"
+ sudo ln -s "$source_path" "$destination_path"
+ sudo chown -h "$username":"$username" "$destination_path"
+}
+export -f copy
+
+find "$subu_initial_files" -mindepth 1 -execdir \
+ bash -c 'copy "$1" "$2" "$3"' _ {} "$subu_home" "$subu_username" \;
+
+
+#set +x
diff --git a/user/document/cant_access_bus.txt b/user/document/cant_access_bus.txt
new file mode 100644
index 0000000..dfb250d
--- /dev/null
+++ b/user/document/cant_access_bus.txt
@@ -0,0 +1,4 @@
+
+after changing to the new user:
+
+> export NO_AT_BRIDGE=1
diff --git a/user/document/note.txt b/user/document/note.txt
new file mode 100644
index 0000000..3cdd7d7
--- /dev/null
+++ b/user/document/note.txt
@@ -0,0 +1,42 @@
+
+this does not apply to the current scripts, but rather the setuid code
+
+subu-mk-0
+
+ 1. We have to make the subu for step 2 so that we will have subu_uid and subu_gid
+ to work with, but we delay this for as long as possible, as the program might
+ first bail due to other errors.
+
+ 2. Then we add user access via setfacl to masteru's home directory and to
+ subu_land, so that we have permissions to make the home directory.
+
+ 3. Then as subu we create the home directory. .. I wonder where the system
+ gets the umask for this? Perhaps we should create the dir, and then change
+ the ownership instead?
+
+ 4. Still as subu, we add facls to our directory to give masteru access.
+
+finished, good part is that we never need to move back to root.
+
+setfacl -m u:subu:x masteru
+setfacl -m u:subu:x masteru/subu_land
+setfacl -m d:u:masteru:rwX,u:masteru:rwX subu
+
+
+using luseradd to make the subu is a circular problem because we need to setfacls
+to allow the creating of the home directory inside the masteru/subu_land, but
+to set facls we need the uid from luseradd. So..
+ 1. luseradd without creation of a home directory. We can provide the path,
+ but can't create it.
+ 2. get the uid, and set the facls
+ 3. create the home directory
+
+Step 3 is a bit of a problem, because subu's don't have write permission for
+subu_land/
+
+.. or maybe not, luseradd puts users in /home, but those users don't have
+write permissions there either, so I'll try and see what happens.
+
+given all the funky security stuff recently, I really need to call luseradd
+to get the user added. Wish there was a C programming interface. My gosh,
+python has one, and you can't if setuid root python programs.
diff --git a/user/document/real_uid.txt b/user/document/real_uid.txt
new file mode 100644
index 0000000..b25e817
--- /dev/null
+++ b/user/document/real_uid.txt
@@ -0,0 +1,19 @@
+
+Real uid is a poorly named term for the uid of the user who launched the
+process. The uid that the process has been set to is the effective uid. There
+is a third stored uid in a process's record. Hence the uid being used by the
+OS will be set to one of these.
+
+Our subu-mk-0 program wants to create a subservient user to a master user. The
+master user is known via the real uid. The effective user will be that of root,
+as the script needs root privilege to run adduser.
+
+sudo resets the real uid, and there is no reliable approch then to create a subu-mk-0
+program run by sudo. A setuid root program is needed. Only compiled executables can
+be setuid root on linux.
+
+There is an environment variable given to programs run by sudo, $SUDO_USER. Sudo sets
+it, so if called from sudo then that works. It could be set by another user, even
+if that user is root or not.
+
+I will make a setuid C program. Too bad, had written this in Python.
diff --git a/user/document/real_uid_bug.pdf b/user/document/real_uid_bug.pdf
new file mode 100644
index 0000000..2d4a83d
Binary files /dev/null and b/user/document/real_uid_bug.pdf differ
diff --git a/user/document/sound.txt b/user/document/sound.txt
new file mode 100644
index 0000000..0a02f87
--- /dev/null
+++ b/user/document/sound.txt
@@ -0,0 +1,28 @@
+
+before changing users:
+
+user must be in group audio
+
+> sudo dnf install pulseaudio-utils
+> pactl load-module module-native-protocol-tcp
+
+after changing users:
+
+> export PULSE_SERVER=localhost
+
+According to
+https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/CLI/#default.pa
+the module load command goes in /etc/pulse/default.pa and the pactl command is not needed,
+but this did not work:
+
+ /etc/pulse/default.pa
+ load-module module-native-protocol-tcp
+
+this did not work
+seems this must be run by the login user, not even root can do it:
+
+ pactl load-module module-native-protocol-tcp
+
+also requires restart of google-chrome etc.
+
+for now I will add this the .bashrc file for admin
diff --git a/user/document/src.txt b/user/document/src.txt
new file mode 100644
index 0000000..902157b
--- /dev/null
+++ b/user/document/src.txt
@@ -0,0 +1,9 @@
+
+ src-da a simple doubling size expanding array in C
+ src-tranche splits source code into multiple files. A poor man's 'makeheaders'.
+src-dispatch runs a function or shell command as a separate process
+ src-db sqlite schema and interface for subu
+ src-0 The layer 0 commands for subu. Some are setuid root programs.
+ src-py The application layer
+
+
diff --git a/user/document/subu-mk-0.txt b/user/document/subu-mk-0.txt
new file mode 100644
index 0000000..c3146bf
--- /dev/null
+++ b/user/document/subu-mk-0.txt
@@ -0,0 +1,104 @@
+I. If we allowed the subu_home directory to be put anywhere, this script could
+ be used by masteru gain access to any directory on the system. Hence, we have
+ to add some constraints:
+
+ constraint 1) the subuhome directory must not already exist, not as a
+ directory or as any other type of object.
+
+ constraint 2) masteru must already have privledges to reach access $(masteru_home)/subuland
+
+ constraint 3) subuhome may only be placed under the directory $(masteru_home)/subuland.
+
+ convention 4) only subuhome directories may be placed in $(masteru_home)/subuland.
+
+ -> without constraint 1), exploit 1
+
+ Suppose that a wily masteru was able to move an inaccessible directory that
+ he or she wanted access to and place it under $(masteru_home)/subuland.
+ Typically such directories are not moveable by wiley users in the first
+ place, but suppose the wily masteru found such a directory.
+
+ Alternatively suppose the wily masteru made a directory under
+ $(masteru_home)/subuland of his or her own, and placed an inaccessible file
+ or subdirectory inside of it.
+
+ Alternatively suppose that the wily masteru made $(masteru_home)/subuland a
+ hard link or a symlink to a directory that contained a subdirectory that
+ masteru did not have access to.
+
+ The the wiley masteru could then create a subu by the same name as the
+ directory he desired access to, and trick the foolish subu-mk-0 into giving
+ him or her access.
+
+ -> without constraint 2) exploit 2
+
+ Then the masteru could place subu directories in places he can not access.
+ The foolish subu-mk-0 program would then add 'x' acls to as to reach this
+ place. The masteru could then change identity to the subu, (i.e. enter the
+ container), and then reach that place he or she could not reach before.
+
+ -> without constraint 3) exploit 3
+
+ If masteru looses x privlege to a place, subu might keep it, and then
+ exploit 2 would work despite the existence of constraint 2. It would be
+ unusual that masteru not have x privledges to masteru_home. Furthmore, we
+ decree that masteru has x privige to subuland. Hence, exploit 3 can be
+ prevented by following this convention.
+
+ -> without convention 4) exploit 4
+
+
+II. the ownership flaw
+
+subu will own the files and directories that it makes. The default acls are
+such that masteru will also have access to subu's file. This defines the master
+user / subservient user convention on the filesystem.
+
+However, because subu owns the files and directories, it can modify the
+acls. Thus a wily subu can lock the masteru out.
+
+Perhaps the master has a 'fix perms' script. However, there is no enshrined
+relationship in the system between the masteru and the subu, so the system won't
+know for sure the subu belongs to the masteru, and thus can not allow masteru to
+change the supposed subu's permissions to give back access to masteru.
+
+Perhaps we propose that instead masteru owns the files and directories of
+subuhome, and subu is given access privilege through acls and default acls.
+Indeed, then subu can't change the acls on these existing files. However, if
+subu is allowed to own processes, then those processes might create files owned
+by the subu, and the subu can lock the master out from access to these new
+files.
+
+How about a variation. Perhaps the subu shares the uid of the masteru, but has
+a different gid. The subuhome then has the sticky bit set on the group access,
+so all files created remain the same gid. subu process are masteru processes,
+however the gid of the process is that of the subu's. Masteru can then control
+both the files and the processes, but in absence of this control, the subu has
+control.
+
+Then we don't make a new user when we make a subu, we make a new group. We then
+have to add utilities for 'logging into the subu' which goes to a different home
+directory based on the group being logged into.
+
+III. other approaches
+
+Groups don't seem to offer much help, the owner is still the owner.
+
+A volume can be mounted without the subu being able to modify the facls. I
+don't know if the default facls still apply, but if so, then this would be a
+solution.
+
+bindfs can translate uids and gids. The same directory can appear in two
+places, in one place owned by the subu and in another owned by the masteru.
+This looks to be potentially a clean solution. It would also be recursive,
+i.e. a subu could have subus. I'll try this one.
+
+One possibility is for the subusers to appear in /home/ as normal users. Then
+masteru bindfs with translation into subuland. Everything in subuland appears
+to be owned by masteru. This is a transparent way to give masteru control over
+all the files.
+
+Then is the question of being able to control the processes being run by a subu.
+We will need an /etc/ file that pairs masters and subus.
+
+
diff --git a/user/document/subu.txt b/user/document/subu.txt
new file mode 100644
index 0000000..d422784
--- /dev/null
+++ b/user/document/subu.txt
@@ -0,0 +1,68 @@
+
+subu is short for subservient user.
+
+A subu is much like any other user. It has an entry in /etc/passwd, and a home
+directory. As for other users this home directory is most likely under /home.
+Direct login to the subu might be barred, though that is not necessarly the case.
+
+Each subu has two names. One is its 'subu_username'. The other is its
+'subuname'. The subu_username is autogenerated. When using our tools, one
+never needs to know the subu_username. However, the entry in /etc/passwd will be
+the generated name, and the home directory will have the generated name. The
+command 'subu-username subuname' will print the subu_username.
+
+Each subu belongs to a master user, known as masteru. A given masteru may have many
+subus. The masteru is a different user than any of the subu's that are
+subservient to it.
+
+Each masteru has a top level subdirectory called 'subuland'. In this sub
+directory the masteru will find all of its subu home directories. The masteru
+will then see all subu owned files in the subuland through the illusion that the
+masteru owns them rather than the corresponding subu. Thus the master may move
+files around using a regular file navigator.
+
+Actually the subus will not appear in subuland until masteru runs the command
+'subu-mount'. This is normally done when masteru logs in.
+
+The masteru may create and delete subus at will. The masteru may set default
+nice values, renice, or kill subu processes. The masteru may set limits for a
+subu. In fact, the masteru is a bit like root relative to its subus.
+
+There is a control panel that masteru may use. It has a matrix of rectangles,
+where in each rectangle, there is information about each subu's processes and
+disk usage.
+
+The masteru may set the subu for each launched process.
+
+---
+subu-username
+
+prints the username
+returns an error code
+
+---
+subu-number
+
+prints a new maximums subu number.
+returns an error code
+
+These numbers are used in synthesizing usernames. Used for testing, should not
+appear in any scripts.
+
+---
+subu-mount
+
+mounts all of the subus for the given masteru
+returns an error code
+
+---
+subu-mk-0
+
+primitve makes a new subu
+returns an error code
+
+---
+subu-rm-0
+
+primitive removes a subu
+returns an error code
diff --git a/user/document/subu_as_group.txt b/user/document/subu_as_group.txt
new file mode 100644
index 0000000..46da5b9
--- /dev/null
+++ b/user/document/subu_as_group.txt
@@ -0,0 +1,22 @@
+
+note the 'ownerhips flaw' in subu-mk-0.txt. Could groups help with this?
+
+Suppose that instead of creating the subu as a separate user, it is created as a group. Masteru then has a
+number of separate groups. To run a process as the subu, the uid is set to the masteru, and the gid is set
+to the subu. .. but then the process would be able to modify anything owned by masteru
+
+suppose subu belongs to masteru's group .. then all subus are the same and can write each other's data.
+
+suppose masteru belongs to subu's group .. subu is still its own unique user, so it can change group permissions
+on files it makes and lock masteru out.
+
+suppose there is a unique third party, the mediator. Both masteru and subu belong to its group. A
+processes running as subu can only create files in directories that have mediator group permissions. subu still
+owns the files and directories it creates, so ..
+
+suppose the group sticky bit is set. The subu must belong to the group to write anything in the directories.
+Anything it writes are owned by the group. Suppose masteru is also in the this group. Though a mean subu
+could not take away the group ownership, it could
+
+
+
diff --git a/user/document/todo.txt b/user/document/todo.txt
new file mode 100644
index 0000000..96099e2
--- /dev/null
+++ b/user/document/todo.txt
@@ -0,0 +1,17 @@
+
+2022-08-03T15:50:23Z
+
+the group sticky bit scheme has an interesting drawback, the group owner can not
+change permissions of a file owned by the subu. Hence the administrative user who
+is a group owner can not act like an admin. Will need to use facl instead.
+
+ran across this because Lustucru, who is a repo user, can not adjust permissions of
+repo files *and vice versa*. If Lustru creates a file, the group is appropriatly
+sticky, and becomes 'repo', but as Lustcru *owns* such files the repo user may
+not adjust their permissions.
+
+Hence, if the admin owns a file, though it is group of the subu, the subu can
+not change permissions (can not make them more permissive, or not change them at all?).
+
+
+
diff --git a/user/document/try.txt b/user/document/try.txt
new file mode 100644
index 0000000..c157aee
--- /dev/null
+++ b/user/document/try.txt
@@ -0,0 +1,5 @@
+
+sudo_leak_script - demonstrates script injection through the pompt environement variable
+SUDO_USER - shows that userland scripts can trick other scripts into believing they are running under sudo.
+print_env.py - prints getuid, geteuid, some other info, and the value of each environment variable
+libuser - try out libuser
diff --git a/user/document/usb.txt b/user/document/usb.txt
new file mode 100644
index 0000000..4e62275
--- /dev/null
+++ b/user/document/usb.txt
@@ -0,0 +1,18 @@
+
+
+added file /etc/udev/rules/50-usb-scale.rules
+SUBSYSTEM=="usb" ,ATTR{idVendor}=="1d50" ,ATTR{idProduct}=="60fc" ,MODE="0666" ,OWNER="Thomas-Internet"
+
+SUBSYSTEM=="usb" \
+,ATTR{idVendor}=="1d50" \
+,ATTR{idProduct}=="60fc" \
+,MODE="0666" \
+,OWNER="Thomas-Internet"
+
+
+udevadm control --reload-rules
+udevadm control --reload-rules && udevadm trigger
+
+systemctl status systemd-udevd
+
+firefox can find the usb hardward key with these settings, google-chrome can not.
diff --git a/user/document/video.txt b/user/document/video.txt
new file mode 100644
index 0000000..e60e4f0
--- /dev/null
+++ b/user/document/video.txt
@@ -0,0 +1,6 @@
+
+user must be in group video
+
+I added 666 permissions to udev for the USB camera but doubt this
+is needed.
+
diff --git a/user/makefile b/user/makefile
new file mode 100755
index 0000000..01d6747
--- /dev/null
+++ b/user/makefile
@@ -0,0 +1,56 @@
+
+# nice idea, but the modules have to be made in the correct order, perhaps run this to check the module list
+# MAKEABLE= $(shell find module tool -name 'makefile' | grep -v deprecated)
+
+CLEANABLE=\
+ module/da\
+ module/da/test\
+ module/tranche\
+ module/debug\
+ module/dispatch\
+ module/subu-0
+
+MAKEABLE=\
+ module/da\
+ module/da/test\
+ module/tranche\
+ module/debug\
+ module/dispatch\
+ module/subu-0
+
+
+.PHONY: all
+all:
+ for dir in $(MAKEABLE); do make -C $$dir dist-clean dep lib exec share || true; done
+
+.PHONY: info
+info:
+ @echo "MAKEABLE:" $(MAKEABLE)
+
+.PHONY: setup
+setup:
+ for dir in $(MAKEABLE); do make -C $$dir setup || true; done
+
+.PHONY: dep
+dep:
+ for dir in $(MAKEABLE); do make -C $$dir dep || true; done
+
+.PHONY: update
+update:
+ for dir in $(MAKEABLE); do make -C $$dir lib exec share || true; done
+
+.PHONY: clean
+clean:
+ for dir in $(CLEANABLE); do make -C $$dir clean || true; done
+
+.PHONY: dist-clean
+dist-clean : clean
+ for dir in $(CLEANABLE); do make -C $$dir dist-clean || true; done
+ for i in $(wildcard module/share/lib/*); do rm $$i; done
+ for i in $(wildcard module/share/inc/*); do rm $$i; done
+ for i in $(wildcard module/share/bin/*); do rm $$i; done
+
+
+
+
+
diff --git a/user/module/da/doc/Acc.txt b/user/module/da/doc/Acc.txt
new file mode 100644
index 0000000..24ae5ba
--- /dev/null
+++ b/user/module/da/doc/Acc.txt
@@ -0,0 +1,118 @@
+
+
+Memory accounting.
+
+----------------------------------------
+Objectives:
+
+1) to detect memory leaks
+2) to help identify the source of memory leaks
+3) to provide useful information during debug sessions
+
+Initially considered making a tool that would work with source code that was unaware of
+Acc. This is no longer an objective. Consequently it is acceptable that source code
+must be modified. Possible examples include having to use a special version of malloc
+and free, and/or having to add small amounts of overhead code.
+
+----------------------------------------
+Requirements:
+
+1. To be able to turn accounting off and thus to minimize its impact. It is acceptable
+that doing so requires a second compile.
+
+2. For specific groups of functions to be able to be tracked independently, or
+not at all.
+
+3. For specific callers to be tracked separately or not at all.
+
+----------------------------------------
+Requirements Use Case Examples:
+
+Requirement 2, Use Case 1: Say there is a dynamic array and a dynamic tree structures which both make
+use of malloc and free. Then malloc/free balance for the dynamic array is reported
+separately than that for the dymaic tree.
+
+Requirement 3, Use Case 1 A dyamic array called from user code should be accounted for, while
+a dynamic array used for the accounting code itself does not.
+
+Requirement 3, Use Case 2 Say that a dyamic array is used by a dynamic tree. This dynamic array should
+be tracked separately from other dynamic arrays. Perhaps it is tracked as part of the rest of
+the tree code, or perhaps it is tracked as part separately from both the rest of the array and tree.
+
+----------------------------------------
+Proposed 'Channel Architecture'
+
+1. Channels are created with an open call, and are retired with a close
+call. Channels might be structs, or integers, etc. (enum tags) (changed name from handles to
+channels to be suggestive of the integer impelementation)
+
+ Acc handle;
+ acc_open(handle);
+
+ or perhaps
+
+ Acc handle = acc_open();
+
+ also then
+
+ acc_close(handle);
+
+2. channel_NULL, means that no accounting should be done
+
+3. dynamic structures are given and keep a copy of the memory accounting channel
+they are initialized with. Integer (enum) handles are an advantage here as they are
+small. (add another field to the da struct for the accounting channel)
+
+Specifically, da_init (was da_alloc) would take a handle operand.
+
+So something like:
+
+ Acc acc_channel = acc_open("Data Structure Martyrs");
+ Da x;
+ da_init(x, acc_channel);
+ .. .. lots of code, possible many acc_report(channel) calls ..
+ acc_report(acc_channel);
+ acc_close(acc_channel);
+
+A dynamic array is initialized with da_init, and the handle is written to a
+field in the Da struct. da_init should accept a memory accounting channel
+number. Constituent acc_malloc and acc_free calls in the dynamic array are
+given the handle, copied in from the Da struct value.
+
+ acc_malloc(size, channel);
+ acc_free(pt, channel)
+
+4. acc_malloc keeps a list of pointers it allocates, say acc_malloc_list[channel]
+5. acc_free(pt) removes pt from the acc_malloc_list, if not found adds it to the acc_spurious_free list[channel]
+
+6. each channel is associated with a mode of accounting. There are currently three modes:
+ 0) do nothing 1) count balance only 2) full pointer accounting Chances are for debugging
+ the user will want mode 2. For non critical code it make sense to run in mode 1. For
+ performance critical code, run in mode 0. Want a switch to turn it all off globally (no header hacks)
+
+ The default is no accounting.
+
+Modes: enum with mode options, stored in array (not a da array)
+-just tells how to run report, is not scope, channels are scope
+
+7. acc_report pretty prints the list of values on the outstanding malloc and spurious free lists,
+if not too many. If too many then it reports a count.
+ Modes tell how to run: Option 1: just true or false Option 2: give me something reasonable (like above) 3: count 4: pointers
+
+8. the header file redefines malloc to something that prints to stderr a warning when called, but only does
+so one time (not every time it is called). same for free. #define malloc crash_and_burn
+
+----------------------------------------
+How the proposed architecture meets requirements
+
+1. requirement 1 is achieved by architecture 6. as all channels may be turned off.
+
+2. requirement 2 is achieved by giving all acc_alloc, and acc_free members of a group
+the same channel. In the case of Da this is achieved by putting the channel in the Da struct,
+and then all routines referencing the struct.
+
+3. requirement 3. consider the use case, that of a Da (dynamic array) and a Dt (dyamic tree).
+ The dynamic tree uses a Da, and when it calls da_init it gives the Da a different channel
+ than the channels used by others. If the Da is to be tracked along with the rest of the tree.
+ Suppose the tree is created with dt_init(tree_channel), then internally the tree creates the
+ arrays it uses as da_init(tree_channel) also. Then they track together.
diff --git a/user/module/da/doc/acc_usermanual.txt b/user/module/da/doc/acc_usermanual.txt
new file mode 100644
index 0000000..9824353
--- /dev/null
+++ b/user/module/da/doc/acc_usermanual.txt
@@ -0,0 +1,23 @@
+Explanation of process for using accounting code.
+
+ First,
+ AccChannel acc_live_channels; needs to be declared at global scope in the CLI file.
+ acc_open(&acc_live_channels, mode); needs to be called in main.
+ ---acc_NULL or acc_SELF only, decide whether to track memory allocation for channels themselves
+
+ To begin an accounting channel, declare an Acc_channel and initialize it by passing a pointer to it into acc_open. You will also need to pass in a Mode.
+
+-acc_NULL does not track
+-acc_BALANCE will give you a count of outstanding mallocs and spurious frees when reported
+-acc_FULL will give you a robust accounting with a list of up to 10 outstanding/spurious pointers, then it will default to a count instead and just give the first 10 addresses.
+-acc_SELF is solely for the accounting software to account for its own memory allocation, therefore listing outstanding/spurious pointers to Acc_channels in the same format as acc_FULL.
+
+ When initializing a Da, you must pass in a pointer to the Da, its element size, and a pointer to the (already initialized) Acc_channel on which it will be stored into da_init. Among its other initialization tasks, this function will call acc_malloc for the base pointer of the Da with the appropriate channel.
+ When allocating memory for anything else in the program, you must pass the size of the memory to be allocated as well as the channel on which it is to be tracked to acc_malloc.
+
+ To free a Da, pass a pointer to the Da into da_free. It will automatically call acc_free for the base pointer, set the size to 0 and set the channel to NULL.
+ To free anything other else in the program, simply call acc_free, passing in the pointer and the channel the pointer is being tracked in. This will zero it out from the channel, call da_pts_nullify to clean up any zeroes at the end of the channel, and then free the pointer.
+
+ To find out if there are any memory leaks in a particular channel, call acc_report with a pointer to the Acc_channel as the argument. Depending on the channel's mode, it will pretty print a current report of memory allocation and frees. If you call a report on acc_live_channels and it is set to Mode acc_SELF, it will report on the memory currently in use for the accounting system itself.
+
+ When finished with a channel, call acc_close and pass in the channel pointer. This will free up the memory used by it and remove it from the acc_live_channels outstanding_malloc list if there is SELF tracking on. Any allocation information being tracked by this channel will be lost, so it is advised to call acc_report before deciding whether to free the channel.
diff --git a/user/module/da/doc/da_lib_doc.txt b/user/module/da/doc/da_lib_doc.txt
new file mode 100644
index 0000000..a98f53c
--- /dev/null
+++ b/user/module/da/doc/da_lib_doc.txt
@@ -0,0 +1,125 @@
+Explanations of primary goals and step-by-step actions of each function in da.lib.c.
+
+Currently needs editing because descriptions based on old functions. So, some are not up to date or even no longer existent.
+
+/*
+void da_alloc - The primary goal of this function is to allocate the initial Da in memory and assign the appropriate pointers that correspond. It is much like an initializer in a class. It makes an array large enough to hold 4 elements of the element size passed in as an argument.
+- This function takes a Da pointer called dap and a size_t called element_size.
+- It dereferences the Da pointer and assigns the value of the argument element_size to the element_size size_t variable in the Da.
+- Then it assigns 4 times the value of the argument element_size to the size size_t variable in the Da, thereby making the size of the array to be created large enough to hold 4 elements.
+- Then it uses malloc to allocate an array in memory of this size and pointed to by dap and assigns the pointer to the first element in the array to the char pointer labeled base in the dap Da.
+- Then it assigns the same address to the end pointer. This is just to start off, as the end pointer will be advanced as elements are inserted.
+
+void da_free - The primary goal of this function is to "free" the space in memory where the Da whose pointer is passed in is located. It does not actually delete the data in that location, but frees the memory to be reused by removing the tie between the address and the pointer and removing the span of memory assigned to the Da by setting its size to zero.
+- This function takes a Da pointer called dap.
+- It calls the C function free and passes it the base pointer (which has been assigned the address of first element in the array) of the Da.
+- Then it assigns the size variable in the Da the value of 0.
+
+void da_rewind - The primary goal of this function is to start over in inserting elements in this array. It "rewinds" the end pointer to the base so that, while it does not actually erase the data at those locations in memory, it acts as if there is nothing in the array. New elements will be inserted starting at the base again, overwriting whatever old data was there.
+- This function takes a Da pointer called dap.
+- It takes the value of the base variable of dap and assigns it to the end variable of dap.
+
+bool da_empty - The main goal of this function is to test whether a Da is empty. It will return true if there are no elements in the array and false if there are. For example, it should return true for a brand new Da or for one that has been rewinded, but not for one whose end pointer has moved due to element insertion.
+- This function takes a Da pointer called dap.
+- If the end pointer of dap is the same as the base pointer of dap, the function will return true (as a bool).
+
+size_t da_length - The primary goal of this function is to report how many elements are currently store in a Da.
+- This function takes a Da pointer called dap.
+- It returns the result of an operation that divides the distance from the end pointer to the base pointer of dap by its element size.
+
+void da_rebase - The primary goal of this function is to redirect pointers that previous pointed into a Da to the new location of the array after it has been doubled.
+- This function takes a Da pointer called dap, a char pointer called old_base (presumably the old base pointer from an expanded array), and a void pointer called pta.
+- It initializes a char pointer to a pointer called pt with a value of the pointer to the pointer to the void pointer pta. This would be like having a 2D array pointer because it points to the first element in an array of pointers. The pta would be a pointer to some other thing that had been making reference to dap before it was expanded and needs to be re-pointed into the new position of dap in memory.
+- It initializes a size_t variable called offset with a value of the difference between the pointer to the array pointer pt and the old_base passed in.
+- Then it assigns the pointer to pt with the sum of the base pointer of dap (presumably the new base after an expansion) and the offset.
+
+ char *da_expand - The primary goal of this function is to double the size of the array. It saves and "returns the old base so that existing pointers into the array can be moved to the new array" later. It doubles the size by allocating a new array with size of the variable new_size and copies the old data into it via memcpy with the old base, the end_offset it took from the old Da, and the corresponding element size. Then it frees the old pointer and reassigns all the variables and pointers to the newly allocated values.
+- This function takes a Da pointer called dap.
+- It initializes a size_t variable, declaring it to be named end_offset and assigning it the value of the difference between the pointer to the end of dap and the pointer to the base of dap, aka the current offset of the end pointer.
+- Then it initializesa char pointer called old base with value of the current address of the base of dap.
+- Then it initializes a size_t variable called new_size with the value of the size of dap multiplied by 2 (via left-shift 1, << 1).
+- Then it initializes a char pointer called new_base to a newly allocated array of the new size via the malloc C function.
+- It uses memcpy to copy the data from dap to the new Da by taking all the data withing the range from the old base to the end of the determined by the end offset and the element size of dap.
+- It calls the C function free to deallocate the old base pointer.
+- It changes the base pointer of dap to new_base and the end pointer of dap to where it is offset after the already inserted data.
+- It changes the size variable of dap to new_size.
+- It returns the old_base char pointer.
+
+**** No longer in code.
+bool da_endq -The primary goal of this function is to assure the pointer passed in has not "run off the end of the area currently allocated for the array," that is to say, the end of the data currently contained by the Da, the current address given by the end pointer.
+- This function takes a Da pointer called dap and a void pointer called pt.
+- It returns (bool) true if the char pointer passed in (pt) is greater than or equal to the end pointer of the Da.
+****
+
+bool da_boundq - The primary goal of this function is to assure that the end pointer has not "run off the end of the area allocated for the array," that is to say, the total area allocated for the container at full capacity.
+- This function takes a Da pointer called dap.
+- It returns true if the address referenced by the end pointer of dap is greater than the address reached by adding the size of dap to its base pointer, the address of its first element.
+
+char *da_index - The main goal of this function is to locate a specific element within a Da by creating a pointer that is offset from the base to that element number's worth of element_sizes of data. This way we can put and take items directly from the list without moving the end pointer.
+- This function takes a Da called dap and a size_t called i.
+- It initializes a size_t called offset as i times the element size of dap.
+- It initializes a pointer called pt as the base of dap plus offset.
+- It returns the pointer pt.
+
+void da_push_alloc
+- This function takes a Da called dap.
+- It initializes a size_t called element_off as the difference between the end and base pointers of dap.
+- It adds one dap element_size's worth to the address of the end pointer of dap.
+- It then expands if the end pointer has run off the end of the currently allocated space for dap.
+- It returns a pointer to the address element_off's worth past the base of dap.
+
+void da_push - The primary goal of this function is to push elements into the array. It doubles the array if necessary, copies the information from the source, and moves the end pointer accordingly.
+- This function takes a Da pointer called dap and a void pointer called element.
+- If the end pointer is past the allocated size for the array, it doubles the array with da_expand.
+- It copies the information at the address of element (of the size of the element size of Da) at the location of the end pointer.
+- It then moves the end pointer of dap one element_size worth farther in memory.
+
+bool da_pop - The primary goal of this function is to pop the end pointer of a Da back one element. It takes precaution to ensure it will only go to the base of the Da. It returns a flag to confirm that a pop was performed. And it copies the information from the "deleted" element of the Da into an element pointer, if one was passed in.
+- This function takes a Da pointer called dap and a void pointer called element.
+- It flags (true bool) if the end pointer of dap is farther than one element_size past the base of dap. This ensures that there is actually somewhere to pop from and we won't be popping out of the allocated range of the Da.
+- If true, it removes one dap element_size worth's from the address of dap's end pointer. Then if there is an element pointer, it copies one element_size worth of data starting at the new end pointer into the address of element.
+- It returns the flag bool value to confirm whether or not a pop was performed.
+
+void da_map - The primary goal of this function is to create closure for the Da. It takes the results of functions for all the elements of a Da and copies them to a closure pointer to keep them at global scope even after exiting the namespace the function is in.
+- This function takes a Da pointer called dap, a pointer to a void function which takes two void pointers as arguments, and a void pointer called closure.
+- The arguments of f are intended to be an element pointer and another arg pointer.
+- It initializes a char pointer called pt with the address of the base pointer of dap.
+- As long as pt does not equal the end pointer of dap, it passes pt and closure as arguments to f (which is intended to be da_free_element as passed in by da_free_elements). Then it adds a dap element_size worth to the pt address.
+
+static void da_free_element - The primary goal of this function is to free up space taken by a Da becuase these lists "are sometimes used as resource managers." It is one substep in the process, which is used by the da_map function during a closure procedure to free up the pointer.
+- This function takes two void pointers called pt and closure as arguments.
+- It frees the memory at the address of pt.
+
+void da_free_elements - The primary goal of this function is to free up space taken by a Da because these lists "are sometimes used as resource managers." It is the main call for this function, sending the dap through the da_free_element function for every element and then rewinding the dap. This frees up the memory without deleting the Da itself.
+- This function takes a Da called dap as an argument.
+- It sends the dap pointer, the function da_free_element and the closure pointer of NULL to da_map.
+- It then sends dap to da_rewind.
+
+char *da_fgets - The primary goal of this function is to put text from a file into a dap, line by line, but not endlines of EOF. It preserves the old base, because da_push function will expand the Da if need be, but if not, the base won't have changed. "Use feof(FILE *stream) to test for EOF;"
+- This function takes a Da called dap and a FILE called fd as arguments.
+- It initializes a char pointer called old_base with the address of the base of dap.
+- It initializes an int called c with the value returned by running fd through the fgets C function.
+- As long as c is neither an EOF (end of file) character nor an endline character, it pushes c onto the dap list. Then it copies the result of fgetc(fd) into c again and continues.
+- It initializes an int called terminator with the value 0.
+- It pushes the terminator onto the dap.
+- This function returns the char pointer old_base "so that external pointers can be rebased" in the future.
+
+void da_ints_print
+- This function takes
+
+
+void da_cat - The primary goal of this function is to concatenate the contents of one array onto another. It adds it right to the end of where the last started, doubling if need be. "If dap0 has had a terminatating zero added, that must be popped off before the call. Similarly if a terminating zero is desired, it should be pushed after the call."
+- This function takes two Da pointers called dap0 and dap1 as arguments.
+- It returns if the end pointer of dap 1 already points to the same address as the end pointer of dap0. This prevents redundant concatenation.
+- It initializes a size_t called dap0_size with the difference between the end and base of dap0, then does the same thing for dap1.
+- It adds the size of dap1 to the end pointer of dap0.
+- If the end pointer of dap0 has now run off the edge of dap0's allocated size, it expands/doubles dap0 to accomodate.
+- It copies the contents of dap1 into dap0 starting dap0_size away from the base of dap0 (where the old end pointer would've been).
+
+
+
+
+*/
+
+
+
diff --git a/user/module/da/doc/todo_glenda.txt b/user/module/da/doc/todo_glenda.txt
new file mode 100644
index 0000000..4c270ff
--- /dev/null
+++ b/user/module/da/doc/todo_glenda.txt
@@ -0,0 +1,44 @@
+
+2019-04-19T09:34:21Z
+
+da_erase ; same as da_free, don't tell anyone
+
+da_integer_repeats ; all items in the array are equal
+da_integer_sum ; sum all elements
+ da_integer_transpose ; matrix transpose
+da_integer_repeats_column ; all columns are equal
+
+da_every_column ; like every but for columns instead of elements
+da_every_row ; like every but for rows
+
+
+
+
+
+da_push_row ; push rows/vectors/das onto dama
+da_integer_repeats_row ; transpose and call repeats column
+
+
+transpose needs to output a DaMa, not a raw image matrix, though it can use one to get there if need be
+
+then add integer repeats row which will use transpose and column repeats to do its job
+
+then add da_push_row to add Das to DaMa
+
+then test starting with helper functions
+
+
+
+
+got through each row and push values onto columns or vice versa?
+how to construct new Da's
+how to fill - integers only?
+
+
+--------------------
+
+here, change da_exists to return a pointer to the element, or a NULL pointer (NULL being false, doesn't exist)
+
+you will need the da_pts_exists version that returns a pointer so that you can search the malloc list to find freed pointers
+
+I also added da_pts_nullify, to set a pointer to zero, then to pop NULL pointers from the top of the stack. You will want that to set the malloc poniters to NULL when there is a match with a free pointer, so that the array will contract. using da_pts_nullify at the end, if there are no memory leaks the malloc array will be empty
diff --git a/user/module/da/include/acc.h b/user/module/da/include/acc.h
new file mode 100644
index 0000000..cd90111
--- /dev/null
+++ b/user/module/da/include/acc.h
@@ -0,0 +1,35 @@
+#ifndef ACC_LIB_H
+#define ACC_LIB_H
+
+#include
+#include
+#include
+#include
+
+#define malloc crash_and_burn_malloc
+#define free crash_and_burn_free
+
+typedef struct AccChannel_struct AccChannel;
+typedef struct Da_struct Da; // Da_struct defined in da.lib.h
+
+enum Mode_enum{acc_NULL = 0, acc_BALANCE = 1, acc_FULL = 2, acc_SELF = 3};//0,1,2,3
+typedef enum Mode_enum Mode;
+
+struct AccChannel_struct{
+ Da *outstanding_malloc;
+ Da *spurious_free;
+ Mode mode;
+}; //name instances of channels with handles
+
+//function declarations for accounting
+ AccChannel *acc_open(AccChannel *channel, Mode mode);//initializes channel structs
+ void *acc_malloc(size_t size, AccChannel *channel);//works for things besides Das too
+ void acc_free(void *pt, AccChannel *channel);//works for things besides Das too
+ AccChannel *acc_report(AccChannel *channel);//reports on channels based on mode
+ void acc_close(AccChannel *channel);//frees channel itself
+
+ void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
+ void crash_and_burn_free(void *);// sends error message in case of accidental regular free
+
+
+#endif
diff --git a/user/module/da/include/da.h b/user/module/da/include/da.h
new file mode 100644
index 0000000..3611064
--- /dev/null
+++ b/user/module/da/include/da.h
@@ -0,0 +1,73 @@
+#ifndef DA_LIB_H
+#define DA_LIB_H
+#include
+#include
+#include
+#include
+
+typedef struct AccChannel_struct AccChannel; // AccChannel_struct defined in acc.lib.h
+typedef struct Da_struct Da;
+
+struct Da_struct{
+ char *base;
+ char *end; // one byte/one element off the end of the array
+ size_t size; // size >= (end - base) + 1;
+ size_t element_size;
+ AccChannel *channel;//assign during init, set to NULL during free
+};
+
+// constructors / destructors
+//
+ Da *da_init(Da *dap, size_t element_size, AccChannel *channel);//calls da_malloc for base pointer
+ void da_free(Da *dap);
+ void da_rewind(Da *dap);
+ void da_rebase(Da *dap, char *old_base, void *pta);
+ char *da_expand(Da *dap);
+ bool da_boundq(Da *dap);
+ void da_erase(Da *dap);
+
+// status / attributes
+//
+ bool da_is_empty(Da *dap);
+ bool da_equal(Da *da_0, Da *da_1);
+ size_t da_length(Da *dap);
+ bool da_length_equal(Da *dap0, Da *dap1);
+
+// accessing
+//
+ char *da_index(Da *dap, size_t i);
+ char *da_push(Da *dap, void *element);
+ bool da_pop(Da *dap, void *element);
+
+// iteration, f is given a pointer to an element and a pointer to the closure
+ bool da_endq(Da *dap, void *pt);
+ bool da_right_bound(Da *dap, void *pt);
+ void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
+ bool da_exists(Da *dap, bool f(void *, void*), void *closure);
+ bool da_all(Da *dap, bool f(void *, void*), void *closure);
+
+// elements are pointers
+// would be better if exists returned NULL or a pointer to the existing element-
+ void *da_pts_exists(Da *dap, void *test_element);
+ void da_pts_free_all(Da *dap); // calls free on all elements
+ void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
+
+// elements are integers
+ void da_ints_print(Da *dap, char *sep);
+ bool da_integer_repeats(Da *dap);
+ int da_integer_sum(Da *dap);
+
+// the array itself is a string
+// careful if you add a null terminator it will become part of the da_string, affects iteration etc.
+ char *da_string_input(Da *dap, FILE *file);
+ void da_string_push(Da *dap0, char *string);
+ void da_cat(Da *dap_base, Da *dap_cat);
+
+// when the array holds pointers to C strings
+ void da_strings_print(Da *dap, char *sep);
+ bool da_strings_exists(Da *string_arrp, char *test_string);
+ void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
+ void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
+
+#endif
+
diff --git a/user/module/da/lib/libda.a b/user/module/da/lib/libda.a
new file mode 100644
index 0000000..137836b
Binary files /dev/null and b/user/module/da/lib/libda.a differ
diff --git a/user/module/da/makefile b/user/module/da/makefile
new file mode 100644
index 0000000..85a407e
--- /dev/null
+++ b/user/module/da/makefile
@@ -0,0 +1,33 @@
+# da/
+
+SHELL=/bin/bash
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+-include makefile-flags
+
+.PHONY: all
+all: version
+
+.PHONY: dep
+dep:
+ if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
+ $(MAKE) $@
+
+.PHONY: lib
+lib:
+ cp $(SRCDIR)/da.lib.h $(INCDIR)/da.h
+ cp $(SRCDIR)/acc.lib.h $(INCDIR)/acc.h
+ $(MAKE) $@
+
+.PHONY: exec
+exec:
+ $(MAKE) $@
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/da/makefile-flags b/user/module/da/makefile-flags
new file mode 100644
index 0000000..308602e
--- /dev/null
+++ b/user/module/da/makefile-flags
@@ -0,0 +1,30 @@
+
+MODULE=da
+
+DEPRDIR=deprecated
+DOCDIR=doc
+EXECDIR=exec
+INCDIR=include
+LIBDIR=lib
+SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
+SRCDIR=src
+TESTDIR=test
+TMPDIR=tmp
+TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
+TRYDIR=try
+
+DEPFILE=$(TMPDIR)/makefile-cc.deps
+LIBFILE=$(LIBDIR)/lib$(MODULE).a
+INCFILE=$(INCDIR)/$(MODULE).h
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# compiler and flags
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB
+LINKFLAGS=-L$(LIBDIR) -l$(MODULE)
+
+
+
diff --git a/user/module/da/src/acc.lib.c b/user/module/da/src/acc.lib.c
new file mode 100644
index 0000000..37ba2f3
--- /dev/null
+++ b/user/module/da/src/acc.lib.c
@@ -0,0 +1,119 @@
+/*
+dynamic memory accounting
+
+*/
+
+
+#include "da.lib.h"
+#include "acc.lib.h"
+
+#undef malloc
+#undef free
+
+//-----------------------------------------------------------------
+//function definitions for accounting
+
+AccChannel *acc_open(AccChannel *channel, Mode mode){//acc init
+ Da os; Da sf;
+ channel->outstanding_malloc = da_init(&os, sizeof(void *), NULL);
+ channel->spurious_free = da_init(&sf, sizeof(void *), NULL);
+ channel->mode = mode;
+ return channel;
+}
+void *acc_malloc(size_t size, AccChannel *channel){
+ void *an_allocation_pt = malloc(size);
+ if( channel ) da_push((Da *)(channel->outstanding_malloc), &an_allocation_pt);//tried taking out reference but fixed nothing
+ return (void *)an_allocation_pt;
+}
+void acc_free(void *pt, AccChannel *channel){
+ if( channel ){
+ void **i = (void **)(((Da *)(channel->outstanding_malloc))->base);
+ bool present = false;
+ while( i < (void **)(((Da *)(channel->outstanding_malloc))->end) ){
+ if( *i == pt ){//this is just da_exists, make it return a pointer
+ da_pts_nullify((Da *)(channel->outstanding_malloc), i);
+ present = true;
+ }
+ i++;
+ }
+ if( present == false ) da_push((Da *)(channel->spurious_free), &pt);
+ }
+ free(pt);
+}
+static void count_balance(void *element, void *closure){
+ int *counter = (int *)closure;
+ if( element ) (*counter)++;
+}
+static void acc_rep_helper_BALANCE(AccChannel *channel){
+ int count = 0;
+ da_foreach((Da *)channel->outstanding_malloc, count_balance, &count);
+ printf("There are %d outstanding allocations.\n", count);
+ int count1 = 0;
+ da_foreach((Da *)channel->spurious_free, count_balance, &count1);
+ printf("There are %d spurious frees.\n", count);
+}
+static void print_pointer(void *element, void *closure){
+ if( element ) printf("%d ", *(int *)element);
+}
+static void acc_rep_helper_FULL(AccChannel *channel){
+ printf("There are %d outstanding mallocs.\n", (int)da_length((Da *)(channel->outstanding_malloc)));
+ printf("There are %d spurious frees.\n", (int)da_length((Da *)(channel->spurious_free)));
+ /*if( 0 < count && count < 10 ){
+ printf("The outstanding allocated pointers are: ");
+ da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
+ printf(".\n");
+ }
+ if( 0 < count && count < 10 ){
+ printf("The spuriously freed pointers are: ");
+ da_foreach((Da *)channel->outstanding_malloc, print_pointer, NULL);
+ printf(".\n");
+ }*/
+}
+AccChannel *acc_report(AccChannel *channel){
+ if( channel->mode == acc_NULL ){
+ printf("Accounting mode is NULL.\n");
+ return channel;
+ }
+ if( channel->mode == acc_BALANCE ){
+ printf("Accounting mode is BALANCE.\n");
+ if( da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) ){
+ printf("This channel is in balance.\n");
+ }
+ else{
+ printf("This channel is out of balance.\n");
+ acc_rep_helper_BALANCE(channel);
+ }
+ return channel;
+ }
+ if( channel->mode == acc_FULL ){
+ printf("Accounting mode is FULL.\n");
+ if( false ){
+ printf("This channel is in balance.\n");
+ }
+ else{
+ printf("This channel is out of balance.\n");
+ acc_rep_helper_FULL(channel);
+ }
+ return channel;
+ }
+ if( channel->mode == acc_SELF ){
+ printf("Accounting mode is SELF.\n");
+ if( true/*da_is_empty((Da *)(channel->outstanding_malloc)) && da_is_empty((Da *)(channel->spurious_free)) */){
+ printf("There are no open channels.\n");
+ }
+ else {
+ printf("The accounting code is out of balance.\n");
+ acc_rep_helper_FULL(channel);
+ }
+ return channel;
+ }
+}
+void acc_close(AccChannel *channel){
+ da_free((Da *)(channel->outstanding_malloc));
+ da_free((Da *)(channel->spurious_free));
+ return;
+}
+
+void *crash_and_burn_malloc(size_t size){}
+void crash_and_burn_free(void *pt){}
+
diff --git a/user/module/da/src/acc.lib.h b/user/module/da/src/acc.lib.h
new file mode 100644
index 0000000..cd90111
--- /dev/null
+++ b/user/module/da/src/acc.lib.h
@@ -0,0 +1,35 @@
+#ifndef ACC_LIB_H
+#define ACC_LIB_H
+
+#include
+#include
+#include
+#include
+
+#define malloc crash_and_burn_malloc
+#define free crash_and_burn_free
+
+typedef struct AccChannel_struct AccChannel;
+typedef struct Da_struct Da; // Da_struct defined in da.lib.h
+
+enum Mode_enum{acc_NULL = 0, acc_BALANCE = 1, acc_FULL = 2, acc_SELF = 3};//0,1,2,3
+typedef enum Mode_enum Mode;
+
+struct AccChannel_struct{
+ Da *outstanding_malloc;
+ Da *spurious_free;
+ Mode mode;
+}; //name instances of channels with handles
+
+//function declarations for accounting
+ AccChannel *acc_open(AccChannel *channel, Mode mode);//initializes channel structs
+ void *acc_malloc(size_t size, AccChannel *channel);//works for things besides Das too
+ void acc_free(void *pt, AccChannel *channel);//works for things besides Das too
+ AccChannel *acc_report(AccChannel *channel);//reports on channels based on mode
+ void acc_close(AccChannel *channel);//frees channel itself
+
+ void *crash_and_burn_malloc(size_t size);//sends error message in case of accidental regular malloc
+ void crash_and_burn_free(void *);// sends error message in case of accidental regular free
+
+
+#endif
diff --git a/user/module/da/src/acc.lib.o b/user/module/da/src/acc.lib.o
new file mode 100644
index 0000000..c3a1382
Binary files /dev/null and b/user/module/da/src/acc.lib.o differ
diff --git a/user/module/da/src/da.lib.c b/user/module/da/src/da.lib.c
new file mode 100644
index 0000000..5bca280
--- /dev/null
+++ b/user/module/da/src/da.lib.c
@@ -0,0 +1,353 @@
+/*
+Dynamic Array
+
+Cannot expand an empty array.
+
+*/
+#include
+#include
+#include
+
+#include "acc.lib.h"
+#include "da.lib.h"
+
+//--------------------------------------------------------------------------------
+// constructors / destructors
+
+Da *da_init(Da *dap, size_t element_size, AccChannel *channel){
+ dap->element_size = element_size;
+ dap->size = 4 * element_size;
+ dap->base = acc_malloc(dap->size, channel);
+ dap->end = dap->base;
+ dap->channel = channel;
+ return dap;
+}
+void da_free(Da *dap){
+ acc_free(dap->base, dap->channel);
+ dap->size = 0;
+ dap->channel = NULL;
+}
+void da_rewind(Da *dap){
+ dap->end = dap->base;
+}
+void da_rebase(Da *dap, char *old_base, void *pta){
+ char **pt = (char **)pta;
+ size_t offset = *pt - old_base;
+ *pt = dap->base + offset;
+}
+
+// Doubles size of of da. Returns old base, so that existing pointers into the
+// array can be moved to the new array
+char *da_expand(Da *dap){
+ char *old_base = dap->base;
+ size_t end_offset = dap->end - old_base;
+ size_t new_size = dap->size << 1;
+ char *new_base = acc_malloc(new_size, (AccChannel *)(dap->channel));
+ memcpy( new_base, old_base, end_offset + dap->element_size);
+ acc_free(old_base, (AccChannel *)(dap->channel));
+ dap->base = new_base;
+ dap->end = new_base + end_offset;
+ dap->size = new_size;
+ return old_base;
+}
+
+// true when end has run off the allocated area
+bool da_boundq(Da *dap){
+ return dap->end > (dap->base + dap->size);
+}
+
+// erases all the elements in the array
+// a push followed by an erase should work, but I don't think it does right now
+/*
+void da_erase(Da *dap){
+ da_free(Da *dap);
+}
+*/
+
+//--------------------------------------------------------------------------------
+// status / attributes
+
+bool da_is_empty(Da *dap){
+ return dap->end == dap->base;
+}
+
+bool da_equal(Da *da_0, Da *da_1){
+ return !bcmp(da_0, da_1, sizeof(Da));
+}
+
+size_t da_length(Da *dap){
+ return (dap->end - dap->base)/dap->element_size;
+}
+
+bool da_length_equal(Da *dap0, Da *dap1){
+ return da_length(dap0) == da_length(dap1);
+}
+
+
+//--------------------------------------------------------------------------------
+// accessing
+
+char *da_index(Da *dap, size_t i){
+ size_t offset = i * dap->element_size;
+ char *pt = dap->base + offset;
+ return pt;
+}
+
+// allocate space for a new element at the end of the array
+static char *da_push_alloc(Da *dap){
+ size_t element_off = dap->end - dap->base;
+ //printf("help help help I'm melting!");
+ dap->end += dap->element_size;
+ if( dap->end > dap->base + dap->size ) da_expand(dap);
+ return dap->base + element_off;
+}
+char *da_push(Da *dap, void *element){
+ char *element_pt = da_push_alloc(dap);
+ memcpy(element_pt, element, dap->element_size);
+ return element_pt;
+}
+
+bool da_pop(Da *dap, void *element){
+ bool flag = dap->end >= dap->base + dap->element_size;
+ if( flag ){
+ dap->end -= dap->element_size;
+ if(element) memcpy(element, dap->end, dap->element_size);
+ }
+ return flag;
+}
+
+//--------------------------------------------------------------------------------
+// iteration
+
+// true when pt has run off the end
+bool da_endq(Da *dap, void *pt){
+ return (char *)pt >= dap->end;
+}
+
+// array is a row of elements, pt points at the rightmost element
+bool da_right_bound(Da *dap, void *pt){
+ return ((char *)pt + dap->element_size) >= dap->end;
+}
+
+// passed in f(element_pt, arg_pt)
+// We have no language support closures, so we pass in an argument for it.
+// The closure may be set to NULL if it is not needed.
+void da_foreach(Da *dap, void f(void *, void *), void *closure){
+ char *pt = dap->base;
+ while( pt != dap->end ){
+ f(pt, closure);
+ pt += dap->element_size;
+ }
+}
+
+//â, OR map
+//---> should return the element pointer, same for da_pts_exists
+static bool da_quantifier(bool complement, Da *dap, bool pred(void *, void*), void *closure){
+ char *pt = dap->base;
+ bool result = !complement;
+ while( (complement? !result : result) && (pt != dap->end) ){
+ result = pred(pt, closure);
+ pt += dap->element_size;
+ }
+ return result;
+}
+bool da_exists(Da *dap, bool pred(void *, void*), void *closure){
+ return da_quantifier(true, dap, pred, closure);
+}//return pointer to thing it found that exists
+bool da_exception(Da *dap, bool pred(void *, void*), void *closure){
+ return da_quantifier(false, dap, pred, closure);
+}//make return pointer to exception and NULL (pointer) if no exception
+
+
+
+
+
+
+//--------------------------------------------------------------------------------
+// elements are pointers
+// elements are pointers
+//
+static bool da_pts_exists_0(void *element, void *test_element){ return element == test_element; }
+void *da_pts_exists(Da *dap, void *test_element){
+ if( da_exists(dap, da_pts_exists_0, test_element) ) return test_element;
+ else return NULL; //if da_exists returns pointer, gets bool and pointer in one
+}
+/*
+static da_pts_exists_0(void *element, void *pt){ return element == pt; }
+bool da_pts_exists(Da *dap, void *test_element){
+ return da_exists(dap, da_pts_exists_0, test_element);
+}
+*/
+// elements were allocated, now they will all be freed
+static void da_pts_free_all_0(void *pt, void *closure){
+ acc_free(*(char **)pt, closure);
+ // FREE(*(char **)pt); // FREE does not care about the pointer type
+}
+void da_pts_free_all(Da *dap){
+ da_foreach(dap, da_pts_free_all_0, dap->channel);
+ // da_map(dap, da_pts_free_all_0, NULL);
+ da_rewind(dap);
+}
+
+// elements are pointers
+// ept points at an element, we set *ept to NULL
+// we pop all NULLs off the top of the stack
+void da_pts_nullify(Da *dap, void **ept){
+ if(ept >= (void **)(dap->base) && ept < (void **)(dap->end)){
+ // if(ept >= dap->base && ept < dap->end){
+ *ept = NULL;
+ }
+ while(
+ dap->end > dap->base
+ &&
+ // *(void **)(dap->end - dap->element_size) == NULL
+ // ){
+ *(void **)(dap->end - dap->element_size) == NULL){
+ da_pop(dap, NULL);
+ }
+}
+
+
+
+//--------------------------------------------------------------------------------
+// da is an array of integers
+
+// would like to pass in the printf format to make a general print
+// but can't get *pt on the stack for the printf call .. hmmm
+void da_ints_print(Da *dap, char *sep){
+ char *pt = dap->base; // char * because it points to a byte in the array
+ if( pt < dap->end ){
+ printf("%u", *(int *)pt);
+ pt += dap->element_size;
+ while( pt < dap->end ){
+ printf("%s%u", sep, *(int *)pt);
+ pt += dap->element_size;
+ }}}
+
+bool da_integer_repeats(Da *dap){//all items in the array are equal
+ int n = *(dap->base);
+ char *pt = dap->base + dap->element_size;
+ bool flag = true;
+ while( flag && pt != dap->end ){
+ flag = *pt == n;
+ pt+=dap->element_size;
+ }
+ return flag;
+}
+
+int da_integer_sum(Da *dap){//sum all elements
+ char *pt = dap->base;
+ int sum = 0;
+ while( pt != dap->end ){
+ sum += *(pt);
+ pt+=dap->element_size;
+ }
+ return sum;
+}
+
+
+
+
+//--------------------------------------------------------------------------------
+// da is an array of strings
+
+// for the case of an array of strings
+void da_strings_print(Da *dap, char *sep){
+ char *pt = dap->base; // char * because it points to a byte in the array
+ if( pt < dap->end ){
+ fputs(*(char **)pt, stdout);
+ pt += dap->element_size;
+ while( pt < dap->end ){
+ fputs(sep,stdout);
+ fputs(*(char **)pt,stdout);
+ pt += dap->element_size;
+ }}}
+
+// da is an array of strings, true if the test string is in the array
+// might be better to iterate instead of using a map ...
+typedef struct {
+ char *string;
+ bool found;
+} da_strings_exists_closure;
+static void string_equal(void *sp, void *closure){
+ char *string_element = *(char **)sp;
+ da_strings_exists_closure *ss = (da_strings_exists_closure *)closure;
+ if( ss->found ) return;
+ ss->found = !strcmp(string_element, ss->string);
+ return;
+}
+
+bool da_strings_exists(Da *string_arrp, char *test_string){
+ da_strings_exists_closure sec;
+ sec.string = test_string;
+ sec.found = false;
+ da_foreach(string_arrp, string_equal, &sec);
+ return sec.found;
+}
+
+void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *)){
+ if( da_strings_exists( string_arrp, proffered_string)){ // then throw it away, we don't need it
+ if(destruct)destruct(proffered_string);
+ return;
+ }
+ da_push(string_arrp, &proffered_string);
+}
+
+// union
+void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *)){
+ char *pt = proffered_string_arrp->base;
+ while( pt < proffered_string_arrp->end ){
+ da_strings_set_insert(string_arrp, *(char **)pt, destruct);
+ pt += proffered_string_arrp->element_size;
+ }
+ return;
+}
+
+
+//--------------------------------------------------------------------------------
+// the da itself is a string
+
+// Puts text from a line into buffer *dap. Does not push EOF or '\n' into the
+// buffer. Returns the old_base so that external pointers can be rebased.
+// It is possible that the the base hasn't changed. Use feof(FILE *stream) to
+// test for EOF;
+char *da_string_input(Da *dap, FILE *file){
+ char *old_base = dap->base;
+ int c = fgetc(file);
+ while( c != EOF && c != '\n' ){
+ da_push(dap, &c);
+ c = fgetc(file);
+ }
+ int terminator = 0;
+ da_push(dap, &terminator);
+ return old_base;
+}
+
+void da_string_push(Da *dap0, char *string){
+ if(!*string) return;
+ size_t dap0_size = dap0->end - dap0->base;
+ size_t string_size = strlen(string);
+ dap0->end += string_size;
+ while( dap0->end >= dap0->base + dap0->size ) da_expand(dap0);
+ memcpy(dap0->base + dap0_size, string, string_size);
+}
+
+
+//--------------------------------------------------------------------------------
+// list operations
+
+// If dap0 has had a terminatating zero added, that must be popped off before
+// the call. Similarly if a terminating zero is desired, it should be pushed
+// after the call.
+
+// appends contents of dap1 onto dap0
+void da_cat(Da *dap0, Da *dap1){
+ if(dap1->base == dap1->end) return;
+ size_t dap0_size = dap0->end - dap0->base;
+ size_t dap1_size = dap1->end - dap1->base; // size of the active portion
+ dap0->end += dap1_size;
+ while( dap0->end >= dap0->base + dap0->size ) da_expand(dap0);
+ memcpy(dap0->base + dap0_size, dap1->base, dap1_size);
+}
+
+
diff --git a/user/module/da/src/da.lib.h b/user/module/da/src/da.lib.h
new file mode 100644
index 0000000..3611064
--- /dev/null
+++ b/user/module/da/src/da.lib.h
@@ -0,0 +1,73 @@
+#ifndef DA_LIB_H
+#define DA_LIB_H
+#include
+#include
+#include
+#include
+
+typedef struct AccChannel_struct AccChannel; // AccChannel_struct defined in acc.lib.h
+typedef struct Da_struct Da;
+
+struct Da_struct{
+ char *base;
+ char *end; // one byte/one element off the end of the array
+ size_t size; // size >= (end - base) + 1;
+ size_t element_size;
+ AccChannel *channel;//assign during init, set to NULL during free
+};
+
+// constructors / destructors
+//
+ Da *da_init(Da *dap, size_t element_size, AccChannel *channel);//calls da_malloc for base pointer
+ void da_free(Da *dap);
+ void da_rewind(Da *dap);
+ void da_rebase(Da *dap, char *old_base, void *pta);
+ char *da_expand(Da *dap);
+ bool da_boundq(Da *dap);
+ void da_erase(Da *dap);
+
+// status / attributes
+//
+ bool da_is_empty(Da *dap);
+ bool da_equal(Da *da_0, Da *da_1);
+ size_t da_length(Da *dap);
+ bool da_length_equal(Da *dap0, Da *dap1);
+
+// accessing
+//
+ char *da_index(Da *dap, size_t i);
+ char *da_push(Da *dap, void *element);
+ bool da_pop(Da *dap, void *element);
+
+// iteration, f is given a pointer to an element and a pointer to the closure
+ bool da_endq(Da *dap, void *pt);
+ bool da_right_bound(Da *dap, void *pt);
+ void da_foreach(Da *dap, void f(void *, void *), void *closure); //used to be da_map
+ bool da_exists(Da *dap, bool f(void *, void*), void *closure);
+ bool da_all(Da *dap, bool f(void *, void*), void *closure);
+
+// elements are pointers
+// would be better if exists returned NULL or a pointer to the existing element-
+ void *da_pts_exists(Da *dap, void *test_element);
+ void da_pts_free_all(Da *dap); // calls free on all elements
+ void da_pts_nullify(Da *dap, void **ept); // sets *ept to NULL, pops all NULLs from top of stack
+
+// elements are integers
+ void da_ints_print(Da *dap, char *sep);
+ bool da_integer_repeats(Da *dap);
+ int da_integer_sum(Da *dap);
+
+// the array itself is a string
+// careful if you add a null terminator it will become part of the da_string, affects iteration etc.
+ char *da_string_input(Da *dap, FILE *file);
+ void da_string_push(Da *dap0, char *string);
+ void da_cat(Da *dap_base, Da *dap_cat);
+
+// when the array holds pointers to C strings
+ void da_strings_print(Da *dap, char *sep);
+ bool da_strings_exists(Da *string_arrp, char *test_string);
+ void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
+ void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
+
+#endif
+
diff --git a/user/module/da/src/da.lib.o b/user/module/da/src/da.lib.o
new file mode 100644
index 0000000..8031e38
Binary files /dev/null and b/user/module/da/src/da.lib.o differ
diff --git a/user/module/da/src/da_mat.lib.c_nocompile b/user/module/da/src/da_mat.lib.c_nocompile
new file mode 100644
index 0000000..fb7cef6
--- /dev/null
+++ b/user/module/da/src/da_mat.lib.c_nocompile
@@ -0,0 +1,262 @@
+
+//-----------------------------------------------------
+
+
+//-------------------------------------------------------
+
+// all things Da matrix
+// a DaMa (Doubling array Matrix) is a Da whose elements are Da's
+// forms a matrix if you treat what's pointed to by base pointers of the elements of the DaMa as the first column of elements and fill in each row with the contents of the Das
+// The "row major" nomenclature is used to remain consistent with database logic.
+/* Example:
+Da dar0; Da *dap0 = &dar0; da_alloc(dap0, sizeof(int));
+Da dar1; Da *dap1 = &dar1; da_alloc(dap1, sizeof(int));
+Da dama; Da *damp = &dama; da_alloc(damp, sizeof(Da));
+da_push(damp, dap0);
+da_push(damp, dap1);
+*/
+
+/*
+
+Da *da_mat_push_row_alloc(Da *damp){
+ size_t row_off = (Da *)(damp->end) - (Da *)(damp->base);
+ damp->end += damp->element_size;
+ if( damp->end > damp->base + damp->size ) da_expand(damp);
+ return (Da *)(damp->base) + row_off;
+}
+Da *da_mat_push_row(Da *damp, Da *dap){// Dama won't track changes to Das after pushing onto rows
+ Da *row_pt = da_mat_push_row_alloc(damp);
+ memcpy(row_pt, dap, damp->element_size);
+ return row_pt;
+}
+
+void da_mat_push_column(Da *damp, Da *dap, void *fill){
+ Da *tran = da_mat_transpose(damp, fill);
+ da_mat_push_row(tran, dap);
+ Da *new_dama = da_mat_transpose(tran, fill);
+ //add protection against memory overwrite - expand if necessary
+ memcpy(damp, new_dama, new_dama->size);
+}
+
+void da_mat_every_row(Da *damp, void f(void *, void *), void *closure){//like every but for rows instead of elements
+ Da *dpt = (Da *)(damp->base);
+ while( dpt != (Da *)damp->end ){
+ f(dpt, closure);
+ dpt++;
+ }
+}
+
+// da_mat_every_column uses da_mat_longest and therefore da_mat_longer, written for the purpose of terminating the while loop in the appropriate place
+// will return dap1 if equal, cannot determine equality
+Da *da_mat_longer(Da *dap0, Da *dap1){
+ if (da_length(dap0) > da_length(dap1)) return dap0;
+ else return dap1;
+}
+// returns Da in DaMa with longest length
+Da *da_mat_longest(Da *damp){
+ Da *dap = (Da *)(damp->base);
+ Da *longest = (Da *)((damp->base) + sizeof(Da));
+ while( dap < (Da *)(damp->end) ){
+ longest = da_mat_longer(dap,longest);
+ dap++;
+ }
+ return longest;
+}
+void da_mat_every_column(Da *damp, void f(void *, void *), void *closure){//like every but for columns instead of elements
+ Da *dpt = (Da *)(damp->base);
+ size_t rows = damp->size/damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ size_t j = 0;
+ while( j < columns ){
+ int *col = MALLOC(sizeof(rows*sizeof(int)));
+ size_t i = 0;
+ while( i < rows ) {
+ if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
+ *(col+i) = 0;
+ else *(col+i) = *(dpt->base + j*(dpt->element_size));
+ dpt++;
+ i++;
+ }
+ f(col, closure);
+ j++;
+ }
+}
+
+Da *da_mat_transpose(Da *damp, void *fill){// all Das must have same element type, will sort to integer, char, or char * transpose function
+ Da *dap = (Da *)(damp->base);
+ Da tran; da_alloc(&tran, sizeof(damp->element_size));
+ Da *transpose = &tran;
+ if( dap->element_size == sizeof(int) ){
+ int *filler = (int *)fill;
+ transpose = da_mat_ints_transpose(damp, filler);
+ }
+ /*else if( dap->element_size == sizeof(char) ){
+ char *filler = (char *)fill;
+ transpose = da_character_transpose(damp, filler);
+ }
+ else if( dap->element_size == sizeof(char *) ){
+ char **filler = (char **)fill;
+ transpose = da_c_string_transpose(damp, filler);
+ }*/
+ //else error?
+ return transpose;
+}
+
+
+//--------------------------------------------------------------------
+// DaMa is a matrix of integers (stored in Das as columns)
+
+// integer repeats across columns
+bool da_mat_all_rows_same_length(Da *damp){
+ Da *dap = (Da *)(damp->base);
+ Da *pt = dap;
+ bool flag = true;
+ while( flag && pt != (Da *)(damp->end) ){
+ flag = da_length_equal(dap, pt);
+ }
+ return flag;
+}
+bool da_mat_ints_all_rows_repeat(Da *damp){// if rows are made of repeating integers, then all columns read the same thing
+ Da *dpt = (Da *)(damp->base);
+ bool flag = false;
+ if( da_mat_all_rows_same_length((Da *)damp) ){// columns can't be equal if rows not all same length, will return false
+ flag = true;
+ while( flag && dpt != (Da *)(damp->end) ){
+ flag = da_integer_repeats(dpt); // in "da is array of integers" section
+ dpt++;
+ }
+ return flag;
+ }
+ else return flag;
+}
+bool da_mat_ints_all_columns_repeat(Da *damp){// rows are repeating in transpose = columns are repeating
+ int x = 0; //have to pass in fill for transpose, this nullifies effect same_length test
+ Da *test_da = da_mat_transpose(damp, &x);
+ return da_mat_ints_all_rows_repeat(test_da);
+}
+bool da_mat_ints_repeats_matrix(Da *damp){// all elements in matrix are same
+ bool flag1 = da_mat_ints_all_rows_repeat(damp);
+ bool flag2 = da_mat_ints_all_columns_repeat(damp);
+ return flag1 && flag2;
+}
+
+// to transpose directly from one DaMa to another
+Da *da_mat_ints_transpose(Da *damp, int *fill){
+ size_t rows = damp->size/damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ Da *matrix = damp;
+ Da tran;
+ da_alloc(&tran, sizeof(Da));
+ Da *transpose = &tran;
+
+ Da *dpt = (Da *)(matrix->base);
+ int i = 0, j = 0;
+ while( j < columns ){
+ Da new_row; da_alloc(&new_row, sizeof(int));
+ int *ept = fill;
+ while( i < rows ){
+ if( !da_endq(dpt, (dpt->base + j*(dpt->element_size))) ){
+ *ept = *(dpt->base + j*(dpt->element_size));
+ }
+ da_push(&new_row, ept);
+ dpt++;
+ i++;
+ }
+ da_mat_push_row(transpose, &new_row);
+ j++;
+ }
+ return transpose;
+}
+
+//to create raw matrix image in memory, no longer a Da struct
+int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill){
+ size_t rows = damp->size / damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ int *matrix = MALLOC(sizeof(rows*columns));//[rows][columns]
+ int i = 0;
+ Da *dpt = (Da *)(damp->base);
+ while( i < rows )
+ {
+ int *ept = (int *)(dpt->base);
+ int j = 0;
+ while( j < columns )
+ {//matrix[i][j]
+ if (da_endq(dpt,(dpt->base + j*(dpt->element_size))))
+ *(matrix + (i*columns + j)*sizeof(int)) = fill;
+ else *(matrix + (i*columns + j)*sizeof(int)) = *(ept);
+ ept++;
+ j++;
+ }
+ dpt++;
+ i++;
+ }
+ return matrix;
+}
+int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill){
+ size_t rows = damp->size/damp->element_size;
+ size_t columns = da_length(da_mat_longest(damp));
+ int *matrix = da_mat_ints_to_raw_image_matrix(damp, fill);//[rows][columns]
+ int *transpose = MALLOC(sizeof(columns*rows));
+ int i, j;
+ for(i=0;ibase;
+ char *ept = dpt->base;
+ while( dpt != damp->end ){
+ while( ept != dpt->end ){
+ f(ept, closure);
+ ept+=dpt->element_size;
+ }
+ dpt++;
+ }
+*/
+
+
+//------------------------------------
+
+//first pass at array of Das, exists, etc turned into this
+
+typedef struct{
+ Da *da;
+ bool found;
+} da_present_closure;
+
+void da_present(Da **dar, int dar_size, void *closure){
+ Da **pt = dar;
+ da_present_closure *dpc = (da_present_closure *)closure;
+ Da *test_element = dpc->da;
+ int i = 0;
+ while (!dpc->found && i < dar_size){
+ dpc->found = da_equal(*pt, test_element);
+ pt++;
+ i++;
+ }
+ return;
+}
+
+
+void da_mat_map(Da **dar, int dar_size, void f(void *, void *), void *closure){
+ Da **pt = dar;
+ int i = 0;
+ while( i < dar_size ){
+ f(*pt, closure);
+ pt++;
+ i++;
+ }
+ return;
+}
diff --git a/user/module/da/src/da_mat.lib.h_nocompile b/user/module/da/src/da_mat.lib.h_nocompile
new file mode 100644
index 0000000..c3bc5f8
--- /dev/null
+++ b/user/module/da/src/da_mat.lib.h_nocompile
@@ -0,0 +1,25 @@
+/*
+// matrix
+// There is a top level master da array. Its elements are da arrays, these are said to be rows
+ void da_mat_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
+
+ Da *da_mat_push_row_alloc(Da *damp);
+ Da *da_mat_push_row(Da *damp, Da *dap);
+ void da_mat_push_column(Da *damp, Da *dap, void *fill);
+
+ void da_mat_every_row(Da *damp, void f(void *, void *), void *closure);
+ Da *da_mat_longer(Da *dap0, Da *dap1);
+ Da *da_mat_longest(Da *damp);
+ void da_mat_every_column(Da *damp, void f(void *, void *), void *closure);
+
+ Da *da_mat_transpose(Da *damp, void *fill);
+
+ bool da_mat_all_rows_same_length(Da *damp);
+ bool da_mat_ints_all_rows_repeat(Da *damp);
+ bool da_mat_ints_all_columns_repeat(Da *damp);
+ bool da_mat_ints_repeats_matrix(Da *damp);
+
+ Da *da_mat_ints_transpose(Da *damp, int *fill);
+ int *da_mat_ints_to_raw_image_matrix(Da *damp, int fill);
+ int *da_mat_ints_to_raw_image_transpose(Da *damp, int fill);
+*/
diff --git a/user/module/da/src/struct_forward_example.c b/user/module/da/src/struct_forward_example.c
new file mode 100644
index 0000000..d8fec98
--- /dev/null
+++ b/user/module/da/src/struct_forward_example.c
@@ -0,0 +1,27 @@
+
+
+typedef struct AccChannel_struct AccChannel;
+typedef struct Da_struct Da;
+
+typedef long long int size_t;
+
+struct AccChannel_struct{
+ struct Da *outstanding_malloc;
+ Da *spurious_free;
+ // enum Mode mode;
+}; //name instances of channels with handles
+
+struct Da_struct{
+ char *base;
+ char *end; // one byte/one element off the end of the array
+ size_t size; // size >= (end - base) + 1;
+ size_t element_size;
+ AccChannel *channel;//assign during init, set to NULL during free
+};
+
+
+int main(){
+ Da x;
+ AccChannel y;
+ return 5;
+}
diff --git a/user/module/da/src/update_Acc_channel.sed b/user/module/da/src/update_Acc_channel.sed
new file mode 100644
index 0000000..9861d73
--- /dev/null
+++ b/user/module/da/src/update_Acc_channel.sed
@@ -0,0 +1 @@
+s/Acc_channel/AccChannel/g
diff --git a/user/module/da/src/update_da_lib_names.sed b/user/module/da/src/update_da_lib_names.sed
new file mode 100644
index 0000000..6fcf87f
--- /dev/null
+++ b/user/module/da/src/update_da_lib_names.sed
@@ -0,0 +1,21 @@
+s/da_start_accounting/acc_start/g
+s/da_malloc_counted/acc_malloc/g
+s/da_free_counted/acc_free/g
+s/da_result_accounting/acc_result/g
+s/da_free_elements/da_pts_free_all/g
+s/da_matrix_map/da_mat_map/g
+s/da_push_row_alloc/da_mat_push_row_alloc/g
+s/da_push_column/da_mat_push_column/g
+s/da_push_row/da_mat_push_row/g
+s/da_every_row/da_mat_every_row/g
+s/da_longer/da_mat_longer/g
+s/da_longest/da_mat_longest/g
+s/da_every_column/da_mat_every_column/g
+s/da_matrix_transpose/da_mat_transpose/g
+s/da_all_rows_same_length/da_mat_all_rows_same_length/g
+s/da_integer_all_rows_repeat/da_mat_ints_all_rows_repeat/g
+s/da_integer_all_columns_repeat/da_mat_ints_all_columns_repeat/g
+s/da_integer_repeats_matrix/da_mat_ints_repeats_matrix/g
+s/da_integer_transpose/da_mat_ints_transpose/g
+s/da_integer_to_raw_image_matrix/da_mat_ints_to_raw_image_matrix/g
+s/da_integer_to_raw_image_transpose/da_mat_ints_to_raw_image_transpose/g
\ No newline at end of file
diff --git a/user/module/da/src/update_project_da_lib_names.sed b/user/module/da/src/update_project_da_lib_names.sed
new file mode 100644
index 0000000..692744f
--- /dev/null
+++ b/user/module/da/src/update_project_da_lib_names.sed
@@ -0,0 +1,2 @@
+s/da_alloc/da_init/g
+s/da_map/da_foreach/g
diff --git a/user/module/da/test/exec/test_da b/user/module/da/test/exec/test_da
new file mode 100755
index 0000000..def8c1c
Binary files /dev/null and b/user/module/da/test/exec/test_da differ
diff --git a/user/module/da/test/lib/libtest.a b/user/module/da/test/lib/libtest.a
new file mode 100644
index 0000000..6eb3633
Binary files /dev/null and b/user/module/da/test/lib/libtest.a differ
diff --git a/user/module/da/test/lib/test.dat b/user/module/da/test/lib/test.dat
new file mode 100644
index 0000000..6b4b5bd
--- /dev/null
+++ b/user/module/da/test/lib/test.dat
@@ -0,0 +1,3 @@
+this is a test
+ends without a newline
+(setq mode-require-final-newline nil)
\ No newline at end of file
diff --git a/user/module/da/test/makefile b/user/module/da/test/makefile
new file mode 100644
index 0000000..ab92883
--- /dev/null
+++ b/user/module/da/test/makefile
@@ -0,0 +1,35 @@
+# da/test
+
+SHELL=/bin/bash
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+-include makefile-flags
+
+.PHONY: all
+all: version
+
+.PHONY: dep
+dep:
+ if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
+ $(MAKE) $@
+
+.PHONY: lib
+lib:
+ $(MAKE) $@
+
+.PHONY: exec
+exec:
+ $(MAKE) $@
+
+.PHONY: share
+share:
+ @echo "module/da/test nothing to share"
+
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/da/test/makefile-flags b/user/module/da/test/makefile-flags
new file mode 100644
index 0000000..4270f9d
--- /dev/null
+++ b/user/module/da/test/makefile-flags
@@ -0,0 +1,29 @@
+
+MODULE=test
+
+DEPRDIR=deprecated
+DOCDIR=doc
+EXECDIR=exec
+INCDIR=include
+LIBDIR=lib
+SHAREDIR=../share
+SRCDIR=src
+TESTDIR=
+TMPDIR=tmp
+TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
+TRYDIR=try
+
+DEPFILE=$(TMPDIR)/makefile-cc.deps
+LIBFILE=$(LIBDIR)/lib$(MODULE).a
+INCFILE=$(INCDIR)/$(MODULE).h
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# compiler and flags
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB
+#CFLAGS=-std=gnu11 -fPIC -Iinclude -I../include -Werror
+LINKFLAGS= -Llib -L../lib -ltest -lda
+
diff --git a/user/module/da/test/results/results_2019-04-19T09:41:00Z b/user/module/da/test/results/results_2019-04-19T09:41:00Z
new file mode 100644
index 0000000..2649648
--- /dev/null
+++ b/user/module/da/test/results/results_2019-04-19T09:41:00Z
@@ -0,0 +1,78 @@
+Hello Emacs
+
+2019-04-19T09:46:09Z
+glendawest045@phoenix§~/subu/module/da§
+> make dist-clean dep lib
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
+for i in tmp/da.lib.o tmp/makefile-cc.deps; do rm $i || true; done
+for i in ; do [ -e $i ] && rm $i || true; done
+rm include/da.h || true
+rm lib/libda.a || true
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+cp src/da.lib.h include/da.h
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Isrc -Iinclude -I/home/glendawest045/subu/module/share/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB -o tmp/da.lib.o -c src/da.lib.c
+ar rcs lib/libda.a tmp/da.lib.o
+
+2019-04-19T09:46:27Z
+glendawest045@phoenix§~/subu/module/da§
+> cd test/
+
+2019-04-19T09:47:29Z
+glendawest045@phoenix§~/subu/module/da/test§
+> make dist-clean lib exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
+for i in tmp/test_da.cli.o tmp/makefile-cc.deps tmp/test_da.lib.o; do rm $i || true; done
+for i in exec/test_da; do [ -e $i ] && rm $i || true; done
+rm include/test.h || true
+rm: cannot remove 'include/test.h': No such file or directory
+rm lib/libtest.a || true
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
+ar rcs lib/libtest.a tmp/test_da.lib.o
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+make[3]: *** No rule to make target 'exec/test_da', needed by 'sub_exec'. Stop.
+make[2]: *** [makefile:31: sub_exec] Error 2
+make[1]: *** [/home/glendawest045/subu/tool/lib/makefile-cc:164: exec] Error 2
+make: *** [makefile:23: exec] Error 2
+
+2019-04-19T09:47:43Z
+glendawest045@phoenix§~/subu/module/da/test§
+> make dist-clean dep lib exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
+for i in tmp/test_da.lib.o; do rm $i || true; done
+for i in exec/test_da; do [ -e $i ] && rm $i || true; done
+rm include/test.h || true
+rm: cannot remove 'include/test.h': No such file or directory
+rm lib/libtest.a || true
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
+ar rcs lib/libtest.a tmp/test_da.lib.o
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
+gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
+
+2019-04-19T09:48:09Z
+glendawest045@phoenix§~/subu/module/da/test§
+> cd exec/
+
+2019-04-19T09:48:12Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+> ./test_da
+test_da_push_alloc_0 failed
+failed 1 of 21 tests
+
+2019-04-19T09:48:14Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+>
\ No newline at end of file
diff --git a/user/module/da/test/results/results_2019-04-23T14:20:14Z_passed b/user/module/da/test/results/results_2019-04-23T14:20:14Z_passed
new file mode 100644
index 0000000..a82fc93
--- /dev/null
+++ b/user/module/da/test/results/results_2019-04-23T14:20:14Z_passed
@@ -0,0 +1,25 @@
+Hello Emacs
+
+
+2019-04-23T14:20:14Z
+glendawest045@phoenix§~/subu/module/da/test§
+> make lib exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+make[1]: Nothing to be done for 'lib'.
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+make[3]: Nothing to be done for 'sub_exec'.
+
+2019-04-23T14:20:40Z
+glendawest045@phoenix§~/subu/module/da/test§
+> cd exec/
+
+2019-04-23T14:20:45Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+> ./test_da
+passed all 21 tests
+
+2019-04-23T14:20:47Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+>
\ No newline at end of file
diff --git a/user/module/da/test/results/results_2019-04-27T21:08:59Z_failed b/user/module/da/test/results/results_2019-04-27T21:08:59Z_failed
new file mode 100644
index 0000000..dd38722
--- /dev/null
+++ b/user/module/da/test/results/results_2019-04-27T21:08:59Z_failed
@@ -0,0 +1,60 @@
+Hello Emacs
+
+2019-04-27T21:08:59Z
+glendawest045@phoenix§~§
+> cd subu/module/da/
+
+2019-04-27T21:09:12Z
+glendawest045@phoenix§~/subu/module/da§
+> make dist-clean
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
+for i in tmp/da.lib.o tmp/makefile-cc.deps; do rm $i || true; done
+for i in ; do [ -e $i ] && rm $i || true; done
+rm include/da.h || true
+rm lib/libda.a || true
+
+2019-04-27T21:09:18Z
+glendawest045@phoenix§~/subu/module/da§
+> make dep lib
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+cp src/da.lib.h include/da.h
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Isrc -Iinclude -I/home/glendawest045/subu/module/share/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB -o tmp/da.lib.o -c src/da.lib.c
+ar rcs lib/libda.a tmp/da.lib.o
+
+2019-04-27T21:09:28Z
+glendawest045@phoenix§~/subu/module/da§
+> cd test/
+
+2019-04-27T21:09:31Z
+glendawest045@phoenix§~/subu/module/da/test§
+> make dep lib exec
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
+ar rcs lib/libtest.a tmp/test_da.lib.o
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
+gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
+
+2019-04-27T21:09:39Z
+glendawest045@phoenix§~/subu/module/da/test§
+> cd exec/
+
+2019-04-27T21:09:43Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+> ./test_da
+da_result_heap_counter failed
+failed 1 of 26 tests
+
+2019-04-27T21:09:48Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+>
\ No newline at end of file
diff --git a/user/module/da/test/results/results_2019-04-30T14:37:28Z_passed b/user/module/da/test/results/results_2019-04-30T14:37:28Z_passed
new file mode 100644
index 0000000..0bbf894
--- /dev/null
+++ b/user/module/da/test/results/results_2019-04-30T14:37:28Z_passed
@@ -0,0 +1,55 @@
+Hello Emacs
+
+2019-04-30T14:37:28Z
+glendawest045@phoenix§~/subu/module/da§
+> make dist-clean
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dist-clean
+for i in tmp/da.lib.o tmp/makefile-cc.deps; do rm $i || true; done
+for i in ; do [ -e $i ] && rm $i || true; done
+rm include/da.h || true
+rm lib/libda.a || true
+
+2019-04-30T14:37:37Z
+glendawest045@phoenix§~/subu/module/da§
+> make dep lib
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+cp src/da.lib.h include/da.h
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Isrc -Iinclude -I/home/glendawest045/subu/module/share/include -ggdb -O0 -Werror -DDEBUG -DDEBUGDB -o tmp/da.lib.o -c src/da.lib.c
+ar rcs lib/libda.a tmp/da.lib.o
+
+2019-04-30T14:37:46Z
+glendawest045@phoenix§~/subu/module/da§
+> cd test/
+
+2019-04-30T14:37:50Z
+glendawest045@phoenix§~/subu/module/da/test§
+> make dep lib exec
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
+ar rcs lib/libtest.a tmp/test_da.lib.o
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
+gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
+
+2019-04-30T14:37:52Z
+glendawest045@phoenix§~/subu/module/da/test§
+> cd exec/
+
+2019-04-30T14:37:54Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+> ./test_da
+passed all 26 tests
+
+2019-04-30T14:37:57Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+>
\ No newline at end of file
diff --git a/user/module/da/test/results/results_2019-05-03T18:06:21Z_passed b/user/module/da/test/results/results_2019-05-03T18:06:21Z_passed
new file mode 100644
index 0000000..20c6e8c
--- /dev/null
+++ b/user/module/da/test/results/results_2019-05-03T18:06:21Z_passed
@@ -0,0 +1,82 @@
+Hello Emacs
+
+2019-05-03T18:06:21Z
+glendawest045@phoenix§~/subu/module/da§
+> make all
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc version
+makefile version 6.0
+gcc -v
+Using built-in specs.
+COLLECT_GCC=gcc
+COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
+OFFLOAD_TARGET_NAMES=nvptx-none
+OFFLOAD_TARGET_DEFAULT=1
+Target: x86_64-linux-gnu
+Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-6ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
+Thread model: posix
+gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)
+g++ -v
+Using built-in specs.
+COLLECT_GCC=g++
+COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
+OFFLOAD_TARGET_NAMES=nvptx-none
+OFFLOAD_TARGET_DEFAULT=1
+Target: x86_64-linux-gnu
+Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.3.0-6ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-8/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
+Thread model: posix
+gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)
+make -v
+GNU Make 4.2.1
+Built for x86_64-pc-linux-gnu
+Copyright (C) 1988-2016 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.
+
+2019-05-03T18:06:24Z
+glendawest045@phoenix§~/subu/module/da§
+> make dep lib exec
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+cp src/da.lib.h include/da.h
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+make[1]: Nothing to be done for 'lib'.
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+make[3]: Nothing to be done for 'sub_exec'.
+
+2019-05-03T18:06:45Z
+glendawest045@phoenix§~/subu/module/da§
+> cd test/
+
+2019-05-03T18:06:49Z
+glendawest045@phoenix§~/subu/module/da/test§
+> make dep lib exec
+if [ -e tmp/makefile-cc.deps ]; then rm tmp/makefile-cc.deps; fi
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc dep
+C compiler only deps
+deps for C linking
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc lib
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.lib.o -c src/test_da.lib.c
+ar rcs lib/libtest.a tmp/test_da.lib.o
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc exec
+make sub_exec
+/usr/bin/make --no-print-directory -f /home/glendawest045/subu/tool/lib/makefile-cc sub_exec
+gcc -std=gnu11 -fPIC -Iinclude -I../include -ggdb -DDEBUG -DDEBUGDB -o tmp/test_da.cli.o -c src/test_da.cli.c
+gcc -o exec/test_da tmp/test_da.cli.o -Llib -L../lib -ltest -lda
+
+2019-05-03T18:06:55Z
+glendawest045@phoenix§~/subu/module/da/test§
+> cd exec/
+
+2019-05-03T18:06:59Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+> ./test_da
+passed all 26 tests
+
+2019-05-03T18:07:01Z
+glendawest045@phoenix§~/subu/module/da/test/exec§
+>
\ No newline at end of file
diff --git a/user/module/da/test/src/test_da.cli.c b/user/module/da/test/src/test_da.cli.c
new file mode 100644
index 0000000..4b14d8e
--- /dev/null
+++ b/user/module/da/test/src/test_da.cli.c
@@ -0,0 +1,103 @@
+
+#include
+#include
+#include "test_da.lib.h"
+#include
+#include
+
+//AccChannel acc_live_channels;
+
+int main(){
+ //acc_open(&acc_live_channels, acc_SELF);
+ // enumeration of tests
+ typedef bool (*test_fun)();
+ test_fun tests[] =
+ {
+ test_da_push_0,
+ test_da_expand_0,
+ test_da_string_input_0,
+ test_da_pop_0,
+ test_da_cat_0,
+ test_da_cat_1,
+ test_da_rewind_0,
+ test_da_index_0,
+ test_da_free_elements_0,
+ test_da_strings_exists_0,
+ test_da_rebase_0,
+ test_da_boundq_0,
+ test_da_foreach_0,
+ //test_da_present_0,
+ test_da_exists_0,
+ test_da_exists_1,
+ //test_da_all_0,
+ test_da_init_0,
+ test_da_free_0,
+ test_da_is_empty_0,
+ test_da_length_0,
+ // test_da_push_row_0,
+ // test_da_erase_0,
+ // test_da_longer_0,
+ // test_da_longest_0,
+ test_da_accounting_0,
+ NULL};
+ char *test_names[] =
+ {
+ "test_da_push_0",
+ "test_da_expand_0",
+ "test_da_string_input_0",
+ "test_da_pop_0",
+ "test_da_cat_0",
+ "test_da_cat_1",
+ "test_da_rewind_0",
+ "test_da_index_0",
+ "test_da_free_elements_0",
+ "test_da_strings_exists_0",
+ "test_da_rebase_0",
+ "test_da_boundq_0",
+ "test_da_foreach_0",
+ //"test_da_present_0",
+ "test_da_exists_0",
+ "test_da_exists_1",
+ "test_da_all_0",
+ "test_da_init_0",
+ "test_da_free_0",
+ "test_da_is_empty_0",
+ "test_da_length_0",
+ //"test_da_push_row_0",
+ //"test_da_erase_0",
+ //"test_da_longer_0",
+ //"test_da_longest_0",
+ "test_da_accounting_0",
+ NULL};
+ // call tests
+ bool da_0_passed = true;
+ unsigned int passed = 0;
+ unsigned int failed = 0;
+ test_fun *tfp = tests;
+ char **tnp = test_names;
+ while(*tfp){
+ if( !(*tfp)() ){
+ failed++;
+ if(*tnp)
+ printf("%s failed\n", *tnp);
+ else
+ fprintf(stderr, "internal error, no test_names[] entry for test\n");
+ }else
+ passed++;
+ tfp++;
+ tnp++;
+ }
+ //acc_report(&acc_live_channels);
+ // summarize results
+ if( passed == 0 && failed == 0)
+ printf("no tests ran\n");
+ else if( passed == 0 )
+ printf("failed all %u tests\n", failed);
+ else if( failed == 0 )
+ printf("passed all %u tests\n", passed);
+ else
+ printf("failed %u of %u tests\n", failed, passed + failed);
+
+ if( passed == 0 || failed != 0 ) return 1;
+ return 0;
+}
diff --git a/user/module/da/test/src/test_da.lib.c b/user/module/da/test/src/test_da.lib.c
new file mode 100644
index 0000000..7857883
--- /dev/null
+++ b/user/module/da/test/src/test_da.lib.c
@@ -0,0 +1,984 @@
+/*
+Tests for Da.
+
+*/
+
+#include
+#include
+#include
+#include
+#include
+
+#include "test_da.lib.h"
+
+
+// tests push
+bool test_da_push_0(){
+ //AccChannel c;
+ //AccChannel *channel = acc_open(&c, acc_SELF);
+ Da da;
+ da_init(&da, sizeof(int), NULL); // leaves room for 4 ints
+ int i = 0;
+ int *pt = (int *)da.base;
+ // will double, 4 -> 8, then double 8 -> 16
+ while( i < 10 ){
+ da_push(&da, &i);
+ i++;
+ pt++;
+ }
+
+ bool flag0 = da.size == sizeof(int) * 16;
+ bool flag1 = 10 == (da.end - da.base) / sizeof(int);
+ bool flag2 = true;
+ pt = (int *)da.base;
+ i = 0;
+ while( i < 10 ){
+ flag2 = flag2 && *pt == i && !da_endq(&da, pt);
+ i++;
+ pt++;
+ }
+ bool flag3 = da_endq(&da, pt);
+ da_free(&da);
+ //acc_report(channel);
+ //acc_close(channel);
+ return flag0 && flag1 && flag2 && flag3;
+}
+
+// tests manual expansion
+bool test_da_expand_0(){
+ Da da;
+ Da *dap = da_init(&da, sizeof(int), NULL); // leaves room for 4 ints
+ int i = 0;
+ int *pt = (int *)da.base;
+ // will double, 4 -> 8, then double 8 -> 16
+ while( i < 10 ){
+ da.end += da.element_size;
+ if( da_boundq(&da) ){
+ char *old_base = da_expand(&da);
+ da_rebase(&da, old_base, &pt);
+ }
+ *pt = i;
+ i++;
+ pt++;
+ }
+
+ bool flag0 = da.size == sizeof(int) * 16;
+ bool flag1 = 10 == (da.end - da.base) / sizeof(int);
+ bool flag2 = true;
+ pt = (int *)da.base;
+ i = 0;
+ while( i < 10 ){
+ flag2 = flag2 && *pt == i && !da_endq(&da, pt);
+ i++;
+ pt++;
+ }
+ bool flag3 = da_endq(&da, pt);
+ da_free(dap);
+ return flag0 && flag1 && flag2 && flag3;
+}
+
+// da_fgets via da_string_input
+bool test_da_string_input_0(){
+
+ char *data_file_name = "../lib/test.dat";
+ FILE *file = fopen(data_file_name,"r");
+ if(!file){
+ fprintf(stderr,"test_da_2, could not open data file %s for reading\n", data_file_name);
+ return false;
+ }
+
+ Da da;
+ da_init(&da, sizeof(char), NULL);
+
+ da_string_input(&da, file);
+ bool flag0 = !strcmp(da.base, "this is a test");
+
+ char *old_base;
+ da_pop(&da, NULL); // pop the prior null terminator
+ char *s1 = da.end;
+ old_base = da_string_input(&da,file);
+ da_rebase(&da, old_base, &s1);
+ bool flag1 = !strcmp(s1, "ends without a newline");
+
+ da_pop(&da, NULL); // pop the prior null terminator
+ char *s2 = da.end;
+ old_base = da_string_input(&da,file);
+ da_rebase(&da, old_base, &s2);
+ bool flag2 = !strcmp(s2, "(setq mode-require-final-newline nil)");
+
+ bool flag3 = !strcmp(da.base, "this is a testends without a newline(setq mode-require-final-newline nil)");
+
+ fclose(file);
+ da_free(&da);
+ return flag0 && flag1 && flag2 && flag3;
+}
+
+// da_pop
+bool test_da_pop_0(){
+
+ Da da;
+ da_init(&da, sizeof(int), NULL);
+
+ int i = 5;
+ da_push(&da, &i);
+ i++;
+ da_push(&da, &i);
+ i++;
+ da_push(&da, &i);
+
+ int j;
+ bool flag0 = da_pop(&da, &j) && j == 7;
+ bool flag1 = da_pop(&da, &j) && j == 6;
+ bool flag2 = da_pop(&da, NULL);
+ bool flag3 = !da_pop(&da, &j);
+ da_free(&da);
+ return flag0 && flag1 && flag2 && flag3;
+}
+
+// da_cat
+bool test_da_cat_0(){
+
+ Da da0, da1;
+ da_init(&da0, sizeof(int), NULL);
+ da_init(&da1, sizeof(int), NULL);
+
+ int i = 5;
+ while(i < 8){
+ da_push(&da0, &i);
+ i++;
+ }
+ while(i < 11){
+ da_push(&da1, &i);
+ i++;
+ }
+
+ da_cat(&da0, &da1);
+
+ bool flag[6];
+ int j;
+ int k = 0;
+ while(k < 6){
+ flag[k] = da_pop(&da0, &j) && (j == 10 - k);
+ k++;
+ }
+
+ bool result = flag[0];
+ k = 1;
+ while(result && k < 6){
+ result = flag[k];
+ k++;
+ }
+ da_free(&da0);
+ da_free(&da1);
+ return result;
+}
+
+//Glenda: this was already tested much better above, where each element was actually tested, not just one, but it was a good one to test for practice
+bool test_da_cat_1(){
+ Da dar0;
+ Da dar1;
+ da_init(&dar0, sizeof(int), NULL);
+ da_init(&dar1, sizeof(int), NULL);
+ int n = 2;
+ {
+ int m = 0;
+ while(m < 4){
+ da_push(&dar0, &n);
+ n+=2;
+ m++;
+ }
+ }
+ size_t off0 = dar0.end - dar0.base;
+ bool flag1 = dar0.base != dar0.end;
+ for (int m=0; m<4; m++){
+ da_push(&dar1, &n);
+ n+=2;
+ }
+ size_t off1 = dar1.end - dar1.base;
+ bool flag2 = dar1.base != dar1.end;
+ da_cat(&dar0, &dar1);
+ bool flag3 = dar0.end == dar0.base + off0 +off1;
+ bool flag4 = *(dar0.base + (5*dar0.element_size)) == *(dar1.base + dar1.element_size);
+ da_free(&dar0);
+ da_free(&dar1);
+ return flag1 && flag2 && flag3 && flag4;
+}
+
+
+//Glenda's tests
+//tested output for success and artificial failure
+
+//tests da_rewind
+bool test_da_rewind_0(){
+ int i = 10;
+ Da dar;
+ da_init(&dar, sizeof(int), NULL);
+ while(i < 18){
+ da_push(&dar, &i);
+ ++i;
+ }
+ bool flag1 = dar.end != dar.base;
+ da_rewind(&dar);
+ int n = *(dar.end);
+ bool flag2 = dar.end == dar.base;
+ bool flag3 = n == 10;
+ bool flag4 = (*(dar.end + (7 * sizeof(int))) = 17);
+ bool result = flag1 && flag2 && flag3 && flag4;
+
+ da_free(&dar);
+ return result;
+}
+
+//tests da_index
+bool test_da_index_0(){
+ Da dar;
+ Da *dar_pt = &dar;
+ da_init(dar_pt, sizeof(int), NULL);
+
+
+ bool flag[4];
+ {//push to dar and test da_index
+ char *a[4];
+ size_t i = 0;
+ int n = 10;
+ int *n_pt = &n;
+ while(i < 4){
+ da_push(dar_pt, n_pt);
+ a[i] = da_index(dar_pt, i);
+ flag[i] = a[i] == dar.base + (i*dar.element_size);
+ i++;
+ n++;
+ }
+ }
+ bool result = flag[0] && flag[1] && flag[2] && flag[3];
+ da_free(dar_pt);
+ return result;
+}
+
+//tests da_free_elements - still getting core dump on function call
+//cannot test sub-functions bc da_free_element needs to be static
+bool test_da_free_elements_0(){
+ Da dar;
+ Da *dar_pt = &dar;
+ da_init(dar_pt, sizeof(int*), NULL);
+
+ int i = 3;
+ int *i_pt = &i;
+ while(i < 7){
+ da_push(dar_pt, &i_pt);
+ ++i;
+ }
+
+ //da_free_elements(dar_pt);
+ bool result = true;
+ da_free(dar_pt);
+ return result;
+}
+
+//tests da_strings_exist
+bool test_da_strings_exists_0(){
+ Da dar;
+ Da *dar_pt = &dar;
+ da_init(dar_pt, sizeof(char *), NULL);
+
+ //fill dar with strings
+ char *string0 = "nope";
+ char **string0_pt = &string0;
+ da_push(dar_pt, string0_pt);
+ char *string1 = "okay";
+ char **string1_pt = &string1;
+ da_push(dar_pt, string1_pt);
+ char *string2 = "welp";
+ char **string2_pt = &string2;
+ da_push(dar_pt, string2_pt);
+ char *string3 = "sure";
+ char **string3_pt = &string3;
+ da_push(dar_pt, string3_pt);
+
+ bool result;
+ {//test dar for each string
+ result = da_strings_exists(dar_pt, string0);
+ if (result == true)
+ result = da_strings_exists(dar_pt, string1);
+ if (result == true)
+ result = da_strings_exists(dar_pt, string2);
+ if (result == true)
+ result = da_strings_exists(dar_pt, string3);
+ }
+ da_free(dar_pt);
+ return result;
+}
+
+
+//tests rebase
+bool test_da_rebase_0(){
+ Da dar;
+ da_init(&dar,sizeof(char), NULL);
+
+ char **el_pt = (char **)acc_malloc(4*(sizeof(char*)), NULL);
+ {//push "temp" into dar, leave with pointer to last element
+ int i = 0;
+ char arr[4] = {'t','e','m','p'};
+ while(i<4){
+ char c = *(arr+i);
+ *el_pt = da_push(&dar, &c);
+ el_pt++;
+ i++;
+ }
+ el_pt--;
+ }
+
+ //check that push worked, that element pointer is in right place, and that expand works
+ bool flag1 = dar.base != dar.end;
+ bool flag2 = *el_pt == dar.end - dar.element_size;
+
+ char *obase = dar.base;
+ char *old_base = da_expand(&dar);
+ bool flag3 = obase == old_base;
+
+ bool flag4[4];
+ {//check that each pointer is properly rebased
+ int i = 0;
+ while(i<4 && *el_pt >= old_base){
+ size_t old_offset = *el_pt - old_base;
+ da_rebase(&dar, old_base, el_pt);
+ size_t new_offset = *el_pt - dar.base;
+ flag4[i] = old_offset == new_offset;
+ el_pt--;
+ i++;
+ }
+ el_pt++;
+ }
+
+ bool result = flag4[0];
+ {//now check that all pointers are properly rebased
+ int i = 1;
+ while(result && i < 4){
+ result = flag4[i];
+ i++;
+ }
+ }
+ da_free(&dar);
+ acc_free(el_pt, NULL);
+ return flag1 && flag2 && flag3 && result;
+}
+
+/* {//problems with FREE and MALLOC
+ char *a = MALLOC(10);
+ strcpy(a, "zsdf");
+ Da da;
+ Da *da_pt = &da;
+ da_init(da_pt, sizeof(char *));
+ da_push(da_pt, a);
+ ...
+ FREE(*(char *)da_index(da_pt, 0));
+ da_free(da_pt);
+} */
+
+//tests da_boundq
+bool test_da_boundq_0(){
+ Da dar;
+ da_init(&dar,sizeof(char), NULL);
+
+ bool flag[5];
+ {//pushes onto dar and tests no runoff
+ char arr[4] = {'r','e','s','t'};
+ int i = 0;
+ char c;
+ while(i<4){
+ c = arr[i];
+ da_push(&dar, &c);
+ flag[i] = (dar.end != dar.base) && !da_boundq(&dar);
+ i++;
+ }
+
+ }
+
+ //makes end pointer run off allocated area, tests boundq detects runoff
+ dar.end++; // = dar.base + dar.size;
+ flag[4] = da_boundq(&dar);
+
+ bool result = true;
+ {//check all test results
+ int i = 0;
+ while (result && i < 5){
+ result = flag[i];
+ i++;
+ }
+ }
+ da_free(&dar);
+ return result;
+}
+
+//tests foreach
+static void test_da_foreach_0_helper(void *pt, void *closure){
+ int *n = (int *)closure;
+ *n += *(int *)pt;
+}
+bool test_da_foreach_0(){
+ Da dar;
+ da_init(&dar, sizeof(int), NULL);
+
+ {//pushes onto dar
+ int arr[4] = {5,6,7,8};
+ int i = 0;
+ while(i<4){
+ da_push(&dar, arr+i);
+ i++;
+ }
+ }
+
+ int n = 0;
+ int *closure = &n;
+
+ da_foreach(&dar, test_da_foreach_0_helper, (int *)closure);
+ //rename to da_foreach
+ bool result = n == (5+6+7+8);
+ da_free(&dar);
+ return result;
+}
+
+/*
+//tests da_present
+bool test_da_present_0(){
+ int dar_size = 0;
+ Da **dar = acc_malloc(3 * sizeof(Da *), NULL);
+
+ Da dap_0;
+ Da *dap_0_pt = &dap_0;
+ da_init(dap_0_pt,sizeof(int), NULL);
+
+ Da dap_1;
+ Da *dap_1_pt = &dap_1;
+ da_init(dap_1_pt,sizeof(char), NULL);
+
+ dar[dar_size] = dap_0_pt; dar_size++;
+ dar[dar_size] = dap_1_pt; dar_size++;
+ Da dap_2;
+ Da *dap_2_pt = &dap_2;
+ da_init(dap_2_pt,sizeof(char *), NULL);
+ dar[dar_size] = dap_2_pt; dar_size++;
+
+ Da ;
+ Da *matrix = ;
+ da_init(dar, sizeof(Dap *));
+
+ typedef struct{
+ Da *da;
+ bool found;
+} da_present_closure;
+
+ bool flag[4];
+ da_present_closure dpc;
+ dpc.da = dap_0_pt;
+ dpc.found = false;
+
+ //test da_equal
+ flag[0] = da_equal(dap_0_pt, dpc.da);
+
+ //test da_present
+ da_present(dar, dar_size, &dpc);
+ flag[1] = dpc.found;
+ dpc.found = false;
+ da_present(dar, dar_size, &dpc);
+ flag[2] = dpc.found;
+ dpc.found = false;
+ da_present(dar, dar_size, &dpc);
+ flag[3] = dpc.found;
+ dpc.found = false;
+
+ bool result = flag[0] && flag[1] && flag[2] && flag[3];
+ da_free(dap_0_pt); da_free(dap_1_pt); da_free(dap_2_pt);
+ acc_free(dar, NULL);
+ return result;
+}
+*/
+
+//tests for da_exists and all
+
+static bool test_exists_helper(void *pt, void *closure){
+ bool result = *(int*)pt == *(int *)closure;
+ return result;
+}
+
+//tests da_exists
+bool test_da_exists_0(){
+ Da dar;
+ Da *dar_pt = &dar;
+ da_init(dar_pt, sizeof(int), NULL);
+
+ int n[5] = {5,6,7,8,9};
+
+ {//pushes ints 5-8 onto dar
+ int j = 0;
+ while (j < 5){
+ if (j != 3){
+ int *n_pt = n+j;
+ da_push(dar_pt, n_pt);
+ }
+ j++;
+ }
+ }
+
+ bool flag[5];
+ {//tests da_exists
+ int j = 0;
+ while(j < 5){
+ int *n_pt = n+j;
+ flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
+ j++;
+ }
+ }
+
+ bool result_1 = flag[0] && flag[1] && flag[2] && !flag[3] && flag[4];
+
+ {//add 8
+ int *n_pt = n+3;
+ da_push(dar_pt, n_pt);
+ }
+
+ {//tests da_exists
+ int j = 0;
+ while(j < 5){
+ int *n_pt = n+j;
+ flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
+ j++;
+ }
+ }
+
+ bool result_2 = flag[0] && flag[1] && flag[2] && flag[3] && flag[4];
+ da_free(dar_pt);
+ return result_1 && result_2;
+}
+bool test_da_exists_1(){//tests that expansion doesn't change results
+ Da dar;
+ Da *dar_pt = &dar;
+ da_init(dar_pt, sizeof(int), NULL);
+
+ int n[8] = {20,21,22,23,24,25,26,27};
+
+ {//pushes 20-27 onto dar except 23 and 26
+ int j = 0;
+ while (j < 8){
+ if (j != 3 && j != 6){
+ int *n_pt = n+j;
+ da_push(dar_pt, n_pt);
+ }
+ j++;
+ }
+ }
+
+ bool flag[8];
+ {//tests da_exists
+ int j = 0;
+ while(j < 8){
+ int *n_pt = n+j;
+ flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
+ j++;
+ }
+ }
+
+ bool result_1 =
+ flag[0] && flag[1] && flag[2] && !flag[3] && flag[4] && flag[5]
+ && !flag[6] && flag[7];
+
+ {//add 23 and 26
+ int *n_pt = n+3;
+ da_push(dar_pt, n_pt);
+ n_pt = n+6;
+ da_push(dar_pt, n_pt);
+ }
+
+ {//tests da_exists
+ int j = 0;
+ while(j < 8){
+ int *n_pt = n+j;
+ flag[j] = da_exists(dar_pt, test_exists_helper, n_pt);
+ j++;
+ }
+ }
+
+ bool result_2 =
+ flag[0] && flag[1] && flag[2] && flag[3] && flag[4] && flag[5]
+ && flag[6] && flag[7];
+ da_free(dar_pt);
+ return result_1 && result_2;
+}
+
+
+/*
+//tests da_all
+bool test_da_all_0(){
+ Da dar;
+ Da *dar_pt = &dar;
+ da_init(dar_pt, sizeof(int), NULL);
+
+ int n = 5;
+ int *n_pt = &n;
+ //push 5 onto dar 4 times
+ da_push(dar_pt, n_pt);
+ da_push(dar_pt, n_pt);
+ da_push(dar_pt, n_pt);
+ da_push(dar_pt, n_pt);
+
+ //tests da_all is true
+ bool flag1 = da_all(dar_pt, test_exists_helper, n_pt);
+
+ da_pop(dar_pt, NULL);
+ n = 6;
+ //tests da_all is false
+ bool flag2 = !da_all(dar_pt, test_exists_helper, n_pt);
+ da_free(dar_pt);
+
+ return flag1 && flag2;
+}
+*/
+
+
+//tests da_init
+bool test_da_init_0(){
+ Da da0; Da *da0_pt = &da0; da_init(da0_pt, sizeof(char), NULL);
+ Da da1; Da *da1_pt = &da1; da_init(da1_pt, sizeof(int), NULL);
+ Da da2; Da *da2_pt = &da2; da_init(da2_pt, sizeof(char *), NULL);
+ bool flag[6];
+
+ //check that da is allocated as array of 4 chars
+ flag[0] = da0_pt->element_size == 1;
+ flag[1] = da0_pt->size == 4;
+
+ //check that da is allocated as array of 4 ints
+ flag[2] = da1_pt->element_size == 4;
+ flag[3] = da1_pt->size == 16;
+
+ //check that da is allocated as array of 4 char *s
+ flag[4] = da2_pt->element_size == 8;
+ flag[5] = da2_pt->size == 32;
+
+ bool result =
+ flag[0] && flag[1] && flag[2] && flag[3] && flag[4] && flag[5];
+
+ da_free(da0_pt);
+ da_free(da1_pt);
+ da_free(da2_pt);
+ return result;
+}
+
+//tests da_free
+bool test_da_free_0(){
+ Da da;
+ Da *da_pt = &da;
+ da_init(da_pt, sizeof(int), NULL);
+
+ //store location of da
+ Da *keep = da_pt;
+ Da *save = da_pt;
+
+ //acc_free da
+ da_free(da_pt);
+
+ //re-allocate memory to dew da of chars
+ da_init(keep, sizeof(char), NULL);
+
+ //test that same memory is properly re-allocated
+ bool flag1 = keep == save;
+ bool flag2 = keep->element_size == 1;
+ da_free(keep);
+ return flag1 && flag2;
+}
+
+//tests da_is_empty
+bool test_da_is_empty_0(){
+ int i = 6;
+ Da da;
+ Da *da_pt = &da;
+ da_init(da_pt, sizeof(int), NULL);
+ bool flag0 = da_is_empty(da_pt);
+ while(i < 11){
+ da_push(da_pt, &i);
+ ++i;
+ }
+ bool flag1 = !da_is_empty(da_pt);
+ da_rewind(da_pt);
+ bool flag2 = da_is_empty(da_pt);
+ da_free(da_pt);
+ return flag0 && flag1 && flag2;
+}
+
+//tests da_length
+bool test_da_length_0(){
+ int i = 1;
+ Da da;
+ Da *da_pt = &da;
+ da_init(da_pt, sizeof(int), NULL);
+
+ //test da_length, even pushing past expansions
+ bool result = true;
+ while(result && i < 15){
+ da_push(da_pt, &i);
+ size_t length = da_length(da_pt);
+ result = length == i;
+ ++i;
+ }
+ da_free(da_pt);
+ return result;
+}
+
+/*
+//------------------------------------------------
+// Matrix function tests
+
+//tests da_push_row
+bool test_da_push_row_0(){
+ Da dama; da_init(&dama, sizeof(Da), NULL); Da *damp = &dama;
+ Da row0; da_init(&row0, sizeof(int), NULL); da_push_row(damp, &row0);
+ Da row1; da_init(&row1, sizeof(int), NULL); da_push_row(damp, &row1);
+ Da row2; da_init(&row2, sizeof(int), NULL); da_push_row(damp, &row2);
+
+ bool flag0 = da_equal(&row0, (Da *)(damp->base));
+ bool flag1 = da_equal(&row1, (Da *)(damp->base + damp->element_size));
+ bool flag2 = da_equal(&row2, (Da *)(damp->base + 2*(damp->element_size)));
+ int n = 5;
+ while( n < 8 ){
+ da_push(&row0, &n);
+ n++;
+ }
+ // bool flag3 = da_equal(&row0, (Da *)(damp->base));
+ // Dama won't track changes to Das after pushing onto rows
+ da_free_elements(damp);
+ da_erase(damp);
+ return flag0 && flag1 && flag2;// && flag3;
+}
+
+//tests da_erase
+bool test_da_erase_0(){
+ Da dama; da_init(&dama, sizeof(Da), NULL); Da *damp = &dama;
+ Da row0; da_init(&row0, sizeof(int), NULL); da_push_row(damp, &row0);
+ Da row1; da_init(&row1, sizeof(int), NULL); da_push_row(damp, &row1);
+ Da row2; da_init(&row2, sizeof(int), NULL); da_push_row(damp, &row2);
+
+ //store location of da
+ Da *keep = damp;
+ Da *save = damp;
+
+ //free da
+ da_free_elements(damp);
+ da_erase(damp);
+
+ //re-allocate memory to dew da of chars
+ da_init(keep, sizeof(char), NULL);
+
+ //test that same memory is properly re-allocated
+ bool flag1 = keep == save;
+ bool flag2 = keep->element_size == 1;
+ da_free_elements(keep);
+ da_free(keep);
+ return flag1 && flag2;
+}
+
+//tests da_longer
+bool test_da_longer_0(){
+ Da dama; Da *damp = &dama; da_init(damp, sizeof(Da), NULL);
+
+ Da row0; Da *r0 = &row0; da_init(r0, sizeof(int), NULL);
+ {//fills first row with 4 integers
+ int i = 10;
+ while(i<14){
+ da_push(r0, &i);
+ i++;
+ }
+ }
+ da_push_row(damp, r0);
+
+ Da row1; Da *r1 = &row1; da_init(r1, sizeof(int), NULL);
+ {//fills second row with 4 different integers
+ int i = 20;
+ while(i<24){
+ da_push(r1, &i);
+ i++;
+ }
+ }
+ da_push_row(damp, r1);
+
+ Da row2; Da *r2 = &row2; da_init(r2, sizeof(int), NULL);
+ {//fills third row with 6 integers
+ int i = 30;
+ while(i<36){
+ da_push(r2, &i);
+ i++;
+ }
+ }
+ da_push_row(damp, r2);
+
+ //plain test for which is Da is longer
+ Da *test1 = da_longer(r0, r1);
+ Da *test2 = da_longer(r0, r2);
+
+ //tests from dama which row is longer
+ Da *dr0 = (Da *)(damp->base);
+ Da *dr1 = (Da *)((damp->base)+sizeof(Da *));
+ Da *dr2 = (Da *)((damp->base)+(2*sizeof(Da *)));
+ Da *test3 = da_longer(dr0, dr1);
+ Da *test4 = da_longer(dr2, dr0);
+
+ bool flag1 = test1 == r1;
+ bool flag2 = test2 == r2;
+ bool flag3 = test3 == dr1;
+ bool flag4 = test4 == dr2;
+
+ da_free_elements(damp);
+ da_erase(damp);
+ return flag1 && flag2 && flag3 && flag4;
+}
+
+//tests da_longest
+bool test_da_longest_0(){
+
+ Da dama; Da *damp = &dama; da_init(damp, sizeof(Da), NULL);
+
+ Da row0; Da *r0 = &row0; da_init(r0, sizeof(int), NULL);
+ {//fills first row with 4 integers
+ int i = 10;
+ while(i<14){
+ da_push(r0, &i);
+ i++;
+ }
+ }
+ da_push_row(damp, r0);
+
+ Da row1; Da *r1 = &row1; da_init(r1, sizeof(int), NULL);
+ {//fills second row with 4 different integers
+ int i = 20;
+ while(i<24){
+ da_push(r1, &i);
+ i++;
+ }
+ }
+ da_push_row(damp, r1);
+
+ Da row2; Da *r2 = &row2; da_init(r2, sizeof(int), NULL);
+ {//fills third row with 6 integers
+ int i = 30;
+ while(i<36){
+ da_push(r2, &i);
+ i++;
+ }
+ }
+ da_push_row(damp, r2);
+
+ Da *dr0 = (Da *)(damp->base);
+ Da *dr1 = (Da *)((damp->base)+sizeof(Da));
+ Da *dr2 = (Da *)((damp->base)+(2*sizeof(Da)));
+ Da *test = da_longest(damp);
+
+ bool flag = test == dr2;
+ da_free_elements(damp);
+ da_erase(damp);
+ return flag;
+}
+*/
+
+bool test_da_accounting_0(){
+ AccChannel acc0;
+ AccChannel *acc0_pt = acc_open(&acc0, acc_FULL);
+
+ //Da da0;
+ //Da *dap = (Da *)da_init(&da0, sizeof(int), NULL); //trying to use acc0_pt results in even more immediate seg fault
+
+ printf("Outstanding Malloc: %d\n", (int)(acc0_pt->outstanding_malloc));
+ printf("Spurious Free: %d\n", (int)(acc0_pt->spurious_free));
+ acc_report(acc0_pt);
+
+ // da_free(dap);
+
+ acc_close(acc0_pt);
+ bool result = true;
+ return result;
+}
+
+
+
+/*need to update list
+ Functions
+-da_init
+-da_free
+-da_rewind
+-da_is_empty
+-da_length
+-da_rebase
+-da_expand
+-da_boundq
+-da_index
+-da_strings_exists_0
+-da_push
+-da_pop
+da_endq
+-da_foreach
+da_free_elements
+da_ints_print
+da_integer_repeats
+da_strings_print
+-da_strings_exists
+da_strings_set_insert
+da_strings_set_union
+-da_string_input
+da_string_push
+-da_cat
+-da_exists
+-da_all
+
+//matrix
+-da_erase
+da_push_row_alloc
+-da_push_row
+da_push_column
+
+da_every_row
+-da_longer
+-da_longest
+da_every_column
+
+da_matrix_transpose
+
+da_length_equal
+da_all_rows_same_length
+da_integer_all_rows_repeat
+da_integer_all_columns_repeat
+da_integer_repeats_matrix
+
+da_integer_transpose
+da_integer_to_raw_image_matrix
+da_integer_to_raw_image_transpose
+
+*/
+
+/*
+ Tests
+test_da_push_0
+test_da_expand_0
+test_da_string_input_0
+test_da_pop_0
+test_da_cat_0
+test_da_cat_1
+test_da_rewind_0
+test_da_index_0
+test_da_free_elements_0
+test_da_strings_exists_0
+test_da_rebase_0
+test_da_boundq_0
+test_da_foreach_0
+test_da_present_0
+test_da_exists_0
+test_da_exists_1
+test_da_all_0
+test_da_init_0
+test_da_free_0
+test_da_is_empty_0
+test_da_length_0
+
+//matrix
+da_push_row_0
+da_erase_0
+test_da_longer_0
+test_da_longest_0
+
+*/
diff --git a/user/module/da/test/src/test_da.lib.h b/user/module/da/test/src/test_da.lib.h
new file mode 100644
index 0000000..9872c4f
--- /dev/null
+++ b/user/module/da/test/src/test_da.lib.h
@@ -0,0 +1,31 @@
+#ifndef TEST_DA_LIB_H
+#define TEST_DA_LIB_H
+
+bool test_da_push_0();
+bool test_da_expand_0();
+bool test_da_string_input_0();
+bool test_da_pop_0();
+bool test_da_cat_0();
+bool test_da_cat_1();
+bool test_da_rewind_0();
+bool test_da_index_0();
+bool test_da_free_elements_0();
+bool test_da_strings_exists_0();
+bool test_da_rebase_0();
+bool test_da_boundq_0();
+bool test_da_foreach_0();
+bool test_da_present_0();
+bool test_da_exists_0();
+bool test_da_exists_1();
+//bool test_da_all_0();
+bool test_da_init_0();
+bool test_da_free_0();
+bool test_da_is_empty_0();
+bool test_da_length_0();
+//bool test_da_push_row_0();
+//bool test_da_erase_0();
+//bool test_da_longer_0();
+//bool test_da_longest_0();
+bool test_da_accounting_0();
+
+#endif
diff --git a/user/module/da/test/src/test_da.lib.h.gch b/user/module/da/test/src/test_da.lib.h.gch
new file mode 100644
index 0000000..f5782f9
Binary files /dev/null and b/user/module/da/test/src/test_da.lib.h.gch differ
diff --git a/user/module/da/test/try/passed.transcript b/user/module/da/test/try/passed.transcript
new file mode 100644
index 0000000..d75d376
--- /dev/null
+++ b/user/module/da/test/try/passed.transcript
@@ -0,0 +1,5 @@
+2019-03-31T20:08:48Z
+morpheus@manorhouse§~/subu_land/subu/module/da/test/exec§
+> ./test_da
+passed all 5 tests
+
diff --git a/user/module/debug/makefile b/user/module/debug/makefile
new file mode 100644
index 0000000..a19b90e
--- /dev/null
+++ b/user/module/debug/makefile
@@ -0,0 +1,27 @@
+# db
+
+SHELL=/bin/bash
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+-include makefile-flags
+
+.PHONY: all
+all: version
+
+.PHONY: dep
+dep:
+ if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
+ $(MAKE) $@
+
+.PHONY: lib
+lib:
+ cp $(SRCDIR)/debug.lib.h $(INCDIR)/debug.h
+ $(MAKE) $@
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/debug/makefile-flags b/user/module/debug/makefile-flags
new file mode 100644
index 0000000..4dfd9bf
--- /dev/null
+++ b/user/module/debug/makefile-flags
@@ -0,0 +1,30 @@
+
+MODULE=debug
+
+DEPRDIR=deprecated
+DOCDIR=doc
+EXECDIR=exec
+INCDIR=include
+LIBDIR=lib
+SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
+SRCDIR=src
+TESTDIR=test
+TMPDIR=tmp
+TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
+TRYDIR=try
+
+DEPFILE=$(TMPDIR)/makefile-cc.deps
+LIBFILE=$(LIBDIR)/lib$(MODULE).a
+INCFILE=$(INCDIR)/$(MODULE).h
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# compiler and flags
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
+LINKFLAGS=-L$(LIBDIR) -l$(MODULE)
+
+
+
diff --git a/user/module/debug/src/debug.lib.c b/user/module/debug/src/debug.lib.c
new file mode 100644
index 0000000..01ba20d
--- /dev/null
+++ b/user/module/debug/src/debug.lib.c
@@ -0,0 +1,14 @@
+
+#include "debug.lib.h"
+
+#include
+#include
+
+int debug_printf(const char *format, ...){
+ va_list args;
+ va_start(args,format);
+ int ret = vfprintf(stdout, format, args);
+ fflush(stdout);
+ va_end(args);
+ return ret;
+}
diff --git a/user/module/debug/src/debug.lib.h b/user/module/debug/src/debug.lib.h
new file mode 100644
index 0000000..f1be3d8
--- /dev/null
+++ b/user/module/debug/src/debug.lib.h
@@ -0,0 +1,6 @@
+#ifndef DB_LIB_H
+#define DB_LIB_H
+
+int debug_printf(const char *format, ...);
+
+#endif
diff --git a/user/module/dispatch/dispatch.lib.c b/user/module/dispatch/dispatch.lib.c
new file mode 100644
index 0000000..de7011f
--- /dev/null
+++ b/user/module/dispatch/dispatch.lib.c
@@ -0,0 +1,123 @@
+
+
+#include "dispatch.h"
+
+// we need the declaration for uid_t etc.
+// without this #define execvpe is undefined
+#define _GNU_SOURCE
+
+#include
+#include
+#include
+#include
+
+void dispatch_f_mess(char *fname, int err, char *dispatchee){
+ if(err == 0) return;
+ fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
+ if(err > ERR_DISPATCH){
+ fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
+ return;
+ }
+ switch(err){
+ case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
+ fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
+ break;
+ case ERR_DISPATCH_F_FORK:
+ case ERR_DISPATCH_F_SETEUID:
+ case ERR_DISPATCH_F_SETEGID:
+ fputc(' ', stderr);
+ perror(dispatchee);
+ break;
+ case ERR_DISPATCH_NULL_EXECUTABLE:
+ fprintf(stderr, " executable was not specified");
+ break;
+ case ERR_DISPATCH_EXEC:
+ // exec is running in another process when it fails, so we can't see the errno value it set
+ fprintf(stderr, " exec of \"%s\" failed", dispatchee);
+ break;
+ default:
+ fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
+ }
+ fputc('\n', stderr);
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
+ #ifdef DEBUG
+ debug_printf("%s %s\n", "dispatch_f", fname);
+ #endif
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+ if( pid == 0 ){ // we are the child
+ int status = (*f)(f_arg); // we require that f return a zero or positive value
+ if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+ exit(status);
+ }else{ // we are the parent
+ int err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function with a given euid/egid
+// of course this will only work if our euid is root in the first place
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
+ #ifdef DEBUG
+ debug_printf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
+ #endif
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK;
+ if( pid == 0 ){ // we are the child
+ int status;
+ if( seteuid(euid) == -1 )
+ status = ERR_DISPATCH_F_SETEUID;
+ else if( setegid(egid) == -1 )
+ status = ERR_DISPATCH_F_SETEGID;
+ else{
+ status = (*f)(f_arg);
+ if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+ exit(status);
+ }
+ }else{ // we are the parent
+ uint err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a executable
+int dispatch_exec(char **argv, char **envp){
+ char *command;
+ {
+ if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
+ #ifdef DEBUG
+ debug_printf("dispatch_exec:");
+ char **apt = argv;
+ while( *apt ){
+ debug_printf(" %s",*apt);
+ apt++;
+ }
+ debug_printf("\n");
+ #endif
+ command = argv[0];
+ }
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+ if( pid == 0 ){ // we are the child
+ execvpe(command, argv, envp); // exec will only return if it has an error
+ #ifdef DEBUG
+ debug_printf("dispatch_exec: exec returned, perror message:");
+ perror("dispatch_exec"); // our only chance to print this message, as this is the child process
+ #endif
+ fflush(stdout);
+ exit(ERR_DISPATCH_EXEC);
+ }else{ // we are the parent
+ int err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
diff --git a/user/module/dispatch/dispatch.lib.h b/user/module/dispatch/dispatch.lib.h
new file mode 100644
index 0000000..5e0994f
--- /dev/null
+++ b/user/module/dispatch/dispatch.lib.h
@@ -0,0 +1,31 @@
+/*
+ Runs a command or function as its own process.
+
+ The return status integer from command or function must be greater than ERR_DISPATCH.
+ In the case of dispatch_exec, we only have a promise from the user to not dispatch
+ non compliant commands.
+
+*/
+#ifndef DISPATCH_LIB_H
+#define DISPATCH_LIB_H
+#include
+#include
+
+#define ERR_DISPATCH -1024
+#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
+#define ERR_DISPATCH_F_FORK -1025
+#define ERR_DISPATCH_F_SETEUID -1026
+#define ERR_DISPATCH_F_SETEGID -1027
+#define ERR_DISPATCH_NULL_EXECUTABLE -1028
+#define ERR_DISPATCH_EXEC -1029
+
+// currently both dispatcher and dispatchee strings are statically allocated
+struct dispatch_ctx{
+ char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
+ char *dispatchee; // name of the function being dispatched
+ int err; // error code as listed below, or status returned from dispatchee
+};
+void dispatch_f_mess(char *fname, int err, char *dispatchee);
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
+int dispatch_exec(char **argv, char **envp);
diff --git a/user/module/dispatch/makefile b/user/module/dispatch/makefile
new file mode 100644
index 0000000..add0ff2
--- /dev/null
+++ b/user/module/dispatch/makefile
@@ -0,0 +1,45 @@
+# src-dispatch/makefile
+
+SHELL=/bin/bash
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+-include makefile-flags
+
+
+.PHONY: all
+all: version
+
+.PHONY: info
+info:
+ @echo "TRCDIR: " $(TRCDIR)
+ $(MAKE) $@
+
+.PHONY: setup
+setup:
+ [ ! -e $(TRCDIR) ] && mkdir $(TRCDIR) || true
+ $(MAKE) $@
+
+.PHONY: dep
+dep:
+ if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
+ @trcsources=$(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc);\
+ if [ ! -z "$$trcsources" ]; then\
+ trctargets=$$(tranche-target $$trcsources -sep " " -tdir $(SRCDIR) );\
+ $(ECHO) $$trcsources;\
+ tranche-make $$trcsources -tdir $(SRCDIR) -mfile $(DEPFILE);\
+ $(MAKE) $$trctargets;\
+ fi
+ $(MAKE) $@
+
+.PHONY: lib
+lib:
+ cp $(SRCDIR)/dispatch.lib.h $(INCDIR)/dispatch.h
+ $(MAKE) $@
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/dispatch/makefile-flags b/user/module/dispatch/makefile-flags
new file mode 100644
index 0000000..a50b71c
--- /dev/null
+++ b/user/module/dispatch/makefile-flags
@@ -0,0 +1,31 @@
+
+MODULE=dispatch
+
+DEPRDIR=deprecated
+DOCDIR=doc
+EXECDIR=exec
+INCDIR=include
+LIBDIR=lib
+SHAREDIR=../share
+SRCDIR=tmp
+TESTDIR=test
+TMPDIR=tmp
+TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
+TRCDIR=trc
+TRYDIR=try
+
+DEPFILE=$(TMPDIR)/makefile-trc.deps
+LIBFILE=$(LIBDIR)/lib$(MODULE).a
+INCFILE=$(INCDIR)/$(MODULE).h
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# compiler and flags
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
+LINKFLAGS=-L$(LIBDIR) -L(SHAREDIR)/lib -ldebug
+
+
+
diff --git a/user/module/dispatch/tranche b/user/module/dispatch/tranche
new file mode 100755
index 0000000..ad95624
Binary files /dev/null and b/user/module/dispatch/tranche differ
diff --git a/user/module/dispatch/trc/dispatch.trc.c b/user/module/dispatch/trc/dispatch.trc.c
new file mode 100644
index 0000000..f08602c
--- /dev/null
+++ b/user/module/dispatch/trc/dispatch.trc.c
@@ -0,0 +1,171 @@
+#tranche dispatch.lib.c
+
+#tranche dispatch.lib.h
+ /*
+ Runs a command or function as its own process.
+
+ The return status integer from command or function must be greater than ERR_DISPATCH.
+ In the case of dispatch_exec, we only have a promise from the user to not dispatch
+ non compliant commands.
+
+ */
+ #ifndef DISPATCH_LIB_H
+ #define DISPATCH_LIB_H
+ #include
+ #include
+
+ #define ERR_DISPATCH -1024
+ #define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
+ #define ERR_DISPATCH_F_FORK -1025
+ #define ERR_DISPATCH_F_SETEUID -1026
+ #define ERR_DISPATCH_F_SETEGID -1027
+ #define ERR_DISPATCH_NULL_EXECUTABLE -1028
+ #define ERR_DISPATCH_EXEC -1029
+
+ // currently both dispatcher and dispatchee strings are statically allocated
+ struct dispatch_ctx{
+ char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
+ char *dispatchee; // name of the function being dispatched
+ int err; // error code as listed below, or status returned from dispatchee
+ };
+#tranche-end
+
+
+// we need the declaration for uid_t etc.
+// without this #define execvpe is undefined
+#define _GNU_SOURCE
+
+#include
+#include
+#include
+#include
+#include
+#include "dispatch.lib.h"
+
+#tranche dispatch.lib.h
+void dispatch_f_mess(char *fname, int err, char *dispatchee);
+#tranche-end
+void dispatch_f_mess(char *fname, int err, char *dispatchee){
+ if(err == 0) return;
+ fprintf(stderr, "%s: ", fname); // if fprintf gets an error, errno will be overwritten
+ if(err > ERR_DISPATCH){
+ fprintf(stderr, "dispatchee \"%s\" returned the error %d\n", dispatchee, err);
+ return;
+ }
+ switch(err){
+ case ERR_DISPATCH_NEGATIVE_RETURN_STATUS:
+ fprintf(stderr, " dispatchee \"%s\" returned a negative status.", dispatchee);
+ break;
+ case ERR_DISPATCH_F_FORK:
+ case ERR_DISPATCH_F_SETEUID:
+ case ERR_DISPATCH_F_SETEGID:
+ fputc(' ', stderr);
+ perror(dispatchee);
+ break;
+ case ERR_DISPATCH_NULL_EXECUTABLE:
+ fprintf(stderr, " executable was not specified");
+ break;
+ case ERR_DISPATCH_EXEC:
+ // exec is running in another process when it fails, so we can't see the errno value it set
+ fprintf(stderr, " exec of \"%s\" failed", dispatchee);
+ break;
+ default:
+ fprintf(stderr, " returned undefined status when dispatching \"%s\"", dispatchee);
+ }
+ fputc('\n', stderr);
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function
+#tranche dispatch.lib.h
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
+#tranche-end
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg){
+ #ifdef DEBUG
+ debug_printf("%s %s\n", "dispatch_f", fname);
+ #endif
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+ if( pid == 0 ){ // we are the child
+ int status = (*f)(f_arg); // we require that f return a zero or positive value
+ if( status < ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+ exit(status);
+ }else{ // we are the parent
+ int err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a function with a given euid/egid
+// of course this will only work if our euid is root in the first place
+#tranche dispatch.lib.h
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
+#tranche-end
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid){
+ #ifdef DEBUG
+ debug_printf("%s %s as euid:%u egid:%u\n", "dispatch_f_euid_egid", fname, euid, egid);
+ #endif
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK;
+ if( pid == 0 ){ // we are the child
+ int status;
+ if( seteuid(euid) == -1 )
+ status = ERR_DISPATCH_F_SETEUID;
+ else if( setegid(egid) == -1 )
+ status = ERR_DISPATCH_F_SETEGID;
+ else{
+ status = (*f)(f_arg);
+ if( status <= ERR_DISPATCH ) status = ERR_DISPATCH_NEGATIVE_RETURN_STATUS;
+ exit(status);
+ }
+ }else{ // we are the parent
+ uint err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// interface call point, dispatch a executable
+#tranche dispatch.lib.h
+int dispatch_exec(char **argv, char **envp);
+#tranche-end
+int dispatch_exec(char **argv, char **envp){
+ char *command;
+ {
+ if( !argv || !argv[0] ) return ERR_DISPATCH_NULL_EXECUTABLE;
+ #ifdef DEBUG
+ debug_printf("dispatch_exec:");
+ char **apt = argv;
+ while( *apt ){
+ debug_printf(" %s",*apt);
+ apt++;
+ }
+ debug_printf("\n");
+ #endif
+ command = argv[0];
+ }
+ pid_t pid = fork();
+ if( pid == -1 ) return ERR_DISPATCH_F_FORK; // something went wrong and we are still in the parent process
+ if( pid == 0 ){ // we are the child
+ execvpe(command, argv, envp); // exec will only return if it has an error
+ #ifdef DEBUG
+ debug_printf("dispatch_exec: exec returned, perror message:");
+ perror("dispatch_exec"); // our only chance to print this message, as this is the child process
+ #endif
+ fflush(stdout);
+ exit(ERR_DISPATCH_EXEC);
+ }else{ // we are the parent
+ int err;
+ waitpid(pid, &err, 0);
+ return err;
+ }
+}
+
+#tranche dispatch.lib.h
+#endif
+#tranche-end
+
+#tranche-end
diff --git a/user/module/share/include/da.h b/user/module/share/include/da.h
new file mode 100644
index 0000000..9043cda
--- /dev/null
+++ b/user/module/share/include/da.h
@@ -0,0 +1,114 @@
+#ifndef DA_LIB_H
+#define DA_LIB_H
+#include
+#include
+#include
+
+typedef struct {
+ char *base;
+ char *end; // one byte/one element off the end of the array
+ size_t size; // size >= (end - base) + 1;
+ size_t element_size;
+} Da;
+
+//#include "da_na.lib.h"
+
+#define RETURN(dap, r) \
+ { da_free_elements(dap); return r; }
+
+
+void da_alloc(Da *dap, size_t element_size);
+void da_free(Da *dap);
+void da_rewind(Da *dap);
+bool da_empty(Da *dap);
+size_t da_length(Da *dap);
+void da_rebase(Da *dap, char *old_base, void *pta);
+char *da_expand(Da *dap);
+bool da_boundq(Da *dap);
+
+char *da_index(Da *dap, size_t i);
+char *da_push_alloc(Da *dap);
+char *da_push(Da *dap, void *element);
+bool da_pop(Da *dap, void *element);
+
+bool da_endq(Da *dap, void *pt);
+void da_map(Da *dap, void f(void *, void *), void *closure);
+
+void da_free_elements(Da *dap);
+
+void da_ints_print(Da *dap, char *sep);
+bool da_integer_repeats(Da *dap);
+int da_integer_sum(Da *dap);
+
+
+void da_strings_print(Da *dap, char *sep);
+
+bool da_strings_exists(Da *string_arrp, char *test_string);
+void da_strings_set_insert(Da *string_arrp, char *proffered_string, void destruct(void *));
+void da_strings_set_union(Da *string_arrp, Da *proffered_string_arrp, void destruct(void *));
+
+
+char *da_string_input(Da *dap, FILE *file);
+void da_string_push(Da *dap0, char *string);
+
+void da_cat(Da *dap_base, Da *dap_cat);
+
+void da_present(Da **dar, int dar_size, void *closure);
+bool da_equal(Da *da_el, Da *test_el);
+void da_matrix_map(Da **dar, int dar_size, void f(void *,void*), void *closure);
+
+bool da_exists(Da *dap, bool f(void *, void*), void *closure);
+bool da_all(Da *dap, bool f(void *, void*), void *closure);
+
+//matrix functions
+void da_erase(Da *damp);
+Da *da_push_row_alloc(Da *damp);
+Da *da_push_row(Da *damp, Da *dap);
+void da_push_column(Da *damp, Da *dap, void *fill);
+
+void da_every_row(Da *damp, void f(void *, void *), void *closure);
+Da *da_longer(Da *dap0, Da *dap1);
+Da *da_longest(Da *damp);
+void da_every_column(Da *damp, void f(void *, void *), void *closure);
+
+Da *da_matrix_transpose(Da *damp, void *fill);
+
+bool da_length_equal(Da *dap0, Da *dap1);
+bool da_all_rows_same_length(Da *damp);
+bool da_integer_all_rows_repeat(Da *damp);
+bool da_integer_all_columns_repeat(Da *damp);
+bool da_integer_repeats_matrix(Da *damp);
+
+Da *da_integer_transpose(Da *damp, int *fill);
+int *da_integer_to_raw_image_matrix(Da *damp, int fill);
+int *da_integer_to_raw_image_transpose(Da *damp, int fill);
+
+
+/*
+Accounting for all the pointers for which we allocated memory on the heap.
+
+Replacement for malloc and free that allows us to check if all the memory we allocated was freed, and if all the memory we tried to free was actually allocated by keeping registers of pointers in Da structs.
+ */
+
+#define MALLOC da_malloc_counted
+#define FREE da_free_counted
+#define ACCOUNT da_start_accounting()
+#define BALANCE da_result_accounting()
+#define CLOSE_ACC da_na_free(&heap_acc); da_na_free(&extra_frees)
+
+//These variables must be declared at global scope in file that will use them.
+extern Da heap_acc; extern Da extra_frees; extern bool accounting;
+
+void da_start_accounting();
+void *da_malloc_counted(size_t mem_size);
+void da_free_counted(void *pt);
+bool da_result_accounting(void);
+
+char *da_na_expand(Da *dap);
+char *da_na_push_alloc(Da *dap);
+char *da_na_push(Da *dap, void *element);
+void da_na_free(Da *dap);
+
+
+#endif
+
diff --git a/user/module/share/include/debug.h b/user/module/share/include/debug.h
new file mode 100644
index 0000000..f1be3d8
--- /dev/null
+++ b/user/module/share/include/debug.h
@@ -0,0 +1,6 @@
+#ifndef DB_LIB_H
+#define DB_LIB_H
+
+int debug_printf(const char *format, ...);
+
+#endif
diff --git a/user/module/share/include/dispatch.h b/user/module/share/include/dispatch.h
new file mode 100644
index 0000000..8b99d43
--- /dev/null
+++ b/user/module/share/include/dispatch.h
@@ -0,0 +1,32 @@
+ /*
+ Runs a command or function as its own process.
+
+ The return status integer from command or function must be greater than ERR_DISPATCH.
+ In the case of dispatch_exec, we only have a promise from the user to not dispatch
+ non compliant commands.
+
+ */
+ #ifndef DISPATCH_LIB_H
+ #define DISPATCH_LIB_H
+ #include
+ #include
+
+ #define ERR_DISPATCH -1024
+ #define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
+ #define ERR_DISPATCH_F_FORK -1025
+ #define ERR_DISPATCH_F_SETEUID -1026
+ #define ERR_DISPATCH_F_SETEGID -1027
+ #define ERR_DISPATCH_NULL_EXECUTABLE -1028
+ #define ERR_DISPATCH_EXEC -1029
+
+ // currently both dispatcher and dispatchee strings are statically allocated
+ struct dispatch_ctx{
+ char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
+ char *dispatchee; // name of the function being dispatched
+ int err; // error code as listed below, or status returned from dispatchee
+ };
+void dispatch_f_mess(char *fname, int err, char *dispatchee);
+int dispatch_f(char *fname, int (*f)(void *arg), void *f_arg);
+int dispatch_f_euid_egid(char *fname, int (*f)(void *arg), void *f_arg, uid_t euid, gid_t egid);
+int dispatch_exec(char **argv, char **envp);
+#endif
diff --git a/user/module/share/include/subu.h b/user/module/share/include/subu.h
new file mode 100644
index 0000000..5a82782
--- /dev/null
+++ b/user/module/share/include/subu.h
@@ -0,0 +1,63 @@
+ typedef unsigned int uint;
+ /*
+ Fedora 29's sss_cache is checking the inherited uid instead of the effective
+ uid, so setuid root scripts will fail when calling sss_cache.
+
+ Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root
+ program subu-mk-0.
+ */
+ #define BUG_SSS_CACHE_RUID 1
+ // extern char *DB_File;
+ extern char DB_File[];
+ extern uint Subuhome_Perms;
+ extern uint First_Max_Subunumber;
+ extern char Subuland_Extension[];
+ /*
+ The db file is maintained in SQLite
+
+ Because linux user names are limited length, subu user names are of a compact
+ form: _s. A separate table translates the numbers into the subu names.
+
+ Each of these returns SQLITE_OK upon success
+ */
+ #include
+ #include
+ int db_begin(sqlite3 *db);
+ int db_commit(sqlite3 *db);
+ int db_rollback(sqlite3 *db);
+ int subudb_schema(sqlite3 *db);
+ int subudb_number_get(sqlite3 *db, int *n);
+ int subudb_number_set(sqlite3 *db, int n);
+ int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
+ int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username);
+ typedef struct{
+ char *subuname; // the name that masteru chose for his or her subu
+ char *subu_username; // the adduser name we gave it, typically of the s
+ } subudb_subu_element;
+ int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subus);
+ int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
+ #include
+ #include
+ #include
+ char *useradd_mess(int err);
+ char *userdel_mess(int err);
+ #define SUBU_ERR_ARG_CNT 1
+ #define SUBU_ERR_SETUID_ROOT 2
+ #define SUBU_ERR_MALLOC 3
+ #define SUBU_ERR_MKDIR_SUBUHOME 4
+ #define SUBU_ERR_RMDIR_SUBUHOME 5
+ #define SUBU_ERR_SUBUNAME_MALFORMED 6
+ #define SUBU_ERR_HOMELESS 7
+ #define SUBU_ERR_DB_FILE 8
+ #define SUBU_ERR_SUBUHOME_EXISTS 9
+ #define SUBU_ERR_BUG_SSS 10
+ #define SUBU_ERR_FAILED_USERADD 11
+ #define SUBU_ERR_FAILED_USERDEL 12
+ #define SUBU_ERR_SUBU_NOT_FOUND 13
+ #define SUBU_ERR_N 14
+ #define SUBU_ERR_BIND 15
+ void subu_err(char *fname, int err, char *mess);
+ int subu_mk_0(char **mess, sqlite3 *db, char *subuname);
+ int subu_rm_0(char **mess, sqlite3 *db, char *subuname);
+ int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome);
+ int subu_bind_all(char **mess, sqlite3 *db);
diff --git a/user/module/share/include/tranche.h b/user/module/share/include/tranche.h
new file mode 100644
index 0000000..4c1d2f3
--- /dev/null
+++ b/user/module/share/include/tranche.h
@@ -0,0 +1,12 @@
+#ifndef TRANCHE_LIB_H
+#define TRANCHE_LIB_H
+
+#define TRANCHE_ERR_ARGC 1
+#define TRANCHE_ERR_SRC_OPEN 2
+#define TRANCHE_ERR_DEP_OPEN 4
+
+int tranche_send(FILE *src, Da *arg_fds);
+int tranche_target(FILE *src, Da *targets);
+
+
+#endif
diff --git a/user/module/share/lib b/user/module/share/lib
new file mode 100644
index 0000000..eb95acc
Binary files /dev/null and b/user/module/share/lib differ
diff --git a/user/module/subu-0/deprecated/0_makefile b/user/module/subu-0/deprecated/0_makefile
new file mode 100644
index 0000000..f0708ef
--- /dev/null
+++ b/user/module/subu-0/deprecated/0_makefile
@@ -0,0 +1,40 @@
+# src/0_makefile
+
+SHELL=/bin/bash
+
+-include 0_makefile_flags
+
+SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh
+MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc
+
+SOURCES=$(wildcard *.c)
+HFILES=$(wildcard *.h)
+
+all: version deps lib execs
+
+version:
+ $(MAKE) $@
+ @echo "SUID_TOOL: " $(SUID_TOOL)
+
+deps:
+ makeheaders $(SOURCES) $(HFILES)
+ sed -i '/^ *int *main *(.*)/d' *.h
+ $(MAKE) $@
+
+execs:
+ $(MAKE) $@
+ @echo "-> $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all"
+ cat $(SUID_TOOL)
+ @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ]
+ sudo $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all
+
+clean:
+ $(MAKE) $@
+ for i in $(HFILES); do rm $$i; done
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/subu-0/deprecated/0_makefile-flags b/user/module/subu-0/deprecated/0_makefile-flags
new file mode 100644
index 0000000..d4df01f
--- /dev/null
+++ b/user/module/subu-0/deprecated/0_makefile-flags
@@ -0,0 +1,31 @@
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# directories used by this makefile, these could all be set to dot for
+# the simplest source directory structure
+
+#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared
+#$(PWD) is the directory that make was called from, this is already build in
+#set to dot to use the same directory as the source code
+#leave blank to ommit
+DEPRDIR=1_deprecated
+DOCDIR=1_doc
+EXECSDIR=1_execs
+HDIR=1_headers
+LIBDIR=1_lib
+TESTDIR=1_tests
+TMPDIR=1_tmp
+TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools)
+TRYDIR=1_try
+
+
+# compiler and flags
+CC=gcc
+CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB
+#CFLAGS=-std=gnu11 -fPIC -I. -Werror
+LINKFLAGS=-L1_lib -lsubu -lsqlite3
+
+LIBFILE=$(LIBDIR)/libsubu.a
+
diff --git a/user/module/subu-0/deprecated/1_tmp/da.lib.h b/user/module/subu-0/deprecated/1_tmp/da.lib.h
new file mode 100644
index 0000000..4702189
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/da.lib.h
@@ -0,0 +1,23 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+#include
+void daps_map(char **base,char **end_pt,void f(void *));
+#define RETURN(rc) \
+ { daps_map(mrs, mrs_end, free); return rc; }
+void daps_alloc(char ***base,size_t *s);
+#define MK_MRS \
+ char **mrs; \
+ char **mrs_end; \
+ size_t mrs_size; \
+ daps_alloc(&mrs, &mrs_size);\
+ mrs_end = mrs;
+void daps_push(char ***base,char ***pt,size_t *s,char *item);
+bool daps_bound(char **base,char **pt,size_t s);
+void daps_expand(char ***base,char ***pt,size_t *s);
+void da_map(void *base,void *end_pt,void f(void *),size_t item_size);
+void da_push(void **base,void **pt,size_t *s,void *item,size_t item_size);
+bool da_bound(void *base,void *pt,size_t s);
+void da_expand(void **base,void **pt,size_t *s);
+void da_alloc(void **base,size_t *s,size_t item_size);
+#define INTERFACE 0
diff --git a/user/module/subu-0/deprecated/1_tmp/dbprintf.lib.h b/user/module/subu-0/deprecated/1_tmp/dbprintf.lib.h
new file mode 100644
index 0000000..3056cf6
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/dbprintf.lib.h
@@ -0,0 +1,3 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+int dbprintf(const char *format,...);
diff --git a/user/module/subu-0/deprecated/1_tmp/dispatch.lib.h b/user/module/subu-0/deprecated/1_tmp/dispatch.lib.h
new file mode 100644
index 0000000..07e2271
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/dispatch.lib.h
@@ -0,0 +1,24 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+#include
+int dispatch_exec(char **argv,char **envp);
+typedef unsigned int uint;
+int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid);
+int dbprintf(const char *format,...);
+int dispatch_f(char *fname,int(*f)(void *arg),void *f_arg);
+void dispatch_f_mess(char *fname,int err,char *dispatchee);
+#define ERR_DISPATCH_EXEC -1029
+#define ERR_DISPATCH_NULL_EXECUTABLE -1028
+#define ERR_DISPATCH_F_SETEGID -1027
+#define ERR_DISPATCH_F_SETEUID -1026
+#define ERR_DISPATCH_F_FORK -1025
+#define ERR_DISPATCH_NEGATIVE_RETURN_STATUS -1024
+#define ERR_DISPATCH -1024
+typedef struct dispatch_ctx dispatch_ctx;
+struct dispatch_ctx {
+ char *dispatcher; // name of the dispatch function ("dispatch_f", "dispatch_f_euid_egid", etc.)
+ char *dispatchee; // name of the function being dispatched
+ int err; // error code as listed below, or status returned from dispatchee
+};
+#define INTERFACE 0
diff --git a/user/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h b/user/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h
new file mode 100644
index 0000000..7e52675
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subu-bind-all.cli.h
@@ -0,0 +1,9 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+#include
+#include
+int subu_bind_all(char **mess,sqlite3 *db);
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subu-bind.cli.h b/user/module/subu-0/deprecated/1_tmp/subu-bind.cli.h
new file mode 100644
index 0000000..af12d61
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subu-bind.cli.h
@@ -0,0 +1,7 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+#include
+#include
+int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome);
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subu-common.lib.h b/user/module/subu-0/deprecated/1_tmp/subu-common.lib.h
new file mode 100644
index 0000000..cfdc520
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subu-common.lib.h
@@ -0,0 +1,9 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+extern char Subuland_Extension[];
+typedef unsigned int uint;
+extern uint First_Max_Subunumber;
+extern uint Subuhome_Perms;
+extern char DB_File[];
+#define BUG_SSS_CACHE_RUID 1
+#define INTERFACE 0
diff --git a/user/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h b/user/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h
new file mode 100644
index 0000000..487b509
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subu-mk-0.cli.h
@@ -0,0 +1,10 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+#include
+#include
+void subu_err(char *fname,int err,char *mess);
+int subu_mk_0(char **mess,sqlite3 *db,char *subuname);
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h b/user/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h
new file mode 100644
index 0000000..070bfe8
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subu-rm-0.cli.h
@@ -0,0 +1,10 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+#include
+#include
+void subu_err(char *fname,int err,char *mess);
+int subu_rm_0(char **mess,sqlite3 *db,char *subuname);
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subu.lib.h b/user/module/subu-0/deprecated/1_tmp/subu.lib.h
new file mode 100644
index 0000000..69c5da7
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subu.lib.h
@@ -0,0 +1,66 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+typedef unsigned int uint;
+#include
+typedef struct subudb_subu_element subudb_subu_element;
+int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt);
+struct subudb_subu_element {
+ char *subuname;
+ char *subu_username;
+};
+#include
+#include
+int subu_bind_all(char **mess,sqlite3 *db);
+int subu_bind(char **mess,char *masteru_name,char *subu_username,char *subuhome);
+int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username);
+int subu_rm_0(char **mess,sqlite3 *db,char *subuname);
+int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+#include
+#include
+int dispatch_exec(char **argv,char **envp);
+#define BUG_SSS_CACHE_RUID 1
+void dispatch_f_mess(char *fname,int err,char *dispatchee);
+#define ERR_DISPATCH -1024
+int dispatch_f_euid_egid(char *fname,int(*f)(void *arg),void *f_arg,uid_t euid,gid_t egid);
+#include
+void daps_map(char **base,char **end_pt,void f(void *));
+#define RETURN(rc) \
+ { daps_map(mrs, mrs_end, free); return rc; }
+void daps_push(char ***base,char ***pt,size_t *s,char *item);
+int dbprintf(const char *format,...);
+void daps_alloc(char ***base,size_t *s);
+#define MK_MRS \
+ char **mrs; \
+ char **mrs_end; \
+ size_t mrs_size; \
+ daps_alloc(&mrs, &mrs_size);\
+ mrs_end = mrs;
+int subu_mk_0(char **mess,sqlite3 *db,char *subuname);
+extern char Subuland_Extension[];
+int db_commit(sqlite3 *db);
+int db_rollback(sqlite3 *db);
+int subudb_number_set(sqlite3 *db,int n);
+int subudb_number_get(sqlite3 *db,int *n);
+int db_begin(sqlite3 *db);
+extern uint Subuhome_Perms;
+extern char DB_File[];
+void subu_err(char *fname,int err,char *mess);
+#define SUBU_ERR_BIND 15
+#define SUBU_ERR_N 14
+#define SUBU_ERR_SUBU_NOT_FOUND 13
+#define SUBU_ERR_FAILED_USERDEL 12
+#define SUBU_ERR_FAILED_USERADD 11
+#define SUBU_ERR_BUG_SSS 10
+#define SUBU_ERR_SUBUHOME_EXISTS 9
+#define SUBU_ERR_DB_FILE 8
+#define SUBU_ERR_HOMELESS 7
+#define SUBU_ERR_SUBUNAME_MALFORMED 6
+#define SUBU_ERR_RMDIR_SUBUHOME 5
+#define SUBU_ERR_MKDIR_SUBUHOME 4
+#define SUBU_ERR_MALLOC 3
+#define SUBU_ERR_SETUID_ROOT 2
+#define SUBU_ERR_ARG_CNT 1
+char *userdel_mess(int err);
+char *useradd_mess(int err);
+#define INTERFACE 0
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb-init.cli.h b/user/module/subu-0/deprecated/1_tmp/subudb-init.cli.h
new file mode 100644
index 0000000..4435103
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb-init.cli.h
@@ -0,0 +1,11 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+int db_commit(sqlite3 *db);
+int db_rollback(sqlite3 *db);
+int subudb_schema(sqlite3 *db);
+int db_begin(sqlite3 *db);
+#include
+#include
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb-number.cli.h b/user/module/subu-0/deprecated/1_tmp/subudb-number.cli.h
new file mode 100644
index 0000000..c130fbb
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb-number.cli.h
@@ -0,0 +1,11 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+int subudb_number_get(sqlite3 *db,int *n);
+int subudb_number_set(sqlite3 *db,int n);
+#include
+#include
+#define SUBU_ERR_N 14
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h b/user/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h
new file mode 100644
index 0000000..4f335be
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb-rel-get.cli.h
@@ -0,0 +1,9 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username);
+#include
+#include
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h b/user/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h
new file mode 100644
index 0000000..243b3a9
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb-rel-put.cli.h
@@ -0,0 +1,8 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+#include
+#include
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h b/user/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h
new file mode 100644
index 0000000..595427f
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb-rel-rm.cli.h
@@ -0,0 +1,8 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+#include
+#include
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h b/user/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h
new file mode 100644
index 0000000..16310b7
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb-subus.cli.h
@@ -0,0 +1,14 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+typedef struct subudb_subu_element subudb_subu_element;
+int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt);
+struct subudb_subu_element {
+ char *subuname;
+ char *subu_username;
+};
+#include
+#include
+#define SUBU_ERR_DB_FILE 8
+extern char DB_File[];
+#define SUBU_ERR_ARG_CNT 1
diff --git a/user/module/subu-0/deprecated/1_tmp/subudb.lib.h b/user/module/subu-0/deprecated/1_tmp/subudb.lib.h
new file mode 100644
index 0000000..be73823
--- /dev/null
+++ b/user/module/subu-0/deprecated/1_tmp/subudb.lib.h
@@ -0,0 +1,27 @@
+/* This file was automatically generated. Do not edit! */
+#undef INTERFACE
+#include
+int subudb_Masteru_Subu_rm(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+#include
+#include
+void da_expand(void **base,void **pt,size_t *s);
+bool da_bound(void *base,void *pt,size_t s);
+typedef struct subudb_subu_element subudb_subu_element;
+int subudb_Masteru_Subu_get_subus(sqlite3 *db,char *masteru_name,subudb_subu_element **sa_pt,subudb_subu_element **sa_end_pt);
+void subu_element_free(subudb_subu_element *base,subudb_subu_element *end_pt);
+void da_alloc(void **base,size_t *s,size_t item_size);
+struct subudb_subu_element {
+ char *subuname;
+ char *subu_username;
+};
+int subudb_Masteru_Subu_get_subu_username(sqlite3 *db,char *masteru_name,char *subuname,char **subu_username);
+int subudb_Masteru_Subu_put(sqlite3 *db,char *masteru_name,char *subuname,char *subu_username);
+int subudb_number_set(sqlite3 *db,int n);
+int subudb_number_get(sqlite3 *db,int *n);
+typedef unsigned int uint;
+extern uint First_Max_Subunumber;
+int subudb_schema(sqlite3 *db);
+int db_rollback(sqlite3 *db);
+int db_commit(sqlite3 *db);
+int db_begin(sqlite3 *db);
+#define INTERFACE 0
diff --git a/user/module/subu-0/doc/todo.txt b/user/module/subu-0/doc/todo.txt
new file mode 100644
index 0000000..3631ba1
--- /dev/null
+++ b/user/module/subu-0/doc/todo.txt
@@ -0,0 +1,41 @@
+2019-02-05T23:14:40Z
+ error can cause subu-mk-0 to leave the creating of a subu in an intermediate
+ state. Rather than bailing on some of the errors we need to clean up instead.
+ Perhaps the yet to be written subu-rm program will be resilent enough to do
+ more general cleanup.
+
+2019-02-23T18:56:31Z
+ need to modify subu-init to take a configuration file name argument instead of
+ using a global variabel value. might want to add arguments to other subu
+ commands also
+
+2019-03-11T13:48:03Z
+ in subu.lib.c append cascading rmdir failure mess to useradd failure mess
+
+2019-03-11T13:48:03Z
+ want to add subu-type to masteru_subu(), I imagine there will be static,
+ permanent, and temporary subu types.
+
+2019-03-12T18:35:06Z
+ the masteru subu relation should contain the uid of the masteru as
+ well as the backup type for the subu: git, rdiff, rsync, none.
+ and the persisitance fo the subu: indefinite, session.
+ seems that operations need to be logged, in case the db is lost
+ the transcript can be played back. It should also be possible
+ to co-opt an existing user as a subu, though, would require
+ sudo privs.
+
+ need to add messages for subu errors I've added to the end of
+ the list in subu.lib.c
+
+2019-03-14T10:43:50Z
+
+ should mod all to he subudb routines to return a message, probably
+ strdup(sqlite_errmsg(db)), then the callers to these routines can just pass
+ mess in rather than making up new ones for each situation. The error code
+ probably already carries the contexts specific message. Or perhaps add
+ a string cat function for message strings, that would run through a stream
+ and free the originals.
+
+2019-04-02T19:24:03Z
+ Really need to add a transcript to help recover if there are any problems.
diff --git a/user/module/subu-0/exec/subu-bind b/user/module/subu-0/exec/subu-bind
new file mode 100755
index 0000000..6e4b6fd
Binary files /dev/null and b/user/module/subu-0/exec/subu-bind differ
diff --git a/user/module/subu-0/exec/subu-bind-all b/user/module/subu-0/exec/subu-bind-all
new file mode 100755
index 0000000..5d29017
Binary files /dev/null and b/user/module/subu-0/exec/subu-bind-all differ
diff --git a/user/module/subu-0/exec/subu-mk-0 b/user/module/subu-0/exec/subu-mk-0
new file mode 100755
index 0000000..0889e0e
Binary files /dev/null and b/user/module/subu-0/exec/subu-mk-0 differ
diff --git a/user/module/subu-0/exec/subu-rm-0 b/user/module/subu-0/exec/subu-rm-0
new file mode 100755
index 0000000..f68421d
Binary files /dev/null and b/user/module/subu-0/exec/subu-rm-0 differ
diff --git a/user/module/subu-0/exec/subudb-init b/user/module/subu-0/exec/subudb-init
new file mode 100755
index 0000000..6d26441
Binary files /dev/null and b/user/module/subu-0/exec/subudb-init differ
diff --git a/user/module/subu-0/exec/subudb-number b/user/module/subu-0/exec/subudb-number
new file mode 100755
index 0000000..dd78319
Binary files /dev/null and b/user/module/subu-0/exec/subudb-number differ
diff --git a/user/module/subu-0/exec/subudb-rel-get b/user/module/subu-0/exec/subudb-rel-get
new file mode 100755
index 0000000..7093dab
Binary files /dev/null and b/user/module/subu-0/exec/subudb-rel-get differ
diff --git a/user/module/subu-0/exec/subudb-rel-put b/user/module/subu-0/exec/subudb-rel-put
new file mode 100755
index 0000000..4ddb70f
Binary files /dev/null and b/user/module/subu-0/exec/subudb-rel-put differ
diff --git a/user/module/subu-0/exec/subudb-rel-rm b/user/module/subu-0/exec/subudb-rel-rm
new file mode 100755
index 0000000..4284dcb
Binary files /dev/null and b/user/module/subu-0/exec/subudb-rel-rm differ
diff --git a/user/module/subu-0/exec/subudb-subus b/user/module/subu-0/exec/subudb-subus
new file mode 100755
index 0000000..8a2a01b
Binary files /dev/null and b/user/module/subu-0/exec/subudb-subus differ
diff --git a/user/module/subu-0/include/subu.h b/user/module/subu-0/include/subu.h
new file mode 100644
index 0000000..5a82782
--- /dev/null
+++ b/user/module/subu-0/include/subu.h
@@ -0,0 +1,63 @@
+ typedef unsigned int uint;
+ /*
+ Fedora 29's sss_cache is checking the inherited uid instead of the effective
+ uid, so setuid root scripts will fail when calling sss_cache.
+
+ Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root
+ program subu-mk-0.
+ */
+ #define BUG_SSS_CACHE_RUID 1
+ // extern char *DB_File;
+ extern char DB_File[];
+ extern uint Subuhome_Perms;
+ extern uint First_Max_Subunumber;
+ extern char Subuland_Extension[];
+ /*
+ The db file is maintained in SQLite
+
+ Because linux user names are limited length, subu user names are of a compact
+ form: _s. A separate table translates the numbers into the subu names.
+
+ Each of these returns SQLITE_OK upon success
+ */
+ #include
+ #include
+ int db_begin(sqlite3 *db);
+ int db_commit(sqlite3 *db);
+ int db_rollback(sqlite3 *db);
+ int subudb_schema(sqlite3 *db);
+ int subudb_number_get(sqlite3 *db, int *n);
+ int subudb_number_set(sqlite3 *db, int n);
+ int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
+ int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username);
+ typedef struct{
+ char *subuname; // the name that masteru chose for his or her subu
+ char *subu_username; // the adduser name we gave it, typically of the s
+ } subudb_subu_element;
+ int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subus);
+ int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
+ #include
+ #include
+ #include
+ char *useradd_mess(int err);
+ char *userdel_mess(int err);
+ #define SUBU_ERR_ARG_CNT 1
+ #define SUBU_ERR_SETUID_ROOT 2
+ #define SUBU_ERR_MALLOC 3
+ #define SUBU_ERR_MKDIR_SUBUHOME 4
+ #define SUBU_ERR_RMDIR_SUBUHOME 5
+ #define SUBU_ERR_SUBUNAME_MALFORMED 6
+ #define SUBU_ERR_HOMELESS 7
+ #define SUBU_ERR_DB_FILE 8
+ #define SUBU_ERR_SUBUHOME_EXISTS 9
+ #define SUBU_ERR_BUG_SSS 10
+ #define SUBU_ERR_FAILED_USERADD 11
+ #define SUBU_ERR_FAILED_USERDEL 12
+ #define SUBU_ERR_SUBU_NOT_FOUND 13
+ #define SUBU_ERR_N 14
+ #define SUBU_ERR_BIND 15
+ void subu_err(char *fname, int err, char *mess);
+ int subu_mk_0(char **mess, sqlite3 *db, char *subuname);
+ int subu_rm_0(char **mess, sqlite3 *db, char *subuname);
+ int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome);
+ int subu_bind_all(char **mess, sqlite3 *db);
diff --git a/user/module/subu-0/makefile b/user/module/subu-0/makefile
new file mode 100644
index 0000000..c12df9c
--- /dev/null
+++ b/user/module/subu-0/makefile
@@ -0,0 +1,52 @@
+# src-dispatch/makefile
+
+SHELL=/bin/bash
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+-include makefile-flags
+
+.PHONY: all
+all: version
+
+.PHONY: info
+info:
+ @echo "TRCDIR: " $(TRCDIR)
+ @echo "SHAREDIR: " $(SHAREDIR)
+ $(MAKE) $@
+
+.PHONY: setup
+setup:
+ [ ! -e $(TRCDIR) ] && mkdir $(TRCDIR) || true
+ $(MAKE) $@
+
+.PHONY: dep
+dep:
+ if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
+ trcsources=($(wildcard $(TRCDIR)/*.trc.c)$(wildcard $(TRCDIR)/*.trc.cc));\
+ if [ ! -z "$$trcsources" ]; then\
+ trctargets=$$(tranche-target $${trcsources[@]} -sep " " -tdir $(SRCDIR) );\
+ $(ECHO) "trcsources: " $${trcsources[@]};\
+ $(ECHO) "trctargets: " $$trctargets;\
+ tranche-make $${trcsources[@]} -tdir $(SRCDIR) -mfile $(DEPFILE);\
+ $(MAKE) $$trctargets;\
+ fi
+ $(MAKE) $@
+
+.PHONY: exec
+exec:
+ $(MAKE) $@
+
+.PHONY: lib
+lib:
+ cp $(SRCDIR)/common.lib.h $(INCDIR)/subu.h
+ cat $(SRCDIR)/subudb.lib.h >> $(INCDIR)/subu.h
+ cat $(SRCDIR)/subu.lib.h >> $(INCDIR)/subu.h
+ $(MAKE) $@
+
+%::
+ @echo default target
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/subu-0/makefile-flags b/user/module/subu-0/makefile-flags
new file mode 100644
index 0000000..ae748ac
--- /dev/null
+++ b/user/module/subu-0/makefile-flags
@@ -0,0 +1,28 @@
+
+MODULE=subu-0
+
+DEPRDIR=deprecated
+DOCDIR=doc
+EXECDIR=exec
+INCDIR=include
+LIBDIR=lib
+SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
+SRCDIR=tmp
+TESTDIR=test
+TMPDIR=tmp
+TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
+TRCDIR=trc
+TRYDIR=try
+
+DEPFILE=$(TMPDIR)/makefile-trc.deps
+LIBFILE=$(LIBDIR)/lib$(MODULE).a
+INCFILE=$(INCDIR)/$(MODULE).h
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# compiler and flags
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
+LINKFLAGS=-L$(LIBDIR) -L$(SHAREDIR)/lib/ -l$(MODULE) -lda -ldispatch -ldebug -lsqlite3
diff --git a/user/module/subu-0/trc/common.trc.c b/user/module/subu-0/trc/common.trc.c
new file mode 100644
index 0000000..fec4853
--- /dev/null
+++ b/user/module/subu-0/trc/common.trc.c
@@ -0,0 +1,29 @@
+#tranche common.lib.c
+#include "common.lib.h"
+
+#tranche common.lib.h
+ typedef unsigned int uint;
+ /*
+ Fedora 29's sss_cache is checking the inherited uid instead of the effective
+ uid, so setuid root scripts will fail when calling sss_cache.
+
+ Fedora 29's 'useradd' calls sss_cache, and useradd is called by our setuid root
+ program subu-mk-0.
+ */
+ #define BUG_SSS_CACHE_RUID 1
+#tranche-end
+
+#tranche common.lib.h
+ // extern char *DB_File;
+ extern char DB_File[];
+ extern uint Subuhome_Perms;
+ extern uint First_Max_Subunumber;
+ extern char Subuland_Extension[];
+#tranche-end
+// char *DB_File = "/etc/subudb";
+char DB_File[] = "subudb";
+uint Subuhome_Perms = 0700;
+uint First_Max_Subunumber = 114;
+char Subuland_Extension[] = "/subuland/";
+
+#tranche-end
diff --git a/user/module/subu-0/trc/subu-bind-all.trc.c b/user/module/subu-0/trc/subu-bind-all.trc.c
new file mode 100644
index 0000000..66dfe19
--- /dev/null
+++ b/user/module/subu-0/trc/subu-bind-all.trc.c
@@ -0,0 +1,34 @@
+#tranche subu-bind-all.cli.c
+/*
+mount all the subu user directories into master's subuland
+uses unmount to undo this
+
+*/
+#include
+#include
+#include "common.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+ if( argc != 1){
+ fprintf(stderr, "%s does not take arguments\n",argv[0]);
+ return SUBU_ERR_ARG_CNT;
+ }
+
+ int rc;
+ sqlite3 *db;
+ rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
+ return SUBU_ERR_DB_FILE;
+ }
+
+ char *mess;
+ rc = subu_bind_all(&mess, db);
+ if(rc != 0){
+ fprintf(stderr, "subu-bind: %s\n", mess);
+ return rc;
+ }
+ return 0;
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subu-bind.trc.c b/user/module/subu-0/trc/subu-bind.trc.c
new file mode 100644
index 0000000..93ce926
--- /dev/null
+++ b/user/module/subu-0/trc/subu-bind.trc.c
@@ -0,0 +1,29 @@
+#tranche subu-bind.cli.c
+/*
+mount a subu user directory into master's subuland
+uses unmount to undo this
+
+*/
+#include
+#include
+#include
+#include "common.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+
+ if( argc != 4){
+ fprintf(stderr, "usage: %s masteru subu_username subuhome\n",argv[0]);
+ return SUBU_ERR_ARG_CNT;
+ }
+
+ int rc;
+ char *mess;
+ rc = subu_bind(&mess, argv[1], argv[2], argv[3]);
+ if(rc != 0){
+ fprintf(stderr, "subu-bind: %s\n", mess);
+ return rc;
+ }
+ return 0;
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subu-mk-0.trc.c b/user/module/subu-0/trc/subu-mk-0.trc.c
new file mode 100644
index 0000000..0ae869b
--- /dev/null
+++ b/user/module/subu-0/trc/subu-mk-0.trc.c
@@ -0,0 +1,47 @@
+#tranche subu-mk-0.cli.c
+/*
+ subu-mk-0 command
+
+*/
+#include
+#include
+#include
+#include "common.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+ char *command = argv[0];
+ if( argc != 2 ){
+ fprintf(stderr, "usage: %s subu", command);
+ return SUBU_ERR_ARG_CNT;
+ }
+ char *subuname = argv[1];
+
+ int rc;
+ sqlite3 *db;
+ rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "error when opening db, %s\n", DB_File);
+ fprintf(stderr, "sqlite3 says: %s\n", sqlite3_errmsg(db));
+ sqlite3_close(db);
+ return SUBU_ERR_DB_FILE;
+ }
+
+ char *mess;
+ rc = subu_mk_0(&mess, db, subuname);
+ if( rc ){
+ subu_err("subu_mk_0", rc, mess);
+ free(mess);
+ sqlite3_close(db);
+ return rc;
+ }
+
+ rc = sqlite3_close(db);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subu-rm-0.trc.c b/user/module/subu-0/trc/subu-rm-0.trc.c
new file mode 100644
index 0000000..f7fa21b
--- /dev/null
+++ b/user/module/subu-0/trc/subu-rm-0.trc.c
@@ -0,0 +1,35 @@
+#tranche subu-rm-0.cli.c
+/*
+ subu-mk-0 command
+
+*/
+#include
+#include
+#include "common.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+ char *command = argv[0];
+ if( argc != 2 ){
+ fprintf(stderr, "usage: %s subu", command);
+ return SUBU_ERR_ARG_CNT;
+ }
+ char *subuname = argv[1];
+
+ sqlite3 *db;
+ {
+ int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File);
+ return SUBU_ERR_DB_FILE;
+ }}
+
+ {
+ char *mess=0;
+ int ret = subu_rm_0(&mess, db, subuname);
+ subu_err("subu_rm_0", ret, mess);
+ free(mess);
+ return ret;
+ }
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subu.trc.c b/user/module/subu-0/trc/subu.trc.c
new file mode 100644
index 0000000..6ce4625
--- /dev/null
+++ b/user/module/subu-0/trc/subu.trc.c
@@ -0,0 +1,742 @@
+#tranche subu.lib.c
+/*
+ sqllite3 is used to maintain the db file, which is currently compiled
+ in as /etc/subu.db, (or just subu.db for testing).
+
+ masteru is the user who ran this script. The masteru name comes from getuid
+ and /etc/passwd.
+
+ subu is a subservient user. The subuname is passed in as an argument.
+
+ subu-mk-0 synthesizes a new user user name s, calls useradd to creat
+ the new uswer account, and enters the relationship between masteru, subu, and
+ s in the db file. It is this relation in the db file that
+ associates the subuname with the s user.
+
+ subu-rm-0 uses userdel to delete the related s user account. It
+ then removes the relaton from the db file.
+
+ subu-mk-0 and subu-rm-0 are setuid root scripts.
+
+*/
+#include
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+// without this #define we get the warning: implicit declaration of function âseteuidâ/âsetegidâ
+#define _GNU_SOURCE
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#tranche subu.lib.h
+ #include
+ #include
+ #include
+#tranche-end
+
+//--------------------------------------------------------------------------------
+// dispatched command errors .. should add mkdir and rmdir ...
+//
+#tranche subu.lib.h
+ char *useradd_mess(int err);
+#tranche-end
+char *useradd_mess(int err){
+ if(err <= 0) return NULL;
+ char *mess;
+ switch(err){
+ case 1: mess = "can't update password file"; break;
+ case 2: mess = "invalid command syntax"; break;
+ case 3: mess = "invalid argument to option"; break;
+ case 4: mess = "UID already in use (and no -o)"; break;
+ case 5: mess = "undefined"; break;
+ case 6: mess = "specified group doesn't exist"; break;
+ case 7:
+ case 8: mess = "undefined"; break;
+ case 9: mess = "username already in use"; break;
+ case 10: mess = "can't update group file:"; break;
+ case 11: mess = "undefined"; break;
+ case 12: mess = "can't create home directory"; break;
+ case 13: mess = "undefined"; break;
+ case 14: mess = "can't update SELinux user mapping"; break;
+ default: mess = "undefined"; break;
+ }
+ return strdup(mess);
+}
+#tranche subu.lib.h
+ char *userdel_mess(int err);
+#tranche-end
+char *userdel_mess(int err){
+ if(err <= 0) return NULL;
+ char *mess;
+ switch(err){
+ case 1: mess = "can't update password file"; break;
+ case 2: mess = "invalid command syntax"; break;
+ case 3:
+ case 4:
+ case 5: mess = "undefined"; break;
+ case 6: mess = "specified user doesn't exist"; break;
+ case 7:
+ case 8:
+ case 9: mess = "undefined"; break;
+ case 10: mess = "can't update group file:"; break;
+ case 11: mess = "undefined"; break;
+ case 12: mess = "can't remove home directory"; break;
+ default: mess = "undefined"; break;
+ }
+ return strdup(mess);
+}
+
+
+//--------------------------------------------------------------------------------
+//
+#tranche subu.lib.h
+ #define SUBU_ERR_ARG_CNT 1
+ #define SUBU_ERR_SETUID_ROOT 2
+ #define SUBU_ERR_MALLOC 3
+ #define SUBU_ERR_MKDIR_SUBUHOME 4
+ #define SUBU_ERR_RMDIR_SUBUHOME 5
+ #define SUBU_ERR_SUBUNAME_MALFORMED 6
+ #define SUBU_ERR_HOMELESS 7
+ #define SUBU_ERR_DB_FILE 8
+ #define SUBU_ERR_SUBUHOME_EXISTS 9
+ #define SUBU_ERR_BUG_SSS 10
+ #define SUBU_ERR_FAILED_USERADD 11
+ #define SUBU_ERR_FAILED_USERDEL 12
+ #define SUBU_ERR_SUBU_NOT_FOUND 13
+ #define SUBU_ERR_N 14
+ #define SUBU_ERR_BIND 15
+#tranche-end
+#tranche subu.lib.h
+ void subu_err(char *fname, int err, char *mess);
+#tranche-end
+void subu_err(char *fname, int err, char *mess){
+ if(!mess) mess = "";
+ switch(err){
+ case 0: return;
+ case SUBU_ERR_ARG_CNT:
+ if(mess[0])
+ fprintf(stderr, "Incorrect number of arguments, %s", mess);
+ else
+ fprintf(stderr, "Incorrect number of arguments.", mess);
+ break;
+ case SUBU_ERR_SETUID_ROOT:
+ fprintf(stderr, "This program must be run setuid root from a user account.");
+ break;
+ case SUBU_ERR_MALLOC:
+ perror(fname);
+ break;
+ case SUBU_ERR_DB_FILE:
+ fprintf(stderr, "error on %s", DB_File); // DB_File is in common
+ fprintf(stderr, ": %s", mess);
+ break;
+ case SUBU_ERR_HOMELESS:
+ fprintf(stderr,"Masteru, \"%s\", has no home directory", mess);
+ break;
+ case SUBU_ERR_SUBUNAME_MALFORMED:
+ fprintf(stderr, "subuname, \"%s\" is not in [ _.-a-zA-Z0-9]*", mess);
+ break;
+ case SUBU_ERR_SUBUHOME_EXISTS:
+ fprintf(stderr, "a file system object already exists at subuhome, \"%s\"\n", mess);
+ break;
+ case SUBU_ERR_MKDIR_SUBUHOME:
+ fprintf(stderr, "masteru could not make subuhome, \"%s\"", mess);
+ break;
+ case SUBU_ERR_BUG_SSS:
+ perror(fname);
+ break;
+ case SUBU_ERR_FAILED_USERADD:
+ fprintf(stderr, "%s useradd failed\n", mess);
+ break;
+ default:
+ fprintf(stderr, "unknown error code %d\n", err);
+ }
+ fputc('\n', stderr);
+}
+
+
+//--------------------------------------------------------------------------------
+// a well formed subuname
+// returns the length of the subuname, or -1
+//
+static int allowed_subuname(char **mess, char *subuname, size_t *subuname_len){
+ char *ch = subuname;
+ size_t i = 0;
+ while(
+ *ch
+ &&
+ ( *ch >= 'a' && *ch <= 'z'
+ ||
+ *ch >= 'A' && *ch <= 'Z'
+ ||
+ *ch >= '0' && *ch <= '9'
+ ||
+ *ch == '-'
+ ||
+ *ch == '_'
+ ||
+ *ch == '.'
+ ||
+ *ch == ' '
+ )
+ ){
+ ch++;
+ i++;
+ }
+ if( !*ch ){
+ *subuname_len = i;
+ return 0;
+ }else{
+ if(mess) *mess = strdup(subuname);
+ return SUBU_ERR_SUBUNAME_MALFORMED;
+ }
+}
+
+//--------------------------------------------------------------------------------
+// dispatched functions
+//
+static int masteru_mkdir_subuhome(void *arg){
+ char *subuhome = (char *) arg;
+ if( mkdir( subuhome, Subuhome_Perms ) == -1 ){ // find subuhome perms in common
+ perror("masteru_mkdir_subuhome");
+ return SUBU_ERR_MKDIR_SUBUHOME;
+ }
+ return 0;
+}
+static int masteru_rmdir_subuhome(void *arg){
+ char *subuhome = (char *) arg;
+ if( rmdir( subuhome ) == -1 ){ // find subuhome perms in common
+ perror("masteru_rmdir_subuhome");
+ return SUBU_ERR_RMDIR_SUBUHOME;
+ }
+ return 0;
+}
+
+//--------------------------------------------------------------------------------
+// build strings
+//
+static int mk_subu_username(char **mess, sqlite3 *db, char **subu_username){
+ int rc,n;
+ db_begin(db);
+ if(
+ (rc = subudb_number_get(db, &n))
+ ||
+ (rc = subudb_number_set(db, ++n))
+ ){
+ db_rollback(db);
+ return SUBU_ERR_DB_FILE;
+ }
+ db_commit(db);
+
+ size_t len = 0;
+ FILE* name_stream = open_memstream(subu_username, &len);
+ fprintf(name_stream, "s%d", n);
+ fclose(name_stream);
+ return 0;
+}
+
+// man page says that getpwuid strings may not be freed, I don't know how long until they
+// are overwritten, so I just make my own copies that can be freed
+static int uid_to_name_and_home(uid_t uid, char **name, char **home ){
+ struct passwd *pw_record_pt = getpwuid(uid); // reading /etc/passwd
+ *name = strdup(pw_record_pt->pw_name);
+ *home = strdup(pw_record_pt->pw_dir);
+ if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS;
+ return 0;
+}
+
+static int username_to_home(char *name, char **home ){
+ struct passwd *pw_record_pt = getpwnam(name); // reading /etc/passwd
+ *home = strdup(pw_record_pt->pw_dir);
+ if( !home || !home[0] || (*home)[0] == '(' ) return SUBU_ERR_HOMELESS;
+ return 0;
+}
+
+static int mk_subuland(char *masteru_home, char **subuland){
+ size_t masteru_home_len = strlen(masteru_home);
+ char *Subuland_Extension = "/subuland/";
+ size_t Subuland_Extension_len = strlen(Subuland_Extension);
+ *subuland = (char *)malloc( masteru_home_len + Subuland_Extension_len + 1 );
+ if(!*subuland) SUBU_ERR_MALLOC;
+ strcpy(*subuland, masteru_home);
+ strcpy(*subuland + masteru_home_len, Subuland_Extension);
+ return 0;
+}
+
+static int mk_subuhome(char *subuland, char *subuname, char **subuhome){
+ size_t subuland_len = strlen(subuland);
+ size_t subuhome_len = subuland_len + strlen(subuname); // subuland has a trailing '/'
+ *subuhome = (char *)malloc(subuhome_len + 1);
+ if(!*subuhome) return SUBU_ERR_MALLOC;
+ strcpy (*subuhome, subuland);
+ strcpy (*subuhome + subuland_len, subuname);
+ return 0;
+}
+
+
+
+//===============================================================================
+#tranche subu.lib.h
+ int subu_mk_0(char **mess, sqlite3 *db, char *subuname);
+#tranche-end
+int subu_mk_0(char **mess, sqlite3 *db, char *subuname){
+
+ int rc;
+ if(mess)*mess = 0;
+ Da resources;
+ da_alloc(&resources, sizeof(char *));
+
+ //--------------------------------------------------------------------------------
+ size_t subuname_len;
+ rc = allowed_subuname(mess, subuname, &subuname_len);
+ if(rc) return rc;
+ #ifdef DEBUG
+ debug_printf("subuname is well formed\n");
+ #endif
+
+ //--------------------------------------------------------------------------------
+ uid_t masteru_uid;
+ gid_t masteru_gid;
+ uid_t set_euid;
+ gid_t set_egid;
+ {
+ masteru_uid = getuid();
+ masteru_gid = getgid();
+ set_euid = geteuid();
+ set_egid = getegid();
+ #ifdef DEBUG
+ debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid);
+ #endif
+ if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT;
+ }
+
+ //--------------------------------------------------------------------------------
+ char *masteru_name = 0;
+ char *masteru_home = 0;
+ char *subu_username = 0;
+ char *subuland = 0;
+ char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir
+ da_push(&resources, masteru_name);
+ da_push(&resources, masteru_home);
+ da_push(&resources, subu_username);
+ da_push(&resources, subuland);
+ da_push(&resources, subuhome);
+ rc =
+ uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
+ ||
+ mk_subu_username(mess, db, &subu_username)
+ ||
+ mk_subuland(masteru_home, &subuland)
+ ||
+ mk_subuhome(subuland, subuname, &subuhome)
+ ;
+ if(rc) RETURN(&resources, rc);
+ #ifdef DEBUG
+ debug_printf("subu_username, subuland, subuhome: \"%s\"\"%s\"\"%s\"\n", subu_username, subuland, subuhome);
+ #endif
+
+ //--------------------------------------------------------------------------------
+ // By having masteru create the subuhome, we know that masteru has rights to
+ // to access this directory. This will be the mount point for bindfs
+ {
+ struct stat st;
+ if( stat(subuhome, &st) != -1 ){
+ if(mess)*mess = strdup(subuhome);
+ RETURN(&resources, SUBU_ERR_SUBUHOME_EXISTS);
+ }
+ int dispatch_err = dispatch_f_euid_egid
+ (
+ "masteru_mkdir_subuhome",
+ masteru_mkdir_subuhome,
+ (void *)subuhome,
+ masteru_uid,
+ masteru_gid
+ );
+ if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_MKDIR_SUBUHOME ){
+ #ifdef DEBUG
+ dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_mkdir_subuhome");
+ #endif
+ if(mess)*mess = strdup(subuhome);
+ RETURN(&resources, SUBU_ERR_MKDIR_SUBUHOME);
+ }
+ }
+ #ifdef DEBUG
+ debug_printf("made directory \"%s\"\n", subuhome);
+ #endif
+
+ //--------------------------------------------------------------------------------
+ // Make the subservient user account, i.e. the subu
+ {
+ #ifdef DEBUG
+ debug_printf("making subu \"%s\" as user \"%s\"\n", subuname, subu_username);
+ #endif
+ #if BUG_SSS_CACHE_RUID
+ #ifdef DEBUG
+ debug_printf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n");
+ #endif
+ if( setuid(0) == -1 ) RETURN(&resources, SUBU_ERR_BUG_SSS);
+ #endif
+ char *command = "/usr/sbin/useradd";
+ char *argv[3];
+ argv[0] = command;
+ argv[1] = subu_username;
+ argv[2] = (char *) NULL;
+ char *envp[1];
+ envp[0] = (char *) NULL;
+ int dispatch_err = dispatch_exec(argv, envp);
+ if( dispatch_err != 0 ){
+ #ifdef DEBUG
+ dispatch_f_mess("dispatch_exec", dispatch_err, command);
+ #endif
+ // go back and remove the directory we made in subuland
+ int dispatch_err_rmdir = dispatch_f_euid_egid
+ (
+ "masteru_rmdir_subuhome",
+ masteru_rmdir_subuhome,
+ (void *)subuhome,
+ masteru_uid,
+ masteru_gid
+ );
+ #ifdef DEBUG
+ dispatch_f_mess("dispatch_f_euid_egid", dispatch_err_rmdir, "masteru_rmdir_subuhome");
+ #endif
+ if(mess)*mess = useradd_mess(dispatch_err);
+ RETURN(&resources, SUBU_ERR_FAILED_USERADD);
+ }
+ #ifdef DEBUG
+ debug_printf("added user \"%s\"\n", subu_username);
+ #endif
+ }
+
+ //--------------------------------------------------------------------------------
+ #ifdef DEBUG
+ debug_printf("setting the masteru_name, subuname, subu_username relation\n");
+ #endif
+ {
+ int rc = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username);
+ if( rc != SQLITE_OK ){
+ if(mess)*mess = strdup("insert of masteru subu relation failed");
+ RETURN(&resources, SUBU_ERR_DB_FILE);
+ }
+ }
+ #ifdef DEBUG
+ debug_printf("finished subu-mk-0(%s)\n", subuname);
+ #endif
+ RETURN(&resources, 0);
+}
+
+//================================================================================
+#tranche subu.lib.h
+ int subu_rm_0(char **mess, sqlite3 *db, char *subuname);
+#tranche-end
+int subu_rm_0(char **mess, sqlite3 *db, char *subuname){
+
+ int rc;
+ if(mess)*mess = 0;
+ Da resources;
+ da_alloc(&resources, sizeof(char *));
+
+ //--------------------------------------------------------------------------------
+ size_t subuname_len;
+ rc = allowed_subuname(mess, subuname, &subuname_len);
+ if(rc) return rc;
+ #ifdef DEBUG
+ debug_printf("subuname is well formed\n");
+ #endif
+
+ //--------------------------------------------------------------------------------
+ uid_t masteru_uid;
+ gid_t masteru_gid;
+ uid_t set_euid;
+ gid_t set_egid;
+ {
+ masteru_uid = getuid();
+ masteru_gid = getgid();
+ set_euid = geteuid();
+ set_egid = getegid();
+ #ifdef DEBUG
+ debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid);
+ #endif
+ if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT;
+ }
+
+ //--------------------------------------------------------------------------------
+ // various strings that we will need
+ char *masteru_name = 0;
+ char *masteru_home = 0;
+ char *subuland = 0;
+ char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir
+ da_push(&resources, masteru_name);
+ da_push(&resources, masteru_home);
+ da_push(&resources, subuland);
+ da_push(&resources, subuhome);
+ rc =
+ uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
+ ||
+ mk_subuland(masteru_home, &subuland)
+ ||
+ mk_subuhome(subuland, subuname, &subuhome)
+ ;
+ if(rc) RETURN(&resources, rc);
+ #ifdef DEBUG
+ debug_printf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome);
+ #endif
+
+ //--------------------------------------------------------------------------------
+ // removal from db
+ char *subu_username = 0;
+ da_push(&resources, subu_username);
+
+ db_begin(db);
+
+ rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
+ if( rc != SQLITE_OK ){
+ if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file");
+ rc = SUBU_ERR_SUBU_NOT_FOUND;
+ db_rollback(db);
+ RETURN(&resources, rc);
+ }
+ #ifdef DEBUG
+ printf("subu_username: \"%s\"\n", subu_username);
+ #endif
+
+ rc = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username);
+ if( rc != SQLITE_OK ){
+ if(mess)*mess = strdup("removal of masteru subu relation failed");
+ db_rollback(db);
+ RETURN(&resources, SUBU_ERR_DB_FILE);
+ }
+ #ifdef DEBUG
+ debug_printf("removed the masteru_name, subuname, subu_username relation\n");
+ #endif
+
+ rc = db_commit(db);
+ if( rc != SQLITE_OK ){
+ if(mess)*mess = strdup("removal of masteru subu relation in unknown state, exiting");
+ RETURN(&resources, SUBU_ERR_DB_FILE);
+ }
+
+ // even after removing the last masteru subu relation, we still do not remove
+ // the max subu count. Hence, a masteru will keep such for a life time.
+
+
+ //--------------------------------------------------------------------------------
+ // Only masteru can remove directories from masteru/subuland, so we switch to
+ // masteru's uid to perform the rmdir.
+ //
+ {
+ #ifdef DEBUG
+ debug_printf("as masteru, removing the directory \"%s\"\n", subuhome);
+ #endif
+ int dispatch_err = dispatch_f_euid_egid
+ (
+ "masteru_rmdir_subuhome",
+ masteru_rmdir_subuhome,
+ (void *)subuhome,
+ masteru_uid,
+ masteru_gid
+ );
+ if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_RMDIR_SUBUHOME ){
+ #ifdef DEBUG
+ dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_rmdir_subuhome");
+ #endif
+ if(mess)*mess = strdup(subuhome);
+ RETURN(&resources, SUBU_ERR_RMDIR_SUBUHOME);
+ }
+ }
+
+ //--------------------------------------------------------------------------------
+ // Delete the subservient user account
+ {
+ #ifdef DEBUG
+ debug_printf("deleting user \"%s\"\n", subu_username);
+ #endif
+ #if BUG_SSS_CACHE_RUID
+ #ifdef DEBUG
+ debug_printf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n");
+ #endif
+ if( setuid(0) == -1 ){
+ RETURN(&resources, SUBU_ERR_BUG_SSS);
+ }
+ #endif
+ char *command = "/usr/sbin/userdel";
+ char *argv[4];
+ argv[0] = command;
+ argv[1] = subu_username;
+ argv[2] = "-r";
+ argv[3] = (char *) NULL;
+ char *envp[1];
+ envp[0] = (char *) NULL;
+ int dispatch_err = dispatch_exec(argv, envp);
+ if( dispatch_err != 0 ){
+ #ifdef DEBUG
+ dispatch_f_mess("dispatch_exec", dispatch_err, command);
+ #endif
+ if(mess)*mess = userdel_mess(dispatch_err);
+ RETURN(&resources, SUBU_ERR_FAILED_USERDEL);
+ }
+ #ifdef DEBUG
+ debug_printf("deleted user \"%s\"\n", subu_username);
+ #endif
+ }
+
+ #ifdef DEBUG
+ debug_printf("finished subu-rm-0(%s)\n", subuname);
+ #endif
+ RETURN(&resources, 0);
+}
+
+//================================================================================
+// identifies masteru, the bindfs maps each subu_user's home to its mount point
+// in subuland.
+#tranche subu.lib.h
+ int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome);
+#tranche-end
+int subu_bind(char **mess, char *masteru_name, char *subu_username, char *subuhome){
+
+ int rc;
+ if(mess)*mess = 0;
+ Da resources;
+ da_alloc(&resources, sizeof(char *));
+
+ // lookup the subu_user_home
+ char *subu_user_home = 0;
+ da_push(&resources, subu_user_home);
+
+ rc = username_to_home(subu_username, &subu_user_home);
+ if( rc ){
+ if(mess) *mess = strdup("in subu_bind, subu user home directory lookup in /etc/passwd failed.");
+ RETURN(&resources, rc);
+ }
+
+ size_t len = 0;
+ char *map = 0;
+ da_push(&resources, map);
+
+ FILE* map_stream = open_memstream(&map, &len);
+ fprintf(map_stream, "--map=%s/%s:@%s/@%s", subu_username, masteru_name, subu_username, masteru_name);
+ fclose(map_stream);
+
+ char *command = "/usr/bin/bindfs";
+ char *argv[5];
+ argv[0] = command;
+ argv[1] = map;
+ argv[2] = subu_user_home;
+ argv[3] = subuhome;
+ argv[4] = (char *) NULL;
+ char *envp[1];
+ envp[0] = (char *) NULL;
+ int dispatch_err = dispatch_exec(argv, envp);
+ if( dispatch_err != 0 ){
+ #ifdef DEBUG
+ dispatch_f_mess(command, dispatch_err, "dispatch_exec");
+ #endif
+ if(mess)*mess = strdup("bind failed");
+ RETURN(&resources, SUBU_ERR_BIND);
+ }
+ #ifdef DEBUG
+ debug_printf("mapped \"%s\" as \"%s\"\n", subu_user_home, subuhome);
+ #endif
+ RETURN(&resources, 0);
+}
+
+#tranche subu.lib.h
+ int subu_bind_all(char **mess, sqlite3 *db);
+#tranche-end
+int subu_bind_all(char **mess, sqlite3 *db){
+
+ int rc;
+ if(mess)*mess = 0;
+ Da resources;
+ da_alloc(&resources, sizeof(char *));
+
+ //--------------------------------------------------------------------------------
+ uid_t masteru_uid;
+ gid_t masteru_gid;
+ uid_t set_euid;
+ gid_t set_egid;
+ {
+ masteru_uid = getuid();
+ masteru_gid = getgid();
+ set_euid = geteuid();
+ set_egid = getegid();
+ #ifdef DEBUG
+ debug_printf("masteru_uid %u, masteru_gid %u, set_euid %u set_egid %u\n", masteru_uid, masteru_gid, set_euid, set_egid);
+ #endif
+ if( masteru_uid == 0 || set_euid != 0 ) return SUBU_ERR_SETUID_ROOT;
+ }
+
+ //--------------------------------------------------------------------------------
+ // various strings that we will need
+ char *masteru_name = 0;
+ char *masteru_home = 0;
+ char *subuland = 0;
+ da_push(&resources, masteru_name);
+ da_push(&resources, masteru_home);
+ da_push(&resources, subuland);
+ rc =
+ uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
+ ||
+ mk_subuland(masteru_home, &subuland)
+ ;
+ if(rc) RETURN(&resources, rc);
+ #ifdef DEBUG
+ if(masteru_name)
+ debug_printf("masteru_name: \"%s\"", masteru_name);
+ else
+ debug_printf("masteru_name unknown");
+ if(subuland)
+ debug_printf("subuland: \"%s\"", subuland);
+ else
+ debug_printf("subuland unknown");
+ debug_printf("\n");
+ #endif
+
+ //--------------------------------------------------------------------------------
+ Da subus;
+ Da *subusp = &subus;
+ da_alloc(subusp, sizeof(subudb_subu_element));
+ rc = subudb_Masteru_Subu_get_subus(db, masteru_name, subusp);
+ if( rc != SQLITE_OK ){
+ if(mess)*mess = strdup("db access failed when fetching a list of subus");
+ return rc;
+ }
+ // a limitation of our error reporting approach is that we can only
+ // return one error, but here is a loop that might generate many
+ rc = 0;
+ char *subuhome = 0; // the name of the directory to put in subuland, not subu_user home dir
+ uint err_cnt = 0;
+ subudb_subu_element *pt = (subudb_subu_element *)(subusp->base);
+ while( !da_endq(subusp,pt) ){
+ rc = mk_subuhome(subuland, pt->subuname, &subuhome);
+ #ifdef DEBUG
+ if(subuhome)
+ debug_printf("subuhome: \"%s\"\n", subuhome);
+ else
+ debug_printf("subuhome unknown \n");
+ #endif
+ if(!rc) rc = subu_bind(NULL, masteru_name, pt->subu_username, subuhome);
+ if(rc) err_cnt++;
+ free(subuhome);
+ subuhome=0;
+ pt++;
+ }
+ if(err_cnt==1){
+ RETURN(&resources, rc);
+ }
+ if(err_cnt > 1){
+ *mess = strdup("multiple errors occured while binding subus");
+ RETURN(&resources, SUBU_ERR_BIND);
+ }
+ RETURN(&resources, 0);
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb-init.trc.c b/user/module/subu-0/trc/subudb-init.trc.c
new file mode 100644
index 0000000..69bc2a7
--- /dev/null
+++ b/user/module/subu-0/trc/subudb-init.trc.c
@@ -0,0 +1,30 @@
+#tranche subudb-init.cli.c
+/*
+This command initializes the db file.
+
+*/
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+int main(){
+ sqlite3 *db;
+ if( sqlite3_open(DB_File, &db) != SQLITE_OK ){
+ fprintf(stderr, "error exit, could not open db file \"%s\"\n", DB_File);
+ return SUBU_ERR_DB_FILE;
+ }
+ db_begin(db);
+ if( subudb_schema(db) != SQLITE_OK ){
+ db_rollback(db);
+ fprintf(stderr, "error exit, opened db file but could not build schema\n");
+ return SUBU_ERR_DB_FILE;
+ }
+ db_commit(db);
+ if( sqlite3_close(db) != SQLITE_OK ){
+ fprintf(stderr, "error exit, could not close the db\n");
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb-number.trc.c b/user/module/subu-0/trc/subudb-number.trc.c
new file mode 100644
index 0000000..7844b47
--- /dev/null
+++ b/user/module/subu-0/trc/subudb-number.trc.c
@@ -0,0 +1,67 @@
+#tranche subudb-number.cli.c
+/*
+Set or get a new maximum subu number. Currently doesn't do the setting part.
+
+*/
+#include
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+
+ if( argc < 1 || argc > 2){
+ fprintf(stderr, "usage: %s [n]\n",argv[0]);
+ return SUBU_ERR_ARG_CNT;
+ }
+
+ int rc;
+ sqlite3 *db;
+ rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "error exit, could not open db file\n");
+ sqlite3_close(db);
+ return SUBU_ERR_DB_FILE;
+ }
+
+ // then arg[1] holds a number to set the max to
+ if(argc == 2){
+ long int i = strtol(argv[1], NULL, 10);
+ if( i < 0 ){
+ fprintf(stderr, "n must be positive\n");
+ sqlite3_close(db);
+ return SUBU_ERR_N;
+ }
+ if( i > INT_MAX ){
+ fprintf(stderr, "n is too big, max supported by this program is %d\n", INT_MAX);
+ sqlite3_close(db);
+ return SUBU_ERR_N;
+ }
+ rc = subudb_number_set(db, i);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "couldn't set Max_Subunumber: %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_N;
+ }
+ }
+
+ // read and print the current max
+ int n;
+ rc = subudb_number_get(db, &n);
+ if( rc == SQLITE_OK ){
+ printf("%d\n", n);
+ }else{
+ fprintf(stderr, "couldn't get Max_Subunumber: %s\n", sqlite3_errmsg(db));
+ sqlite3_close(db);
+ return SUBU_ERR_DB_FILE;
+ }
+ rc = sqlite3_close(db);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb-rel-get.trc.c b/user/module/subu-0/trc/subudb-rel-get.trc.c
new file mode 100644
index 0000000..b1f87e3
--- /dev/null
+++ b/user/module/subu-0/trc/subudb-rel-get.trc.c
@@ -0,0 +1,46 @@
+#tranche subudb-rel-get.cli.c
+/*
+get the username from the db file
+for testing subudb_Masteru_Subu_get_subu_username
+
+*/
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+
+ if(argc != 3){
+ fprintf(stderr, "usage: %s masteru_name subuname\n", argv[0]);
+ return SUBU_ERR_ARG_CNT;
+ }
+
+ int rc;
+ sqlite3 *db;
+ rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
+ return SUBU_ERR_DB_FILE;
+ }
+
+ char *masteru_name = argv[1];
+ char *subuname = argv[2];
+ char *subu_username;
+
+ int ret = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
+ if( ret != SQLITE_DONE ){
+ fprintf(stderr, "subudb_Masteru_Subu_get_subu_username indicates failure by returning %d\n",ret);
+ fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ ret = sqlite3_close(db);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret);
+ fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb-rel-put.trc.c b/user/module/subu-0/trc/subudb-rel-put.trc.c
new file mode 100644
index 0000000..86d8beb
--- /dev/null
+++ b/user/module/subu-0/trc/subudb-rel-put.trc.c
@@ -0,0 +1,44 @@
+#tranche subudb-rel-put.cli.c
+/*
+puts a relation in the masteru/subu table
+
+*/
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+
+ if(argc != 4){
+ fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]);
+ return 1;
+ }
+ char *masteru_name = argv[1];
+ char *subuname = argv[2];
+ char *subu_username = argv[3];
+
+ sqlite3 *db;
+ {
+ int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
+ return SUBU_ERR_DB_FILE;
+ }}
+
+ int ret = subudb_Masteru_Subu_put(db, masteru_name, subuname, subu_username);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "subudb_Masteru_Subu_put indicates failure by returning %d\n",ret);
+ fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ ret = sqlite3_close(db);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret);
+ fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb-rel-rm.trc.c b/user/module/subu-0/trc/subudb-rel-rm.trc.c
new file mode 100644
index 0000000..88bd70a
--- /dev/null
+++ b/user/module/subu-0/trc/subudb-rel-rm.trc.c
@@ -0,0 +1,45 @@
+#tranche subudb-rel-rm.cli.c
+/*
+puts a relation in the masteru/subu table
+
+*/
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+
+ if(argc != 4){
+ fprintf(stderr, "expected: %s masteru_name subuname subu_username\n", argv[0]);
+ return 1;
+ }
+ char *masteru_name = argv[1];
+ char *subuname = argv[2];
+ char *subu_username = argv[3];
+
+ sqlite3 *db;
+ {
+ int ret = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "could not open db file \"%s\"\n", DB_File);
+ return SUBU_ERR_DB_FILE;
+ }}
+
+ int ret = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username);
+ if( ret != SQLITE_DONE ){
+ fprintf(stderr, "subudb_Masteru_Subu_rm indicates failure by returning %d\n",ret);
+ fprintf(stderr, "sqlite3 issues message, %s\n", sqlite3_errmsg(db));
+ printf("put failed\n");
+ return 2;
+ }
+ ret = sqlite3_close(db);
+ if( ret != SQLITE_OK ){
+ fprintf(stderr, "sqlite3_close(db) indicates failure by returning %d\n",ret);
+ fprintf(stderr, "sqlite3 issues message: %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb-subus.trc.c b/user/module/subu-0/trc/subudb-subus.trc.c
new file mode 100644
index 0000000..500f641
--- /dev/null
+++ b/user/module/subu-0/trc/subudb-subus.trc.c
@@ -0,0 +1,53 @@
+#tranche subudb-subus.cli.c
+/*
+Set or get a new maximum subu number. Currently doesn't do the setting part.
+
+*/
+#include
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+#include "subu.lib.h"
+
+int main(int argc, char **argv){
+
+ if( argc != 2){
+ fprintf(stderr, "usage: %s masteru_name\n",argv[0]);
+ return SUBU_ERR_ARG_CNT;
+ }
+ char *masteru_name = argv[1];
+
+ int rc;
+ sqlite3 *db;
+ rc = sqlite3_open_v2(DB_File, &db, SQLITE_OPEN_READWRITE, NULL);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "error exit, could not open db file\n");
+ sqlite3_close(db);
+ return SUBU_ERR_DB_FILE;
+ }
+
+ Da subu_arr;
+ Da *subu_arrp = &subu_arr;
+ rc = subudb_Masteru_Subu_get_subus(db, masteru_name, subu_arrp);
+ if( rc == SQLITE_OK ){
+ char *pt = subu_arrp->base;
+ subudb_subu_element *pt1;
+ while( pt < subu_arrp->end ){
+ pt1 = (subudb_subu_element *)pt;
+ printf("%s %s\n", pt1->subuname, pt1->subu_username);
+ pt += subu_arrp->element_size;
+ }
+ rc = sqlite3_close(db);
+ if( rc != SQLITE_OK ){
+ fprintf(stderr, "when closing db, %s\n", sqlite3_errmsg(db));
+ return SUBU_ERR_DB_FILE;
+ }
+ return 0;
+ }
+ fprintf(stderr, "lookup failed %s\n", sqlite3_errmsg(db));
+ sqlite3_close(db);
+ return SUBU_ERR_DB_FILE;
+
+}
+#tranche-end
diff --git a/user/module/subu-0/trc/subudb.trc.c b/user/module/subu-0/trc/subudb.trc.c
new file mode 100644
index 0000000..c6fb603
--- /dev/null
+++ b/user/module/subu-0/trc/subudb.trc.c
@@ -0,0 +1,202 @@
+#tranche subudb.lib.c
+#tranche subudb.lib.h
+ /*
+ The db file is maintained in SQLite
+
+ Because linux user names are limited length, subu user names are of a compact
+ form: _s. A separate table translates the numbers into the subu names.
+
+ Each of these returns SQLITE_OK upon success
+ */
+ #include
+ #include
+#tranche-end
+
+#include
+#include
+#include
+#include
+#include
+#include "common.lib.h"
+#include "subudb.lib.h"
+
+//--------------------------------------------------------------------------------
+// sqlite transactions don't nest. There is a way to use save points, but still
+// we can't just nest transactions. Instead use these wrappers around the whole
+// of something that needs to be in a transaction.
+#tranche subudb.lib.h
+ int db_begin(sqlite3 *db);
+ int db_commit(sqlite3 *db);
+ int db_rollback(sqlite3 *db);
+#tranche-end
+int db_begin(sqlite3 *db){
+ return sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, NULL, NULL);
+}
+int db_commit(sqlite3 *db){
+ return sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
+}
+int db_rollback(sqlite3 *db){
+ return sqlite3_exec(db, "ROLLBACK;", NULL, NULL, NULL);
+}
+
+//--------------------------------------------------------------------------------
+#tranche subudb.lib.h
+ int subudb_schema(sqlite3 *db);
+#tranche-end
+int subudb_schema(sqlite3 *db){
+ int rc;
+
+ { // build tables
+ char sql[] =
+ "CREATE TABLE Masteru_Subu(masteru_name TEXT, subuname TEXT, subu_username TEXT);"
+ "CREATE TABLE Attribute_Int(attribute TEXT, value INT);"
+ ;
+ rc = sqlite3_exec(db, sql, NULL, NULL, NULL);
+ if(rc != SQLITE_OK) return rc;
+ }
+
+ { // data initialization
+ char *sql = "INSERT INTO Attribute_Int (attribute, value) VALUES ('Max_Subunumber', ?1);";
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ sqlite3_bind_int(stmt, 1, First_Max_Subunumber);
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ if( rc != SQLITE_DONE ) return rc;
+ }
+
+ return SQLITE_OK;
+}
+
+//--------------------------------------------------------------------------------
+#tranche subudb.lib.h
+ int subudb_number_get(sqlite3 *db, int *n);
+#tranche-end
+int subudb_number_get(sqlite3 *db, int *n){
+ char *sql = "SELECT value FROM Attribute_Int WHERE attribute = 'Max_Subunumber';";
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ int rc = sqlite3_step(stmt);
+ if( rc == SQLITE_ROW ){
+ *n = sqlite3_column_int(stmt,0);
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ if( rc != SQLITE_DONE ) return rc;
+ return SQLITE_OK;
+ }
+ // should have a message return, suppose
+ sqlite3_finalize(stmt);
+ return SQLITE_NOTFOUND;
+}
+
+#tranche subudb.lib.h
+ int subudb_number_set(sqlite3 *db, int n);
+#tranche-end
+int subudb_number_set(sqlite3 *db, int n){
+ int rc;
+ char *sql = "UPDATE Attribute_Int SET value = ?1 WHERE attribute = 'Max_Subunumber';";
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ sqlite3_bind_int(stmt, 1, n);
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ if( rc == SQLITE_DONE ) return SQLITE_OK;
+ return rc;
+}
+
+//--------------------------------------------------------------------------------
+// put relation into Masteru_Subu table
+#tranche subudb.lib.h
+ int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
+#tranche-end
+int subudb_Masteru_Subu_put(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){
+ char *sql = "INSERT INTO Masteru_Subu VALUES (?1, ?2, ?3);";
+ sqlite3_stmt *stmt;
+ sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
+ sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC);
+ sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC);
+ sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC);
+ int rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ if( rc == SQLITE_DONE ) return SQLITE_OK;
+ return rc;
+}
+
+//--------------------------------------------------------------------------------
+#tranche subudb.lib.h
+ int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username);
+#tranche-end
+int subudb_Masteru_Subu_get_subu_username(sqlite3 *db, char *masteru_name, char *subuname, char **subu_username){
+ char *sql = "SELECT subu_username FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2;";
+ size_t sql_len = strlen(sql);
+ sqlite3_stmt *stmt;
+ int rc;
+ rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
+ if( rc != SQLITE_OK ) return rc;
+ sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC);
+ sqlite3_bind_text(stmt, 2, subuname, strlen(subuname), SQLITE_STATIC);
+ rc = sqlite3_step(stmt);
+ if( rc == SQLITE_ROW ){
+ const char *username = sqlite3_column_text(stmt, 0);
+ *subu_username = strdup(username);
+ }else{
+ sqlite3_finalize(stmt);
+ return rc; // woops this needs to return an error!, be sure it is not SQLITE_DONE
+ }
+ rc = sqlite3_step(stmt);
+ if( rc == SQLITE_DONE ) return SQLITE_OK;
+ return rc;
+}
+
+//--------------------------------------------------------------------------------
+#tranche subudb.lib.h
+ typedef struct{
+ char *subuname; // the name that masteru chose for his or her subu
+ char *subu_username; // the adduser name we gave it, typically of the s
+ } subudb_subu_element;
+ int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subus);
+#tranche-end
+//returns an array of subudb_subu_elements that correspond to the masteru_name
+int subudb_Masteru_Subu_get_subus(sqlite3 *db, char *masteru_name, Da *subusp){
+ char *sql = "SELECT subuname, subu_username"
+ " FROM Masteru_Subu"
+ " WHERE masteru_name = ?1;";
+ size_t sql_len = strlen(sql);
+ sqlite3_stmt *stmt;
+ int rc;
+ rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
+ if( rc != SQLITE_OK ) return rc;
+ sqlite3_bind_text(stmt, 1, masteru_name, strlen(masteru_name), SQLITE_STATIC);
+
+ subudb_subu_element *pt;
+ rc = sqlite3_step(stmt);
+ while( rc == SQLITE_ROW ){
+ pt = (subudb_subu_element *)da_push_alloc(subusp);
+ pt->subuname = strdup(sqlite3_column_text(stmt, 0));
+ pt->subu_username = strdup(sqlite3_column_text(stmt, 1));
+ rc = sqlite3_step(stmt);
+ }
+ sqlite3_finalize(stmt);
+ if( rc != SQLITE_DONE ) return rc;
+ return SQLITE_OK;
+}
+
+//--------------------------------------------------------------------------------
+#tranche subudb.lib.h
+ int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username);
+#tranche-end
+int subudb_Masteru_Subu_rm(sqlite3 *db, char *masteru_name, char *subuname, char *subu_username){
+ char *sql = "DELETE FROM Masteru_Subu WHERE masteru_name = ?1 AND subuname = ?2 AND subu_username = ?3;";
+ size_t sql_len = strlen(sql);
+ sqlite3_stmt *stmt;
+ int rc;
+ rc = sqlite3_prepare_v2(db, sql, sql_len, &stmt, NULL);
+ if( rc != SQLITE_OK ) return rc;
+ sqlite3_bind_text(stmt, 1, masteru_name, -1, SQLITE_STATIC);
+ sqlite3_bind_text(stmt, 2, subuname, -1, SQLITE_STATIC);
+ sqlite3_bind_text(stmt, 3, subu_username, -1, SQLITE_STATIC);
+ rc = sqlite3_step(stmt);
+ sqlite3_finalize(stmt);
+ if( rc == SQLITE_DONE ) return SQLITE_OK;
+ return rc;
+}
diff --git a/user/module/subu-0/try/multiple-makefile-targets/makefile b/user/module/subu-0/try/multiple-makefile-targets/makefile
new file mode 100644
index 0000000..400ec02
--- /dev/null
+++ b/user/module/subu-0/try/multiple-makefile-targets/makefile
@@ -0,0 +1,11 @@
+
+
+a b c:
+ echo $@
+
+x y z:
+ echo $@
+
+e f g: x y z
+ echo $^
+
diff --git a/user/module/subu-0/try/voidptr.c b/user/module/subu-0/try/voidptr.c
new file mode 100644
index 0000000..383e9e3
--- /dev/null
+++ b/user/module/subu-0/try/voidptr.c
@@ -0,0 +1,48 @@
+/*
+They say a cast is not required passing a typed pointer to a void * argument,
+but What about void **? .. oop then it matters.
+
+gcc -std=gnu11 -o voidptr voidptr.c
+voidptr.c: In function âmainâ:
+voidptr.c:28:5: warning: passing argument 1 of âgâ from incompatible pointer type [-Wincompatible-pointer-types]
+ g(&pt, y);
+ ^~~
+voidptr.c:13:15: note: expected âvoid **â but argument is of type âint **â
+ void g(void **pt0, void *pt1){
+ ~~~~~~~^~~
+
+*/
+#include
+
+int f(void *pt){
+ return *(int *)pt;
+}
+
+/* fails
+void g(void **pt0, int *pt1){
+ *pt0 = pt1;
+}
+*/
+
+// passes
+void g(void *pt0, int *pt1){
+ *(int **)pt0 = pt1;
+}
+
+int main(){
+ int x = 5;
+ int *xp = &x;
+ printf("%d\n",f(xp));
+
+ int y[3];
+ y[0] = 10;
+ y[1] = 11;
+ y[2] = 12;
+
+ int *pt;
+ g(&pt, y);
+ printf("%d\n",*pt);
+
+ printf("that's all folks\n");
+ return 0;
+}
diff --git a/user/module/subu-1/subu-mk.py b/user/module/subu-1/subu-mk.py
new file mode 100644
index 0000000..203fab4
--- /dev/null
+++ b/user/module/subu-1/subu-mk.py
@@ -0,0 +1,299 @@
+#!/usr/bin/python
+# see the help option for syntax
+# this script must be run from root or sudo
+#
+# on Fedora 29 os.getresuid returned all zeros for a script run from sudo.
+# Hence, I am using the environment variable SUDO_USER
+
+import getpass
+import os
+import sys
+import libuser
+from __future__ import print_function
+
+command = os.path.base(argv[0])
+
+#--------------------------------------------------------------------------------
+# utilities
+#
+def prn(str):
+ print(str,end='')
+
+#--------------------------------------------------------------------------------
+# help
+#
+def help():
+ print( command +
+""" [=help] [=version] [shell=][owner=] [subu=]
+Makes a subservient user.
+If no arguments are given, or if =help is given, this message is printed.
+When this command is invoked through sudo, $SUDO_USER is taken as the owner's username.
+Otherwise, when invoked directly from root, the owner= option must be provided.
+The subu-username argument is the username for the new subservient user
+The the new subu home directory is created in /home/owner/subu/.
+Facls are set to give the owner access to the new subu's home directory.
+The shell option is not implemented yet. Probably need a number of other options also.
+"""
+ )
+
+def version():
+ print(" version 0")
+
+#--------------------------------------------------------------------------------
+# a manager for handling error messages
+#
+class class_err:
+"""
+An error record has the form [flag, message, args]
+ class is fatal, warning, info [currently not implemented]
+ flag is true if an error has occured [need to change this to a count]
+ args is an array of strings to be given after the error message is printed.
+
+The dict holds named error records.
+
+register() is used to name and place error records in the dict. register() is
+typically called multiple times to initialize and error instance.
+
+tattle() is used by the program at run time in order to signal errors.
+
+has_error() returns true if tattle was ever called
+
+report() prints an error report. When errors have occured this
+
+vector() [unimplemented] returns a bit vector with one bit per fatal error
+record, in the order they appear in the dictionary. The bit is set if the error
+ever occured.
+
+We check for as many errors as is convenient to do so rather than stopping on
+the first error.
+"""
+
+ # field offsets into the error record
+ flag_dex = 0;
+ message_dex = 1;
+ args_dex = 2;
+
+ def __init__(self):
+ self.total_cnt = 0
+ self.dict = {}
+
+ def register(name, message):
+ self.dict[name] = [False, message, []]
+
+ def tattle(name, *args):
+ self.total_cnt += 1
+ if name in self.dict:
+ self.dict[name][0] = True
+ self.dict[name][2].extend(args)
+
+ def report():
+ if self.total_cnt:
+ for k,v in self.dict.items():
+ if v[self.flag_dex]:
+ print(v[self.message_dex],end='')
+ args = v[self.args_dex]
+ if length(args) :
+ print(args[0],end='')
+ for arg in args[1:]:
+ print( " " + arg, end='')
+ print()
+
+#--------------------------------------------------------------------------------
+# parse the command line
+#
+err.register(
+ 'impossible_split',
+ "It is not possible, yet this token split into other than one or two pieces: "
+ )
+err.register(
+ 'lone_delim',
+ "No spaces should appear around the '=' delimiter."
+ )
+
+args = sys.argv[1:]
+if len(args) == 0 :
+ version()
+ help()
+ exit(1)
+
+#create a dictionary based on the command line arguments
+arg_dict = {}
+subu_cnt = 0
+delim = '='
+for token in args:
+ token_pair = split(token, delim);
+ if len(token_pair) == 1 : #means there was no '=' in the token
+ arg_dict['subu'] = token_pair
+ subu_cnt++
+ elif len(token_pair) == 2 :
+ if token_pair[0] == '' and token_pair[1] == '' :
+ err.tattle('lone_delim')
+ elif token_pair[1] == '' : # then has trailing delim, will treat the same as a leading delim
+ arg_dict[token_pair[0]] = None
+ elif token_pair[0] == '' : # then has leading delim
+ arg_dict[token_pair[1]] = None
+ else:
+ arg_dict[token_pair[0]] = token_pair[1]
+ else:
+ err.tattle('impossible_split', token)
+
+if not arg_dict or arg_dict.get('help'):
+ help()
+ err.report()
+ exit(1)
+
+if arg_dict.get('version'):
+ version()
+
+#--------------------------------------------------------------------------------
+# check that the command line arguments are well formed.
+#
+err.register(
+ 'too_many_args',
+ command + " takes at most one non-option argument, but we counted: "
+ )
+err.register(
+ 'no_subu'
+ command + " missing subservient username."
+ )
+err.register(
+ 'bad_username'
+ "Usernames match ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$, but found: "
+ )
+err.register(
+ 'unknown_option'
+ command + " doesn't implement option: "
+ )
+
+subu = arg_dict.get('subu')
+if subu_cnt > 1:
+ err.tattle('too_many_args')
+elif not subu
+ err.tattle('no_subu')
+elif not re.match("^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$", subu)
+ err.tattle('bad_username', subu)
+
+for k in arg_dict:
+ if k not in ['help', 'version', 'shell', 'owner', 'subu'] :
+ err.tattle('unkown_option', k)
+
+if arg_dict.get('shell') :
+ print "shell option aint implemented yet"
+
+
+
+#--------------------------------------------------------------------------------
+# check that we have root privilege
+#
+err.register(
+ 'not_root'
+ command + "requires root privilege"
+ )
+
+uid = os.getuid()
+if uid != 0 :
+ err.tattle('not root')
+
+username = getpass.getuser()
+sudo_caller_username = os.environ.get('SUDO_USER')
+
+if !sudo_caller_username
+ if username not == "root":
+ err.tattle('not_root')
+ elif:
+ owner
+
+
+ def has_error(*errs):
+ return self.cnt > 0
+
+
+
+#-----
+
+
+
+
+#--------------------------------------------------------------------------------
+# pull out the owner_dir and subu_dir
+#
+admin= libuser.admin()
+
+err_arg_form = class_err()
+err_arg_form.register('too_many', "too many semicolon delineated parts in")
+
+owner_parts = args[0].split(":")
+subu_parts = args[1].split(":")
+
+owner_user_name = owner_parts[0]
+if not owner_user_name:
+ err_arg_form.tattle('owner_user_name_missing', args[0])
+else:
+ owner_user = admin.lookupUserByName(owner_user_name)
+ if owner_user == None:
+ err_arg_form.tattle('no_such_user_name', owner_user_name)
+ else:
+
+
+subu_user_name = subu_parts[0]
+
+
+if length(owner_parts) > 2:
+ err_arg_form.tattle('too_many', args[0])
+elif length(owner_parts) == 2:
+ owner_dir = owner_parts[1]
+else # get the home directory
+
+
+
+
+
+#--------------------------------------------------------------------------------
+# set the home directory
+#
+if len(args) > args_dir_index:
+ dir = args[args_dir_index]
+else:
+ dir = os.getcwd()
+
+home = dir + "/" + name
+home_flag = not os.path.exists(home)
+
+#--------------------------------------------------------------------------------
+# create the user, setfacls
+#
+err_cnt = 0
+name_available_flag = False
+
+if name_flag:
+ admin = libuser.admin()
+ name_available_flag = name not in admin.enumeratedUsers()
+
+if owner_flag and name_flag and name_available_flag and home_flag :
+ user = admin.initUser(name)
+ user[libuser.HOMEDIRECTORY] = home
+ if opt_shell : user[libuser.SHELL] = opt_shell
+ admin.addUser(user)
+ #setfacl -m d:u:plato:rwx,u:plato:rwx directory
+ setfacl = "setfacl -m d:u:" + name + ":rwx,u:" + name + ":rwx " + home
+ exit(0)
+
+#--------------------------------------------------------------------------------
+# error return
+# .. need to grab the return code from setfacl above and delete the user if it fails
+#
+err_flags = 0
+if not owner_flag :
+ err_flags |= 2**2
+ print "missing owning username argument"
+if not name_flag :
+ err_flags |= 2**3
+ print name + "missing subservient username argument"
+if not name_available_flag :
+ err_flags |= 2**4
+ print name + "specified subservient username already exists"
+if not home_flag :
+ err_flags |= 2**5
+ print "user home directory already exists"
+
+exit(err_flags)
diff --git a/user/module/tranche/deprecated/0_makefile b/user/module/tranche/deprecated/0_makefile
new file mode 100644
index 0000000..f0708ef
--- /dev/null
+++ b/user/module/tranche/deprecated/0_makefile
@@ -0,0 +1,40 @@
+# src/0_makefile
+
+SHELL=/bin/bash
+
+-include 0_makefile_flags
+
+SUID_TOOL=$(TOOLSDIR)/bin/setuid_root.sh
+MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tools/lib/makefile-cc
+
+SOURCES=$(wildcard *.c)
+HFILES=$(wildcard *.h)
+
+all: version deps lib execs
+
+version:
+ $(MAKE) $@
+ @echo "SUID_TOOL: " $(SUID_TOOL)
+
+deps:
+ makeheaders $(SOURCES) $(HFILES)
+ sed -i '/^ *int *main *(.*)/d' *.h
+ $(MAKE) $@
+
+execs:
+ $(MAKE) $@
+ @echo "-> $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all"
+ cat $(SUID_TOOL)
+ @echo -n "Are you sure? [y/N] " && read ans && [ $${ans:-N} == y ]
+ sudo $(SUID_TOOL) $(EXECSDIR)/subu-mk-0 $(EXECSDIR)/subu-rm-0 $(EXECSDIR)/subu-bind-all
+
+clean:
+ $(MAKE) $@
+ for i in $(HFILES); do rm $$i; done
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/tranche/deprecated/0_makefile-flags b/user/module/tranche/deprecated/0_makefile-flags
new file mode 100644
index 0000000..d4df01f
--- /dev/null
+++ b/user/module/tranche/deprecated/0_makefile-flags
@@ -0,0 +1,31 @@
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+# directories used by this makefile, these could all be set to dot for
+# the simplest source directory structure
+
+#LIDBIR, EXECSDIR, HDIR hold the make results that might later be shared
+#$(PWD) is the directory that make was called from, this is already build in
+#set to dot to use the same directory as the source code
+#leave blank to ommit
+DEPRDIR=1_deprecated
+DOCDIR=1_doc
+EXECSDIR=1_execs
+HDIR=1_headers
+LIBDIR=1_lib
+TESTDIR=1_tests
+TMPDIR=1_tmp
+TOOLSDIR=$(realpath $(PROJECT_SUBU)/tools)
+TRYDIR=1_try
+
+
+# compiler and flags
+CC=gcc
+CFLAGS=-std=gnu11 -fPIC -I. -ggdb -Werror -DDEBUG -DDEBUGDB
+#CFLAGS=-std=gnu11 -fPIC -I. -Werror
+LINKFLAGS=-L1_lib -lsubu -lsqlite3
+
+LIBFILE=$(LIBDIR)/libsubu.a
+
diff --git a/user/module/tranche/doc/todo.txt b/user/module/tranche/doc/todo.txt
new file mode 100644
index 0000000..1494e66
--- /dev/null
+++ b/user/module/tranche/doc/todo.txt
@@ -0,0 +1,11 @@
+
+2019-03-22T13:37:23Z
+1. indentation
+
+ the first non blank line after the #tranche keyword sets the indentation
+ level for the following text. When echoing to the output file
+ remove that many leading spaces.
+
+ Hmm, or allow options among the tranche parameters, -indent 3 or
+ -indent ' '.
+
diff --git a/user/module/tranche/makefile b/user/module/tranche/makefile
new file mode 100644
index 0000000..9f66b5c
--- /dev/null
+++ b/user/module/tranche/makefile
@@ -0,0 +1,39 @@
+# tranche/makefile
+
+SHELL=/bin/bash
+MAKE=/usr/bin/make --no-print-directory -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+#MAKE=/usr/bin/make -f $(PROJECT_SUBU)/tool/lib/makefile-cc
+
+-include makefile-flags
+
+.PHONY: all
+all: version
+
+.PHONY: dep
+dep:
+ if [ -e $(DEPFILE) ]; then rm $(DEPFILE); fi
+ $(MAKE) $@
+
+.PHONY: lib
+lib:
+ cp $(SRCDIR)/tranche.lib.h include/tranche.h
+ $(MAKE) $@
+
+.PHONY: exec
+exec:
+ $(MAKE) $@
+
+.PHONY: share
+share:
+ @echo "instead of share, the 'install' target will put the execs in tools/bin"
+
+.PHONY: install
+install:
+ if [ -d $(EXECDIR) ]; then if [ ! -z "$(wildcard $(EXECDIR)/*)" ]; then cp $(EXECDIR)/* $(PROJECT_SUBU)/tool/bin; fi; fi
+
+%::
+ $(MAKE) $@
+
+
+
+
diff --git a/user/module/tranche/makefile-flags b/user/module/tranche/makefile-flags
new file mode 100644
index 0000000..46febb1
--- /dev/null
+++ b/user/module/tranche/makefile-flags
@@ -0,0 +1,26 @@
+MODULE=tranche
+
+DEPRDIR=deprecated
+DOCDIR=doc
+EXECDIR=exec
+INCDIR=include
+LIBDIR=lib
+SHAREDIR=$(realpath $(PROJECT_SUBU)/module/share)
+SRCDIR=src
+TESTDIR=
+TMPDIR=tmp
+TOOLDIR=$(realpath $(PROJECT_SUBU)/tool)
+TRYDIR=try
+
+DEPFILE=$(TMPDIR)/makefile-cc.deps
+LIBFILE=$(LIBDIR)/lib$(MODULE).a
+INCFILE=$(INCDIR)/$(MODULE).h
+
+# some versions of Linux need a -e option others complain if there is a -e .. and it isn't the binary for echo ..
+ECHO= echo
+#ECHO= echo -e
+
+C=gcc
+CFLAGS=-std=gnu11 -fPIC -I$(SRCDIR) -I$(INCDIR) -I$(SHAREDIR)/include -ggdb -Werror -DDEBUG -DDEBUGDB
+LINKFLAGS=-L$(LIBDIR) -L$(SHAREDIR)/lib/ -l$(MODULE) -lda
+
diff --git a/user/module/tranche/src/tranche-make.cli.c b/user/module/tranche/src/tranche-make.cli.c
new file mode 100644
index 0000000..bfe9d9b
--- /dev/null
+++ b/user/module/tranche/src/tranche-make.cli.c
@@ -0,0 +1,154 @@
+/*
+
+usage:
+ argv[0] [] [-sname ] [-tdir ] [-mfile ]
+
+gets the names of all the targets from the source file, then appends
+to the mfile a couple of lines of the form:
+
+... :
+ tranche $@
+
+Our makefile is typically run in the directory above where the sources are
+located.
+
+options
+ the trc file to be read
+-tdir prepend / to each "
+-mfile where to send the output, defaults to stdout
+-sname replaces sourcename as the name to write as the source - useful for pipes
+
+If is not provided stdin is used.
+If -mfile is not provided, stdout is used.
+If -sdir is not provided, the directory part of the is used. If the
+user does not want this behavior, give a value of "." for -sdir.
+
+.. should modify this to allow multiple source files on the command line ..
+.. should check that tdir is an existing directory
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "tranche.lib.h"
+
+int main(int argc, char **argv, char **envp){
+
+ int err = 0;
+ char *sname = 0;
+ char *tdir = 0;
+ char *mfile_path = 0;
+ Da args; // we will queue the non option args here
+ Da *argsp = &args; // collection of the non-option non-option-value args
+ da_alloc(argsp, sizeof(char *));
+ { // argument parse
+ char **pt = argv + 1; // skip the command name
+ char *option;
+ char *value; // currently all our tranche options have exactly one value
+ while(*pt){
+ if( **pt == '-' ){
+ option = *pt + 1;
+
+ // options that take no values:
+ if(!*option){
+ fprintf(stderr, "Currently there is no lone '-' option.\n");
+ err |= TRANCHE_ERR_ARG_PARSE;
+ goto endif;
+ }
+ if( !strcmp(option, "h") || !strcmp(option, "help") ){
+ err |= TRANCHE_ERR_HELP; // this will force the usage message, though it will also return an error
+ goto endif;
+ }
+
+ // options that take one value:
+ pt++; if(!*pt || **pt == '-'){
+ fprintf(stderr, "Missing value for option %s.\n", option);
+ err |= TRANCHE_ERR_ARG_PARSE;
+ if(!*pt) break; // then nothing more to parse
+ goto endif;
+ }
+ value = *pt;
+ if( !strcmp(option, "mfile") ){
+ mfile_path = value;
+ goto endif;
+ }
+ if( !strcmp(option, "tdir") ){
+ tdir = value;
+ path_trim_slashes(tdir);
+ goto endif;
+ }
+ if( !strcmp(option, "sname") ){
+ sname = value;
+ goto endif;
+ }
+ fprintf(stderr, "Unrecognized option %s.", option);
+ err |= TRANCHE_ERR_ARG_PARSE;
+ goto endif;
+ }
+ // else clause
+ da_push(argsp, pt);
+ endif:
+ pt++;
+ }
+ if(da_emptyq(argsp) && !sname){
+ fprintf(stderr, "Must be given at least one source name argument or an sname option\n");
+ err |= TRANCHE_ERR_SNAME;
+ }
+ if(err){
+ fprintf(stderr, "usage: %s [].. [-sname ] [-tdir ]\n", argv[0]);
+ return err;
+ }
+ }// end of argument parse
+
+ // open the output file
+ int mfile_fd;
+ {
+ if(mfile_path)
+ mfile_fd = open(mfile_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
+ else
+ mfile_fd = STDOUT_FILENO;
+
+ if(mfile_fd == -1){
+ fprintf(stderr, "Could not open the dep file %s\n", mfile_path);
+ err |= TRANCHE_ERR_DST_OPEN;
+ }
+ }
+
+ // The arguments are source file paths, but we process each one only once.
+ Da src_arr;
+ Da *src_arrp = &src_arr;
+ da_alloc(src_arrp, sizeof(char *));
+ da_strings_set_union(src_arrp, argsp, NULL); // NULL destructor
+ da_free(argsp);
+
+ char *src_file_path;
+ FILE *src_file;
+ if(da_emptyq(src_arrp))
+ tranche_make(stdin, sname, mfile_fd, tdir);
+ else{
+ char *pt = src_arrp->base;
+ while( pt < src_arrp->end ){
+ src_file_path = *(char **)pt;
+ src_file = fopen(src_file_path, "r");
+ if(!src_file){
+ fprintf(stderr,"Could not open source file %s.\n", src_file_path);
+ err |= TRANCHE_ERR_SRC_OPEN;
+ }else{
+ tranche_make(src_file, src_file_path, mfile_fd, tdir);
+ if( fclose(src_file) == -1 ){perror(NULL); err |= TRANCHE_ERR_FCLOSE;}
+ }
+ pt += src_arrp->element_size;
+ }
+ }
+ da_free(src_arrp);
+
+ if(mfile_fd != STDOUT_FILENO && close(mfile_fd) == -1 ){
+ perror(NULL);
+ err |= TRANCHE_ERR_FCLOSE;
+ }
+ return err;
+}
diff --git a/user/module/tranche/src/tranche-target.cli.c b/user/module/tranche/src/tranche-target.cli.c
new file mode 100644
index 0000000..52277b9
--- /dev/null
+++ b/user/module/tranche/src/tranche-target.cli.c
@@ -0,0 +1,117 @@
+/*
+Scans a tranche and lists the named target files.
+
+stdout is not explicitly named. Would be intersting if stdout
+were also listed if anything is sent to stdout. Might distinguish
+between blank lines being sent and text being sent to stdout.
+
+*/
+
+#include
+#include
+#include
+#include
+#include "tranche.lib.h"
+
+#define ERR_ARGC 1
+#define ERR_SRC_OPEN 2
+
+
+int main(int argc, char **argv, char **envp){
+
+ int err = 0;
+ char *sep = 0;
+ char *tdir = 0;
+ Da args; // we will queue the non option args here
+ Da *argsp = &args; // collection of the non-option non-option-value args
+ da_alloc(argsp, sizeof(char *));
+ { // argument parse
+ char **pt = argv + 1; // skip the command name
+ char *option;
+ char *value; // currently all our tranche options have exactly one value
+ while(*pt){
+ if( **pt == '-' ){
+ option = *pt + 1;
+
+ // options that take no values:
+ if(!*option){
+ fprintf(stderr, "Currently there is no lone '-' option.\n");
+ err |= TRANCHE_ERR_ARG_PARSE;
+ goto endif;
+ }
+ if( !strcmp(option, "h") || !strcmp(option, "help") ){
+ err |= TRANCHE_ERR_HELP; // this will force the usage message, though it will also return an error
+ goto endif;
+ }
+
+ // options that take one value:
+ pt++; if(!*pt || **pt == '-'){
+ fprintf(stderr, "Missing value for option %s.\n", option);
+ err |= TRANCHE_ERR_ARG_PARSE;
+ if(!*pt) break; // then nothing more to parse
+ goto endif;
+ }
+ value = *pt;
+ if( !strcmp(option, "sep") ){
+ sep = value;
+ goto endif;
+ }
+ if( !strcmp(option, "tdir") ){
+ tdir = value;
+ path_trim_slashes(tdir);
+ goto endif;
+ }
+ fprintf(stderr, "Unrecognized option %s.", option);
+ err |= TRANCHE_ERR_ARG_PARSE;
+ goto endif;
+ }
+ // else clause
+ da_push(argsp, pt);
+ endif:
+ pt++;
+ }
+ if(!sep)sep = "\n";
+ if(err){
+ fprintf(stderr, "usage: %s [].. [-sep ]\n", argv[0]);
+ return err;
+ }
+ }// end of argument parse
+
+ // The arguments are source file paths, but we process each one only once.
+ Da src_arr;
+ Da *src_arrp = &src_arr;
+ da_alloc(src_arrp, sizeof(char *));
+ da_strings_set_union(src_arrp, argsp, NULL); // NULL destructor
+ da_free(argsp);
+
+ // a list of unique targets
+ Da target_arr;
+ Da *target_arrp = &target_arr;
+ da_alloc(target_arrp, sizeof(char *));
+
+ uint err_cnt = 0;
+ char *src_file_path;
+ FILE *src_file;
+ if(da_emptyq(src_arrp))
+ tranche_target(stdin, target_arrp, tdir);
+ else{
+ char *pt = src_arrp->base;
+ while( pt < src_arrp->end ){
+ src_file_path = *(char **)pt;
+ src_file = fopen(src_file_path, "r");
+ if(!src_file){
+ fprintf(stderr,"Could not open source file %s.\n", src_file_path);
+ err |= TRANCHE_ERR_SRC_OPEN;
+ }else{
+ tranche_target(src_file, target_arrp, tdir);
+ if( fclose(src_file) == -1 ){perror(NULL); err |= TRANCHE_ERR_FCLOSE;}
+ }
+ pt += src_arrp->element_size;
+ }
+ }
+ da_free(src_arrp);
+ da_strings_print(target_arrp, sep);
+ da_free_elements(target_arrp);
+ da_free(target_arrp);
+ return err;
+}
diff --git a/user/module/tranche/src/tranche.cli.c b/user/module/tranche/src/tranche.cli.c
new file mode 100644
index 0000000..447a78b
--- /dev/null
+++ b/user/module/tranche/src/tranche.cli.c
@@ -0,0 +1,118 @@
+/*
+The purpose of this tools is to facilitate putting prototypes (declarations) next
+to implementations (definitions) in a single source file of a C/C++ programs.
+
+Sends code tranches from a single source file into one or more output files.
+Scans through the single source file looking for lines of the form:
+
+ #tranche-begin filename filename ...
+
+With the # as the first non-space character on the line, with one or more filenames
+following the tag. Upon finding such a line, copies all following lines into the
+listed files, until reaching the end marker:
+
+ #tranche-end
+
+Files are opened for create or append. Typically the user will want to delete
+the tranche output files before running tranche a second time.
+
+.. currently tranche_send will probably mess up if the user nests a tranche to
+the same file as one already open in the containing tranche ..
+
+*/
+
+#include