2019-12-26-Installing-thttpd.txt How much HTML do I have to know to set up a web page? NONE! The thttpd web server, without any HTML, can make a quick and dirty website which looks like a directory listing. The priority is FUNCTION and GLITZ can come later! If you get banned by Google, Facebook, YouTube or whoever, you can be back live in minutes! When a file is put into "public_html" it is live! These instructions may seem long with a lot of unnecessary text, but I want even a third or fourth grader who has never compiled a program to be able to go through the process without any trouble. If they do have trouble, with enough documentation to be able to see where they went wrong and be able to correct the problem. This project should be the beginning for a live stable website directly connected to the Internet, whether connected dynamically or statically, and as a basis for website design. The initial file for a web page is "index.html" although thttpd will recognize INDEX_NAMES: "index.html", "index.htm", "index.xhtml", "index.xht", "Default.htm", and "index.cgi", for initial web page file names. If no index file is found, thttpd will automatically generate its own index which results in a green screen and a directory listing. “Raspberry Pi Desktop (for PC and Mac)” could use some better documentation as far as what the choices do and how they effect an OS that is already installed on the proposed machine. My website, http://162.250.19.7/ is running on a Raspberry Pi 3B with a 1TB hard disk drive and no microSD card. These instructions are for the Raspberry Pi Desktop as well as the Raspberry Pi. If you have an old computer laying around that you aren't using, these instructions should work. I dug out a spare notebook I bought from Wal-Mart back at the end of 2009, an eMachine 250-1162 Notebook with Windows 7 Starter (32-bit), Intel Atom N270 32-bit processor, 10.1" LED LCD display (1024 x 600), 1GB memory, 10/100 (RJ-45) Ethernet port, 3 USB-2 ports, WLAN 802.11 b/g port, etc., still brand new in the box! After Windows loaded, I shrunk the Windows 7 partition as much as I could, and installed “Raspberry Pi Desktop” into the empty space, choosing separate /home and /swap partitions. Better directions for the “Desktop install” would really help! At this point, you have your computer setup, and up and running linux (Raspbian). In the folder /home/pi, make a folder (file: create folder) Acme.com and then click on the folder "Acme.com" (/home/pi/Acme.com, should now be shown). Open web browser - click on 3 vertical dots on right (Customize and Control Chromium), click "Settings" at the bottom of the list, click "advanced" and continue down the list to "Downloads" and move the button to the right (on) for "Ask where to save each file before downloading." Close Settings. On browser "new" tab enter: http://acme.com/ and then press enter. This brings up a green page labeled "ACME Laboratories." Right click in the green - "Save as ..." click, Name: ACME Laboratories.html, on "pi" "Downloads" click "pi" and then under Name, double click on "Acme.com" directory. Now you should see, Name: ACME Laboratories.html with "pi" "Acme.com" below - and a blank page with "Save" at the bottom right, Click "Save." Back on the green "Home" page, the third black bullet down (The ACME Labs freeware library.) click on "thttpd" - tiny/turbo/throttling web server. Right click on green - "Save as ..." click, Name: thttpd.html with "pi" "Acme.com" and at page bottom, click "Save." "thttpd - tiny/turbo/throttling HTTP server" page. Click "Fetch the software." Name: thttpd-2.29.tar.gz (this number could grow), with "pi" "Acme.com" - click "Save." The "Release notes" are lower down the page so we don't need to click and save them. Click "comparison chart" right click and "Save as ..." click, Name: Web Server Comparisons.html and click "Save." You will see the benchmarks were last updated 12jul98, over 21 years ago, and computers are much faster now! go back a page. The "(URL-traffic-based throttling)" is in thttpd man page.html. Click "HTMLized man page" right click and "Save as ..." click, Name: thttpd man page.html with "pi" "Acme.com" click "Save", go back one page. Click "thttpd notes", right click "Save as ..." click, Name: thttpd notes.html, with "pi" "Acme.com" click "Save", go back one page. Click "options guide", right click "Save as ..." click, Name: Configuration Options.html, with "pi" "Acme.com", click "Save", go back one page. Click "auxiliary programs", right click "Save as ..." click, Name: Auxiliary Programs.html, with "pi" "Acme.com", click "Save". We now want to save all 5 of these man pages. Click makeweb page highlight, right click "Save as ..." click, Name: makeweb man page.html, with "pi" Acme.com", click "Save", go back one page. Click htpasswd page highlight, right click, "Save as ...", click, Name: htpasswd man page.html, with "pi" "Acme.com", click "Save", go back one page. Click ssi page highlight, right click, "Save as ...", click, Name: ssi man page.html, with "pi" "Acme.com", click "Save", go back one page. Click redirect page highlight, right click, "Save as ...", click, Name: redirect man page.html, with "pi "Acme.com", click "Save", go back one page. Click syslogtocern page highlight, right click, "Save as ..." click, Name: syslogtocern man page.html, with "pi" "Acme.com", click "Save", go back one page. We have saved all 5 axillary program man pages so go back one more page. Click "other web resources", right click, "Save as ...", click, Name: Other Web Resources.html, with "pi" "Acme.com", click "Save", go back one page. That should cover most of what we need for thttpd, and can now quit the web browser. In File manager: Open /home/pi/Acme.com Right click on thttpd-2.29.tar.gz and click "Extract Here." You should now see a directory labeled "thttpd-2.29." Double click this directory to open it. Make it Full Page. Click on "INSTALL." These are the instructions we need to install thttpd. Since thttpd is a portable program, we will have to build it for our machine. Click the tab at the top of the page "thttpd-2.29" The first thing to do is read through the "config.h" file to get an idea what thttpd does and its controls, so double click on the file "config.h" (opening "config.h" in Geany). We need to make a change - at line 130, (a blank line), add 2 more blank lines by pressing enter. Highlight line 127, (#define TILDE_MAP_1 "users"), right click and select copy. Move to blank line #131, right click and select paste. Line 131 should now be the same as line 127. Under the "FILE" Tab select "SAVE". This is so we can use different "users" for our website with different passwords from "pi" for another layer of security. You might want to read through the "config.h" file to get an idea of what "thttpd" can do. The file "config.h" can now be closed. Open a "terminal" full screen. pi@raspberry:~ $ cd /etc pi@raspberry:/etc $ ls "dphys-swapfile" is the file we need to modify. On my Raspberry Pi 3B I was having trouble with the web browser locking up so I solved the problem by adding # to the line CONF_SWAPSIZE=100 removing the # on the line #CONF_SWAPFACTOR=2 so I would have maximum swap space available. "sudo nano," since this is a root file and add # to CONF_SWAPSIZE=100, remove # from #CONF_SWAPFACTOR=2 and then use "control o" to write the file and then "control x" to exit nano. There was no way to copy the file so I just did a cat on the file so one could see what needs to be changed. pi@raspberry:/etc $ sudo nano dphys-swapfile pi@raspberry:/etc $ cat dphys-swapfile # /etc/dphys-swapfile - user settings for dphys-swapfile package # author Neil Franklin, last modification 2010.05.05 # copyright ETH Zuerich Physics Departement # use under either modified/non-advertising BSD or GPL license # this file is sourced with . so full normal sh syntax applies # the default settings are added as commented out CONF_*=* lines # where we want the swapfile to be, this is the default #CONF_SWAPFILE=/var/swap # set size to absolute value, leaving empty (default) then uses computed value # you most likely don't want this, unless you have an special disk situation #CONF_SWAPSIZE=100 # set size to computed value, this times RAM size, dynamically adapts, # guarantees that there is enough swap without wasting disk space on excess CONF_SWAPFACTOR=2 # restrict size (computed and absolute!) to maximally this limit # can be set to empty for no limit, but beware of filled partitions! # this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it # but is also sensible on 64bit to prevent filling /var or even / partition #CONF_MAXSWAP=2048 pi@raspberry:/etc $ Above is what your file should look like after you save it. pi@raspberry:~ $ cd /etc pi@raspberry:/etc $ cat group (we are looking for a group "www") root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4:pi tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20:pi fax:x:21: voice:x:22: cdrom:x:24:pi floppy:x:25: tape:x:26: sudo:x:27:pi audio:x:29:pi dip:x:30: www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: gnats:x:41: shadow:x:42: utmp:x:43: video:x:44:pi sasl:x:45: plugdev:x:46:pi staff:x:50: games:x:60:pi users:x:100:pi nogroup:x:65534: systemd-journal:x:101: systemd-timesync:x:102: systemd-network:x:103: systemd-resolve:x:104: input:x:105:pi kvm:x:106: render:x:107: crontab:x:108: netdev:x:109:pi pi:x:1000: ntp:x:110: messagebus:x:111: ssh:x:112: avahi:x:113: spi:x:999:pi i2c:x:998:pi gpio:x:997:pi lightdm:x:114: bluetooth:x:115: avahi-autoipd:x:116: Debian-exim:x:117: uuidd:x:118: systemd-coredump:x:996: pi@raspberry:/etc $ Since there is no group "www" with the user "pi" we will need to add this, getting the directions by using "--help" to see our options. pi@raspberry:/etc $ addgroup --help adduser [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] [--add_extra_groups] USER Add a normal user adduser --system [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID] [--gecos GECOS] [--group | --ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] [--add_extra_groups] USER Add a system user adduser --group [--gid ID] GROUP addgroup [--gid ID] GROUP Add a user group addgroup --system [--gid ID] GROUP Add a system group adduser USER GROUP Add an existing user to an existing group general options: --quiet | -q don't give process information to stdout --force-badname allow usernames which do not match the NAME_REGEX configuration variable --help | -h usage message --version | -v version number and copyright --conf | -c FILE use FILE as configuration file pi@raspberry:/etc $ From this we get the commands we need to add a system group "www" and make "pi" a member of this group. pi@raspberry:/etc $ pi@raspberry:/etc $ addgroup --system [--gid ID] GROUP pi@raspberry:/etc $ Add a system group pi@raspberry:/etc $ pi@raspberry:/etc $ adduser USER GROUP pi@raspberry:/etc $ Add an existing user to an existing group We need to add a system group "www" and make "pi" a member of this group. pi@raspberry:/etc $ pi@raspberry:/etc $ sudo addgroup --system www Adding group `www' (GID 119) ... Done. pi@raspberry:/etc $ sudo adduser pi www Adding user `pi' to group `www' ... Adding user pi to group www Done. pi@raspberry:/etc $ cat group root:x:0: daemon:x:1: bin:x:2: sys:x:3: adm:x:4:pi tty:x:5: disk:x:6: lp:x:7: mail:x:8: news:x:9: uucp:x:10: man:x:12: proxy:x:13: kmem:x:15: dialout:x:20:pi fax:x:21: voice:x:22: cdrom:x:24:pi floppy:x:25: tape:x:26: sudo:x:27:pi audio:x:29:pi dip:x:30: www-data:x:33: backup:x:34: operator:x:37: list:x:38: irc:x:39: src:x:40: gnats:x:41: shadow:x:42: utmp:x:43: video:x:44:pi sasl:x:45: plugdev:x:46:pi staff:x:50: games:x:60:pi users:x:100:pi nogroup:x:65534: systemd-journal:x:101: systemd-timesync:x:102: systemd-network:x:103: systemd-resolve:x:104: input:x:105:pi kvm:x:106: render:x:107: crontab:x:108: netdev:x:109:pi pi:x:1000: ntp:x:110: messagebus:x:111: ssh:x:112: avahi:x:113: spi:x:999:pi i2c:x:998:pi gpio:x:997:pi lightdm:x:114: bluetooth:x:115: avahi-autoipd:x:116: Debian-exim:x:117: uuidd:x:118: systemd-coredump:x:996: www:x:119:pi pi@raspberry:/etc $ Success, Group "www" has a user "pi" and is also less than 1000, (the number will probably be different than 119). pi@raspberry:/etc $ pi@raspberry:~ $ cd /usr/local pi@raspberry:/usr/local $ ls -al total 40 drwxr-xr-x 10 root root 4096 Dec 18 06:44 . drwxr-xr-x 10 root root 4096 Dec 18 06:49 .. drwxr-xr-x 2 root root 4096 Sep 25 08:44 bin drwxr-xr-x 2 root root 4096 Sep 25 08:44 etc drwxr-xr-x 2 root root 4096 Sep 25 08:44 games drwxr-xr-x 2 root root 4096 Sep 25 08:44 include drwxr-xr-x 5 root root 4096 Dec 18 06:44 lib lrwxrwxrwx 1 root root 9 Dec 18 06:44 man -> share/man drwxr-xr-x 2 root root 4096 Sep 25 08:44 sbin drwxr-xr-x 7 root root 4096 Dec 18 06:44 share drwxr-xr-x 2 root root 4096 Sep 25 08:44 src pi@raspberry:/usr/local $ cd man pi@raspberry:/usr/local/man $ ls -al total 8 drwxr-xr-x 2 root root 4096 Sep 25 08:44 . drwxr-xr-x 7 root root 4096 Dec 18 06:44 .. We need to add directories; “man1” and “man8” to the “man” directory, “man 8” is in the program but “man1” is not so we will add both. pi@raspberry:/usr/local/man $ pi@raspberry:/usr/local/man $ sudo mkdir -p /usr/local/man/man1 man8 pi@raspberry:/usr/local/man $ ls -al total 16 drwxr-xr-x 4 root root 4096 Dec 20 15:29 . drwxr-xr-x 7 root root 4096 Dec 18 06:44 .. drwxr-xr-x 2 root root 4096 Dec 20 15:29 man1 drwxr-xr-x 2 root root 4096 Dec 20 15:29 man8 pi@raspberry:/usr/local/man $ pi@raspberry:/usr/local/man $ cd ~/Acme.com/thttpd-2.29 pi@raspberry:~/Acme.com/thttpd-2.29 $ My system for the install if an Intel Atom N270, 1 GB Memory, 250 GB HDD Dual booting with Windows 7. The Raspberry Pi will show as an ARM processor. So you have an idea of what to expect, I am including all of the printout that happens in each step. The directions from "INSTALL": INSTALL To build: % ./configure Edit config.h to change the configuration options if necessary. % make To install: % make install Edit one of your system rc files to run thttpd at boot time. Do NOT run it from inetd, that setup is inefficient so thttpd doesn't support it. pi@raspberry:~/Acme.com/thttpd-2.29 $ pi@raspberry:~/Acme.com/thttpd-2.29 $ ls (This is to make sure we are at the right place.) aclocal.m4 contrib libhttpd.c mmc.h timers.c cgi-bin extras libhttpd.h README timers.h cgi-src fdwatch.c Makefile.in scripts TODO config.guess fdwatch.h match.c strerror.c version.h config.h FILES match.h tdate_parse.c config.sub index.html mime_encodings.txt tdate_parse.h configure INSTALL mime_types.txt thttpd.8 configure.in install-sh mmc.c thttpd.c pi@raspberry:~/Acme.com/thttpd-2.29 $ Step #1 of "INSTALL" pi@raspberry:~/Acme.com/thttpd-2.29 $ ./configure creating cache ./config.cache checking host system type... i686-pc-linux-gnu checking target system type... i686-pc-linux-gnu checking build system type... i686-pc-linux-gnu checking for gcc... gcc checking whether the C compiler (gcc ) works... yes checking whether the C compiler (gcc ) is a cross-compiler... no checking whether we are using GNU C... yes checking whether gcc accepts -g... yes checking gcc version... 8 checking how to link static binaries... unknown checking for __progname... yes checking how to run the C preprocessor... gcc -E checking for fcntl.h... yes checking for grp.h... yes checking for memory.h... yes checking for paths.h... yes checking for poll.h... yes checking for sys/poll.h... yes checking for sys/devpoll.h... no checking for sys/event.h... no checking for osreldate.h... no checking whether time.h and sys/time.h may both be included... yes checking for dirent.h that defines DIR... yes checking for opendir in -ldir... no checking for /usr/local/v6/lib... no checking for gethostbyname... yes checking for socket... yes checking for main in -linet6... no checking for crypt... no checking for crypt in -lcrypt... yes checking for hstrerror... yes checking for strerror... yes checking for waitpid... yes checking for vsnprintf... yes checking for daemon... yes checking for setsid... yes checking for setlogin... no checking for getaddrinfo... yes checking for getnameinfo... yes checking for gai_strerror... yes checking for kqueue... no checking for sigset... yes checking for atoll... yes checking for unistd.h... yes checking for getpagesize... yes checking for working mmap... yes checking for select... yes checking for poll... yes checking if struct tm has tm_gmtoff member... yes checking if int64_t exists... yes checking if socklen_t exists... yes checking whether make sets ${MAKE}... yes checking for a BSD compatible install... /usr/bin/install -c updating cache ./config.cache creating ./config.status creating Makefile creating cgi-src/Makefile creating extras/Makefile pi@raspberry:~/Acme.com/thttpd-2.29 $ Step #2 of "INSTALL" pi@raspberry:~/Acme.com/thttpd-2.29 $ make gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c thttpd.c thttpd.c: In function ‘main’: thttpd.c:611:12: warning: implicit declaration of function ‘sigset’; did you mean ‘isset’? [-Wimplicit-function-declaration] (void) sigset( SIGTERM, handle_term ); ^~~~~~ isset rm -f mime_encodings.h sed < mime_encodings.txt > mime_encodings.h \ -e 's/#.*//' -e 's/[ ]*$//' -e '/^$/d' \ -e 's/[ ][ ]*/", 0, "/' -e 's/^/{ "/' -e 's/$/", 0 },/' rm -f mime_types.h sed < mime_types.txt > mime_types.h \ -e 's/#.*//' -e 's/[ ]*$//' -e '/^$/d' \ -e 's/[ ][ ]*/", 0, "/' -e 's/^/{ "/' -e 's/$/", 0 },/' gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c libhttpd.c libhttpd.c: In function ‘cgi_child’: libhttpd.c:3557:12: warning: implicit declaration of function ‘sigset’; did you mean ‘isset’? [-Wimplicit-function-declaration] (void) sigset( SIGPIPE, SIG_DFL ); ^~~~~~ isset libhttpd.c: In function ‘ls’: libhttpd.c:2846:10: warning: ‘strncpy’ specified bound depends on the length of the source argument [-Wstringop-overflow=] (void) strncpy( nameptrs[nnames], de->d_name, namlen ); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ libhttpd.c:64:25: note: length computed here # define NAMLEN(dirent) strlen((dirent)->d_name) ^~~~~~~~~~~~~~~~~~~~~~~~ libhttpd.c:2845:12: note: in expansion of macro ‘NAMLEN’ namlen = NAMLEN(de); ^~~~~~ gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c fdwatch.c gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c mmc.c gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c timers.c gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c match.c gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -c tdate_parse.c gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I. -o thttpd thttpd.o libhttpd.o fdwatch.o mmc.o timers.o match.o tdate_parse.o -lcrypt for i in cgi-src extras ; do ( \ cd $i ; \ pwd ; \ make \ WEBDIR=/usr/local/www \ CGIBINDIR=/usr/local/www/cgi-bin \ MANDIR=/usr/local/man \ WEBGROUP=www \ ) ; done /home/pi/Acme.com/thttpd-2.29/cgi-src make[1]: Entering directory '/home/pi/Acme.com/thttpd-2.29/cgi-src' gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I.. -c redirect.c gcc redirect.o -lcrypt -o redirect gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I.. -c ssi.c ssi.c: In function ‘get_filename.constprop’: ssi.c:183:9: warning: ‘strncpy’ specified bound depends on the length of the source argument [-Wstringop-overflow=] (void) strncpy( fn, filename, fl - vl ); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ssi.c:169:10: note: length computed here fl = strlen( filename ); ^~~~~~~~~~~~~~~~~~ gcc ssi.o ../match.o -lcrypt -o ssi gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I.. -c phf.c gcc phf.o -lcrypt -o phf make[1]: Leaving directory '/home/pi/Acme.com/thttpd-2.29/cgi-src' /home/pi/Acme.com/thttpd-2.29/extras make[1]: Entering directory '/home/pi/Acme.com/thttpd-2.29/extras' gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I.. -DWEBDIR=\"/usr/local/www\" -c makeweb.c gcc makeweb.o -o makeweb -lcrypt gcc -O2 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_ATOLL=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 -DHAVE_SOCKLENT=1 -I.. -DWEBDIR=\"/usr/local/www\" -c htpasswd.c gcc htpasswd.o -o htpasswd -lcrypt make[1]: Leaving directory '/home/pi/Acme.com/thttpd-2.29/extras' pi@raspberry:~/Acme.com/thttpd-2.29 $ Step #3 from "INSTALL" and we have to use "sudo" on this because the program is adding directories that are owned by "root". pi@raspberry:~/Acme.com/thttpd-2.29 $ sudo make install mkdir -p /usr/local/sbin /usr/bin/install -c -m 555 -o bin -g bin thttpd /usr/local/sbin mkdir -p /usr/local/man/man8 /usr/bin/install -c -m 444 -o bin -g bin thttpd.8 /usr/local/man/man8 for i in cgi-src extras ; do ( \ cd $i ; \ pwd ; \ make \ WEBDIR=/usr/local/www \ CGIBINDIR=/usr/local/www/cgi-bin \ MANDIR=/usr/local/man \ WEBGROUP=www \ install \ ) ; done /home/pi/Acme.com/thttpd-2.29/cgi-src make[1]: Entering directory '/home/pi/Acme.com/thttpd-2.29/cgi-src' mkdir -p /usr/local/www/cgi-bin rm -f /usr/local/www/cgi-bin/redirect cp redirect /usr/local/www/cgi-bin/redirect rm -f /usr/local/man/man8/redirect.8 cp redirect.8 /usr/local/man/man8/redirect.8 rm -f /usr/local/www/cgi-bin/ssi cp ssi /usr/local/www/cgi-bin/ssi rm -f /usr/local/man/man8/ssi.8 cp ssi.8 /usr/local/man/man8/ssi.8 rm -f /usr/local/www/cgi-bin/phf cp phf /usr/local/www/cgi-bin/phf make[1]: Leaving directory '/home/pi/Acme.com/thttpd-2.29/cgi-src' /home/pi/Acme.com/thttpd-2.29/extras make[1]: Entering directory '/home/pi/Acme.com/thttpd-2.29/extras' rm -f /usr/local/sbin/makeweb /usr/local/sbin/htpasswd /usr/local/sbin/syslogtocern cp makeweb /usr/local/sbin/makeweb chgrp www /usr/local/sbin/makeweb chmod 2755 /usr/local/sbin/makeweb cp htpasswd /usr/local/sbin/htpasswd cp syslogtocern /usr/local/sbin/syslogtocern rm -f /usr/local/man/man1/makeweb.1 cp makeweb.1 /usr/local/man/man1/makeweb.1 rm -f /usr/local/man/man1/htpasswd.1 cp htpasswd.1 /usr/local/man/man1/htpasswd.1 rm -f /usr/local/man/man8/syslogtocern.8 cp syslogtocern.8 /usr/local/man/man8/syslogtocern.8 make[1]: Leaving directory '/home/pi/Acme.com/thttpd-2.29/extras' pi@raspberry:~/Acme.com/thttpd-2.29 $ "thttpd" is now installed. The next thing is to add directories "logs" and "users" to the "www" directory. pi@raspberry:~/Acme.com/thttpd-2.29 $ cd /usr/local/www pi@raspberry:/usr/local/www $ ls -al total 12 drwxr-xr-x 3 root root 4096 Dec 20 15:49 . drwxr-xr-x 11 root root 4096 Dec 20 15:49 .. drwxr-xr-x 2 root root 4096 Dec 20 15:49 cgi-bin pi@raspberry:/usr/local/www $ sudo mkdir logs users pi@raspberry:/usr/local/www $ ls -al total 20 drwxr-xr-x 5 root root 4096 Dec 20 15:54 . drwxr-xr-x 11 root root 4096 Dec 20 15:49 .. drwxr-xr-x 2 root root 4096 Dec 20 15:49 cgi-bin drwxr-xr-x 2 root root 4096 Dec 20 15:54 logs drwxr-xr-x 2 root root 4096 Dec 20 15:54 users pi@raspberry:/usr/local/www $ Now we go back one level so we can change the owner and group on everything in the "www" directory from "root:root" to "root:www". pi@raspberry:/usr/local/www $ cd .. pi@raspberry:/usr/local $ pi@raspberry:/usr/local $ sudo chown -vR root:www www changed ownership of 'www/users' from root:root to root:www changed ownership of 'www/cgi-bin/phf' from root:root to root:www changed ownership of 'www/cgi-bin/ssi' from root:root to root:www changed ownership of 'www/cgi-bin/redirect' from root:root to root:www changed ownership of 'www/cgi-bin' from root:root to root:www changed ownership of 'www/logs' from root:root to root:www changed ownership of 'www' from root:root to root:www pi@raspberry:/usr/local $ cd www pi@raspberry:/usr/local/www $ ls -al total 20 drwxr-xr-x 5 root www 4096 Dec 20 15:54 . drwxr-xr-x 11 root root 4096 Dec 20 15:49 .. drwxr-xr-x 2 root www 4096 Dec 20 15:49 cgi-bin drwxr-xr-x 2 root www 4096 Dec 20 15:54 logs drwxr-xr-x 2 root www 4096 Dec 20 15:54 users pi@raspberry:/usr/local/www $ Now we need to change the permissions on "users" so those in the "www" group can write to this directory! pi@raspberry:/usr/local/www $ sudo chmod -v 0775 users mode of 'users' changed from 0755 (rwxr-xr-x) to 0775 (rwxrwxr-x) pi@raspberry:/usr/local/www $ ls -al total 20 drwxr-xr-x 5 root www 4096 Dec 20 15:54 . drwxr-xr-x 11 root root 4096 Dec 20 15:49 .. drwxr-xr-x 2 root www 4096 Dec 20 15:49 cgi-bin drwxr-xr-x 2 root www 4096 Dec 20 15:54 logs drwxrwxr-x 2 root www 4096 Dec 20 15:54 users pi@raspberry:/usr/local/www $ We now change back to the "pi" home directory and are going to add a "user" that belongs in the "www" group, from the help on "adduser" we see what we have to type. pi@raspberry:/usr/local/www $ cd pi@raspberry:~ $ pi@raspberry:~ $ adduser --help adduser [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] [--add_extra_groups] USER Add a normal user ... pi@raspberry:~ $ For an example, I will add "ac0xl", my ham radio call sign, as a user for my website. One can think of these as different tabs or categories on your website. Use a different password for these "users" than the one you use for "pi" for more security. The information it asks for was for the "finger" program which most computers don't run for security reasons. I usually just use the "user" for the name and leave the rest blank. (This time I will use my real data.) pi@raspberry:~ $ pi@raspberry:~ $ sudo adduser --ingroup www ac0xl Adding user `ac0xl' ... Adding new user `ac0xl' (1001) with group `www' ... Creating home directory `/home/ac0xl' ... Copying files from `/etc/skel' ... New password: Retype new password: passwd: password updated successfully Changing the user information for ac0xl Enter the new value, or press ENTER for the default Full Name []: Frank Anderson Room Number []: 651 N Broadway Work Phone []: 435-210-0710 Home Phone []: 970-424-1451 Other []: Green River UT 84525-0615 Is the information correct? [Y/n] y pi@raspberry:~ $ pi@raspberry:~ $ cd /home pi@raspberry:/home $ ls -al total 32 drwxr-xr-x 5 root root 4096 Dec 20 16:15 . drwxr-xr-x 21 root root 4096 Dec 18 07:06 .. drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:15 ac0xl drwx------ 2 root root 16384 Dec 18 06:33 lost+found drwxr-xr-x 19 pi pi 4096 Dec 20 14:36 pi pi@raspberry:/home $ cat /etc/group ... www:x:119:pi Looking at "/home" we see "ac0xl" is listed as an owner and belongs to the "www" group. When we look at "/etc/group" we see group "www" only lists "pi" and "ac0xl" is not even listed as a "user" even though I got "Adding new user `ac0xl' (1001) with group `www' ..." which is OK since it does show up right in "/home". pi@raspberry:/home $ cd ac0xl pi@raspberry:/home/ac0xl $ ls -al total 20 drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:15 . drwxr-xr-x 5 root root 4096 Dec 20 16:15 .. -rw-r--r-- 1 ac0xl www 220 Dec 20 16:15 .bash_logout -rw-r--r-- 1 ac0xl www 3523 Dec 20 16:15 .bashrc -rw-r--r-- 1 ac0xl www 807 Dec 20 16:15 .profile pi@raspberry:/home/ac0xl $ This is where I screwed up! But I am leaving it so you will see how to correct the problem if it happens to you. NOTICE the prompt starts with "pi" and I forgot to change to user "ac0xl", so when I did "makeweb", the computer did what I told it to do, and nothing changed in "/home/ac0xl"! pi@raspberry:/home/ac0xl $ pi@raspberry:/home/ac0xl $ makeweb Created web directory /usr/local/www/users/pi Created symbolic link /home/pi/public_html pi@raspberry:/home/ac0xl $ ls -al total 20 drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:15 . drwxr-xr-x 5 root root 4096 Dec 20 16:15 .. -rw-r--r-- 1 ac0xl www 220 Dec 20 16:15 .bash_logout -rw-r--r-- 1 ac0xl www 3523 Dec 20 16:15 .bashrc -rw-r--r-- 1 ac0xl www 807 Dec 20 16:15 .profile pi@raspberry:/home/ac0xl $ pi@raspberry:/home/ac0xl $ cd (putting me back to "/home/pi".) pi@raspberry:~ $ pi@raspberry:~ $ su ac0xl ("shell to user" "ac0xl".) Password: ac0xl@raspberry:/home/pi $ (I am now user "ac0xl".) ac0xl@raspberry:/home/pi $ cd (I am now in the home directory of "ac0xl".) ac0xl@raspberry:~ $ ls -al total 20 drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:15 . drwxr-xr-x 5 root root 4096 Dec 20 16:15 .. -rw-r--r-- 1 ac0xl www 220 Dec 20 16:15 .bash_logout -rw-r--r-- 1 ac0xl www 3523 Dec 20 16:15 .bashrc -rw-r--r-- 1 ac0xl www 807 Dec 20 16:15 .profile ac0xl@raspberry:~ $ makeweb Created web directory /usr/local/www/users/ac0xl Created symbolic link /home/ac0xl/public_html ac0xl@raspberry:~ $ ls -al total 20 drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:22 . drwxr-xr-x 5 root root 4096 Dec 20 16:15 .. -rw-r--r-- 1 ac0xl www 220 Dec 20 16:15 .bash_logout -rw-r--r-- 1 ac0xl www 3523 Dec 20 16:15 .bashrc -rw-r--r-- 1 ac0xl www 807 Dec 20 16:15 .profile lrwxrwxrwx 1 ac0xl www 26 Dec 20 16:22 public_html -> /usr/local/www/users/ac0xl ac0xl@raspberry:~ $ This time I got what I was looking for! To exit the shell and return to your previous position type "exit". ac0xl@raspberry:~ $ exit pi@raspberry:~ $ pi@raspberry:~ $ cd (just to make sure we are in the home directory of "pi".) pi@raspberry:~ $ pi@raspberry:~ $ ls Acme.com Documents MagPi Pictures public_html Videos Desktop Downloads Music Public Templates Now to remove the screw ups! (Created web directory /usr/local/www/users/pi; Created symbolic link /home/pi/public_html). pi@raspberry:~ $ rm -v public_html removed 'public_html' pi@raspberry:~ $ pi@raspberry:~ $ pi@raspberry:~ $ cd /usr/local/www/users pi@raspberry:/usr/local/www/users $ ls -al total 16 drwxrwxr-x 4 root www 4096 Dec 20 16:22 . drwxr-xr-x 5 root www 4096 Dec 20 15:54 .. drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:22 ac0xl drwxr-xr-x 2 pi pi 4096 Dec 20 16:20 pi pi@raspberry:/usr/local/www/users $ sudo rmdir -v pi rmdir: removing directory, 'pi' pi@raspberry:/usr/local/www/users $ ls -al total 12 drwxrwxr-x 3 root www 4096 Dec 20 16:37 . drwxr-xr-x 5 root www 4096 Dec 20 15:54 .. drwxr-xr-x 2 ac0xl www 4096 Dec 20 16:22 ac0xl pi@raspberry:/usr/local/www/users $ Other ideas for web "users" could be: documents, downloads, games, memes, music, pictures, videos, etc., just categories of what you want on your website, or what you want to share. Again the process: sudo adduser --ingroup www videos (new web user "videos") (use a password that is different from the one for "pi") su videos (shell to user "videos") makeweb exit (exit the shell back to where you were) I liked the "anvil_thttpd.gif" on the Acme.com website and chose it as my favicon.ico by renaming a copy to favicon.ico. An "anvil" is built to be hammered on without failing, and "thttpd" is built to take a hammering without failing. It is bullet proof! When you look at your logs you will see how "thttpd" will block all sorts of attempts to break your website! You will also get an idea of things to avoid on your website. pi@raspberry:~ $ cd /usr/local/sbin pi@raspberry:/usr/local/sbin $ ls htpasswd makeweb syslogtocern thttpd pi@raspberry:/usr/local/sbin $ ls -al total 168 drwxr-xr-x 2 root root 4096 Dec 20 15:49 . drwxr-xr-x 11 root root 4096 Dec 20 15:49 .. -rwxr-xr-x 1 root root 16764 Dec 20 15:49 htpasswd -rwxr-sr-x 1 root www 16208 Dec 20 15:49 makeweb -r-xr-xr-x 1 root root 2878 Dec 20 15:49 syslogtocern -r-xr-xr-x 1 bin bin 121448 Dec 20 15:49 thttpd pi@raspberry:/usr/local/sbin $ pi@raspberry:/usr/local/sbin $ cd ~/freedom (The directory "freedom" should be in "/home/pi/"). pi@raspberry:~/freedom $ ls 2010Website.pdf 2019-12-06-Google-Search-Is-Broken.txt thttpd-extras 2019-09-05-Project.txt 2019-12-26-Installing-thttpd.txt thttpd_config 2019-10-01-website.txt sitemap.xml thttpd_config~ 2019-11-26-web-server.txt sitemap.xml.txt pi@raspberry:~/freedom $ pi@raspberry:~/freedom $ pi@raspberry:~/freedom $ sudo cp -rv thttpd-extras /usr/local/sbin/ 'thttpd-extras' -> '/usr/local/sbin/thttpd-extras' 'thttpd-extras/thttpd.sh' -> '/usr/local/sbin/thttpd-extras/thttpd.sh' 'thttpd-extras/thttpd_wrapper' -> '/usr/local/sbin/thttpd-extras/thttpd_wrapper' 'thttpd-extras/thttpd-rotate' -> '/usr/local/sbin/thttpd-extras/thttpd-rotate' 'thttpd-extras/rc.local' -> '/usr/local/sbin/thttpd-extras/rc.local' 'thttpd-extras/readme.txt' -> '/usr/local/sbin/thttpd-extras/readme.txt' 'thttpd-extras/robots.txt' -> '/usr/local/sbin/thttpd-extras/robots.txt' 'thttpd-extras/thttpd_config~' -> '/usr/local/sbin/thttpd-extras/thttpd_config~' 'thttpd-extras/anvil_thttpd.gif' -> '/usr/local/sbin/thttpd-extras/anvil_thttpd.gif' 'thttpd-extras/favicon.ico' -> '/usr/local/sbin/thttpd-extras/favicon.ico' 'thttpd-extras/thttpd_config' -> '/usr/local/sbin/thttpd-extras/thttpd_config' 'thttpd-extras/sitemap.xml' -> '/usr/local/sbin/thttpd-extras/sitemap.xml' 'thttpd-extras/robots-site.txt' -> '/usr/local/sbin/thttpd-extras/robots-site.txt' 'thttpd-extras/sitemap.xml.txt' -> '/usr/local/sbin/thttpd-extras/sitemap.xml.txt' pi@raspberry:~/freedom $ pi@raspberry:~/freedom $ pi@raspberry:~/freedom $ cd /usr/local/sbin/thttpd-extras pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -al total 60 drwxr-xr-x 2 root root 4096 Dec 27 16:36 . drwxr-xr-x 3 root root 4096 Dec 27 16:36 .. -rw-r--r-- 1 root root 533 Dec 27 16:36 anvil_thttpd.gif -rw-r--r-- 1 root root 533 Dec 27 16:36 favicon.ico -rw-r--r-- 1 root root 484 Dec 27 16:36 rc.local -rw-r--r-- 1 root root 247 Dec 27 16:36 readme.txt -rw-r--r-- 1 root root 73 Dec 27 16:36 robots-site.txt -rw-r--r-- 1 root root 27 Dec 27 16:36 robots.txt -rw-r--r-- 1 root root 189 Dec 27 16:36 sitemap.xml -rw-r--r-- 1 root root 189 Dec 27 16:36 sitemap.xml.txt -rw-r--r-- 1 root root 445 Dec 27 16:36 thttpd_config -rw-r--r-- 1 root root 445 Dec 27 16:36 thttpd_config~ -rw-r--r-- 1 root root 1745 Dec 27 16:36 thttpd-rotate -rw-r--r-- 1 root root 136 Dec 27 16:36 thttpd.sh -rw-r--r-- 1 root root 120 Dec 27 16:36 thttpd_wrapper pi@raspberry:/usr/local/sbin/thttpd-extras $ The files: rc.local, and thttpd* files are all program files that have to execute so we need to change their privileges to "0755", the other files are data files and are "0644". pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo chmod -v 0755 rc.local mode of 'rc.local' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo chmod -v 0755 thttpd* mode of 'thttpd_config' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) mode of 'thttpd_config~' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) mode of 'thttpd-rotate' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) mode of 'thttpd.sh' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) mode of 'thttpd_wrapper' changed from 0644 (rw-r--r--) to 0755 (rwxr-xr-x) pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -al total 60 drwxr-xr-x 2 root root 4096 Dec 27 16:36 . drwxr-xr-x 3 root root 4096 Dec 27 16:36 .. -rw-r--r-- 1 root root 533 Dec 27 16:36 anvil_thttpd.gif -rw-r--r-- 1 root root 533 Dec 27 16:36 favicon.ico -rwxr-xr-x 1 root root 484 Dec 27 16:36 rc.local -rw-r--r-- 1 root root 247 Dec 27 16:36 readme.txt -rw-r--r-- 1 root root 73 Dec 27 16:36 robots-site.txt -rw-r--r-- 1 root root 27 Dec 27 16:36 robots.txt -rw-r--r-- 1 root root 189 Dec 27 16:36 sitemap.xml -rw-r--r-- 1 root root 189 Dec 27 16:36 sitemap.xml.txt -rwxr-xr-x 1 root root 445 Dec 27 16:36 thttpd_config -rwxr-xr-x 1 root root 445 Dec 27 16:36 thttpd_config~ -rwxr-xr-x 1 root root 1745 Dec 27 16:36 thttpd-rotate -rwxr-xr-x 1 root root 136 Dec 27 16:36 thttpd.sh -rwxr-xr-x 1 root root 120 Dec 27 16:36 thttpd_wrapper pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat /etc/rc.local #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi exit 0 pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iav /etc/rc.local /etc/rc.local-original '/etc/rc.local' -> '/etc/rc.local-original' pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat rc.local #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # Print the IP address _IP=$(hostname -I) || true if [ "$_IP" ]; then printf "My IP address is %s\n" "$_IP" fi # Start thttpd echo "Starting thttpd. \n" . /etc/thttpd.sh # exit 0 pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ # Start thttpd echo "Starting thttpd. \n" . /etc/thttpd.sh # We see the only difference is the 4 lines before the line "exit 0". To make it easy, we will just replace the old "/etc/rc.local" with our new one. pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iav rc.local /etc/rc.local cp: overwrite '/etc/rc.local'? y 'rc.local' -> '/etc/rc.local' pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -l /etc/rc.local -rwxr-xr-x 1 root root 485 Dec 30 14:27 /etc/rc.local (rc.local is still 0755) pi@raspberry:/usr/local/sbin/thttpd-extras $ We now need to copy thttpd.sh to /etc and make sure it is 0755. pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iav thttpd.sh /etc/ 'thttpd.sh' -> '/etc/thttpd.sh' pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -l /etc/thttpd.sh -rwxr-xr-x 1 root root 136 Dec 27 16:36 /etc/thttpd.sh (thttpd.sh is still 0755) pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat thttpd.sh #!/bin/sh # thttpd.sh if [ -x /usr/local/sbin/thttpd_wrapper ] ; then echo -n " thttpd" /usr/local/sbin/thttpd_wrapper & fi # exit 0 pi@raspberry:/usr/local/sbin/thttpd-extras $ thttpd.sh is looking for thttpd_wrapper to be in "/usr/local/sbin/" and being 0755, so we will copy "thttpd_wrapper" up one level to there. pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iav thttpd_wrapper ../ 'thttpd_wrapper' -> '../thttpd_wrapper' pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -l /usr/local/sbin total 168 -rwxr-xr-x 1 root root 16764 Dec 20 15:49 htpasswd -rwxr-sr-x 1 root www 16208 Dec 20 15:49 makeweb -r-xr-xr-x 1 root root 2878 Dec 20 15:49 syslogtocern -r-xr-xr-x 1 bin bin 121448 Dec 20 15:49 thttpd drwxr-xr-x 2 root root 4096 Dec 30 14:12 thttpd-extras -rwxr-xr-x 1 root root 120 Dec 27 16:36 thttpd_wrapper (thttpd_wrapper is still 0755) pi@raspberry:/usr/local/sbin/thttpd-extras $ The purpose of this file is to restart "thttpd" if it stops and it checks every 10 seconds to see if "/usr/local/sbin/thttpd" is running and it also loads the configuration file that is "/usr/local/www/thttpd_config". If one changes the config file, one only has to kill the "thttpd pid number" and the wrapper will restart it in 10 seconds with the new configuration. "sudo kill xxxx" will kill a program. To get all of the running "pid" numbers use "ps -A". If you forget to use "sudo" to manually start "thttpd" or even "rc.local" every 10 seconds you will get a message that "/usr/local/www/logs/thttpd_log" can not be written to! (because it is now owned by nobody). What appears on your screen is not what you type in, but both the error message and what you type in. Type in "ps -A" and look for the number for "thttpd_wrapper" and then type in "sudo kill xxxx" with "xxxx" being the "pid" number. Been there, done that way too many times! pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat thttpd_wrapper #!/bin/sh # thttpd_wrapper while true ; do /usr/local/sbin/thttpd -D -C /usr/local/www/thttpd_config sleep 10 done # pi@raspberry:/usr/local/sbin/thttpd-extras $ Next "thttpd-rotate" needs to be moved to "/etc/cron.daily/" so our log files get moved every day. The time they get rotated is in "/etc/crontab" pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat /etc/crontab # /etc/crontab: system-wide crontab # Unlike any other crontab you don't have to run the `crontab' # command to install the new version when you edit this file # and files in /etc/cron.d. These files also have username fields, # that none of the other crontabs do. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 17 * * * * root cd / && run-parts --report /etc/cron.hourly 25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily ) 47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly ) 52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly ) # pi@raspberry:/usr/local/sbin/thttpd-extras $ Here we see /etc/cron.daily is started at 06:25 in the morning. pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iav thttpd-rotate /etc/cron.daily/ 'thttpd-rotate' -> '/etc/cron.daily/thttpd-rotate' pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -al /etc/cron.daily total 68 drwxr-xr-x 2 root root 4096 Dec 30 15:22 . drwxr-xr-x 136 root root 12288 Dec 30 14:55 .. -rwxr-xr-x 1 root root 311 May 19 2019 0anacron -rwxr-xr-x 1 root root 1478 May 28 2019 apt-compat -rwxr-xr-x 1 root root 355 Dec 29 2017 bsdmainutils -rwxr-xr-x 1 root root 1187 Apr 18 2019 dpkg -rwxr-xr-x 1 root root 4128 Sep 3 11:51 exim4-base -rwxr-xr-x 1 root root 377 Aug 28 2018 logrotate -rwxr-xr-x 1 root root 1123 Feb 10 2019 man-db -rwxr-xr-x 1 root root 539 Jan 15 2019 mdadm -rwxr-xr-x 1 root root 1403 Mar 21 2019 ntp -rwxr-xr-x 1 root root 249 Sep 27 2017 passwd -rw-r--r-- 1 root root 102 Jun 23 2019 .placeholder -rwxr-xr-x 1 root root 1745 Dec 27 16:36 thttpd-rotate (thttpd_rotate is still 0755) pi@raspberry:/usr/local/sbin/thttpd-extras $ The "thttpd_rotate" file I made is for 50 days so you don't have to move them every day, week, or even month. I also put a header and a tail on the files when they rotate so you have an idea how long your website has been up. pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat thttpd-rotate #!/bin/sh # /etc/cron.daily/thttpd-rotate cd /usr/local/www/logs rm -f thttpd_log.50 mv thttpd_log.49 thttpd_log.50 mv thttpd_log.48 thttpd_log.49 mv thttpd_log.47 thttpd_log.48 mv thttpd_log.46 thttpd_log.47 mv thttpd_log.45 thttpd_log.46 mv thttpd_log.44 thttpd_log.45 mv thttpd_log.43 thttpd_log.44 mv thttpd_log.42 thttpd_log.43 mv thttpd_log.41 thttpd_log.42 mv thttpd_log.40 thttpd_log.41 mv thttpd_log.39 thttpd_log.40 mv thttpd_log.38 thttpd_log.39 mv thttpd_log.37 thttpd_log.38 mv thttpd_log.36 thttpd_log.37 mv thttpd_log.35 thttpd_log.36 mv thttpd_log.34 thttpd_log.35 mv thttpd_log.33 thttpd_log.34 mv thttpd_log.32 thttpd_log.33 mv thttpd_log.31 thttpd_log.32 mv thttpd_log.30 thttpd_log.31 mv thttpd_log.29 thttpd_log.30 mv thttpd_log.28 thttpd_log.29 mv thttpd_log.27 thttpd_log.28 mv thttpd_log.26 thttpd_log.27 mv thttpd_log.25 thttpd_log.26 mv thttpd_log.24 thttpd_log.25 mv thttpd_log.23 thttpd_log.24 mv thttpd_log.22 thttpd_log.23 mv thttpd_log.21 thttpd_log.22 mv thttpd_log.20 thttpd_log.21 mv thttpd_log.19 thttpd_log.20 mv thttpd_log.18 thttpd_log.19 mv thttpd_log.17 thttpd_log.18 mv thttpd_log.16 thttpd_log.17 mv thttpd_log.15 thttpd_log.16 mv thttpd_log.14 thttpd_log.15 mv thttpd_log.13 thttpd_log.14 mv thttpd_log.12 thttpd_log.13 mv thttpd_log.11 thttpd_log.12 mv thttpd_log.10 thttpd_log.11 mv thttpd_log.09 thttpd_log.10 mv thttpd_log.08 thttpd_log.09 mv thttpd_log.07 thttpd_log.08 mv thttpd_log.06 thttpd_log.07 mv thttpd_log.05 thttpd_log.06 mv thttpd_log.04 thttpd_log.05 mv thttpd_log.03 thttpd_log.04 mv thttpd_log.02 thttpd_log.03 mv thttpd_log.01 thttpd_log.02 date >> thttpd_log w >> thttpd_log mv thttpd_log thttpd_log.01 date > thttpd_log w >> thttpd_log kill -usr1 `cat /var/run/thttpd.pid` # pi@raspberry:/usr/local/sbin/thttpd-extras $ To copy the log files to dates, I "cd /usr/local/www/logs/" and then type ls -al to get a listing of the files and the dates for the files. Then to copy the files: "sudo cp -iv *log.xx 2020.01.01" with xx being the log number and then year.mo.da and then check that I have everything right before I press the enter key. Since the log files belong to nobody and nogroup one has to use "sudo" and "cp -iv" so root can then change the owner to something else. I posted the logs to my site just so one could see what to expect from activity on the Internet and how "thttpd" handles those interactions. The last files to copy will be the "thttpd_config" files which go to "/usr/local/www/". pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iav thttpd_config* /usr/local/www/ 'thttpd_config' -> '/usr/local/www/thttpd_config' 'thttpd_config~' -> '/usr/local/www/thttpd_config~' pi@raspberry:/usr/local/sbin/thttpd-extras $ ls -al /usr/local/www/ total 28 drwxr-xr-x 5 root www 4096 Dec 30 15:29 . drwxr-xr-x 11 root root 4096 Dec 20 15:49 .. drwxr-xr-x 2 root www 4096 Dec 20 15:49 cgi-bin drwxr-xr-x 2 root www 4096 Dec 20 15:54 logs -rwxr-xr-x 1 root root 445 Dec 27 16:36 thttpd_config -rwxr-xr-x 1 root root 445 Dec 27 16:36 thttpd_config~ drwxrwxr-x 3 root www 4096 Dec 20 16:37 users pi@raspberry:/usr/local/sbin/thttpd-extras $ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat thttpd_config # /usr/local/www/thttpd_config dir=/usr/local/www chroot #chroot jail data_dir=users #vhost # if you use a domain name you will have to uncomment (remove the # at the beginning) and then make a "user" directory using your external IPv4 address (xxx.xxx.xxx.xxx) and inside this directory make symbolic links back up to your other files in "users" (../"user-name"). cgipat=**.cgi logfile=/usr/local/www/logs/thttpd_log pidfile=/var/run/thttpd.pid # pi@raspberry:/usr/local/sbin/thttpd-extras $ TESTING: Starting thttpd without the wrapper. pi@raspberry:~ $ sudo /usr/local/sbin/thttpd -D -C /usr/local/www/thttpd_config (This screen is still busy because thttpd is in the foreground and still running.) Using the web browser and typing "localhost" I got a green screen with this on it! So far so good! Typing “localhost” on the browser, we get: Index of / mode links bytes last-changed name dr-x 3 4096 Dec 20 23:37 ./ dr-x 5 4096 Dec 30 22:29 ../ dr-x 2 4096 Dec 20 23:22 ac0xl/ In a new terminal, type: "cd /usr/local/www/logs" pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ ls thttpd_log pi@raspberry:/usr/local/www/logs $ cat thttpd_log ::1 - - [30/Dec/2019:23:33:04 +0000] "UNKNOWN UNKNOWN" 400 0 "" "" ::1 - - [30/Dec/2019:23:33:04 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [30/Dec/2019:23:33:05 +0000] "GET /favicon.ico HTTP/1.1" 404 0 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ ps -A (We are looking for the thttpd pid number.) PID TTY TIME CMD 1 ? 00:00:07 systemd 2 ? 00:00:00 kthreadd 3 ? 00:00:00 rcu_gp ... 1591 pts/0 00:00:00 bash 1628 pts/1 00:00:00 bash 1661 ? 00:00:00 gvfsd-network 1692 ? 00:00:00 gvfsd-dnssd 1763 ? 00:00:08 kworker/1:2-events_long 1901 ? 00:00:01 kworker/u4:1-cfg80211 2097 pts/2 00:00:00 bash 2119 ? 00:00:00 kworker/0:2-events 2120 pts/2 00:00:00 sudo 2121 ? 00:00:06 thttpd 2122 ? 00:01:02 x-www-browser 2165 ? 00:00:27 Web Content 2197 ? 00:00:05 WebExtensions 2239 ? 00:00:01 Web Content 2276 ? 00:00:01 kworker/u4:0-events_unbound 2293 ? 00:00:00 kworker/0:1-events 2307 ? 00:00:00 kworker/1:0-events 2310 ? 00:00:00 kworker/u4:2-cfg80211 2311 ? 00:00:00 kworker/0:0-events 2322 ? 00:00:00 kworker/1:1-events 2323 pts/1 00:00:00 ps pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ sudo kill 2121 pi@raspberry:/usr/local/www/logs $ pi@raspberry:~ $ sudo /usr/local/sbin/thttpd -D -C /usr/local/www/thttpd_config ^C (Control C won’t stop the program) ^X (Control X won’t stop the program) pi@raspberry:~ $ The "sudo kill 2121" from a different terminal, released the busy "terminal". pi@raspberry:~ $ Now we need to add the files to "users" that are in "/usr/local/sbin/thttpd-extras". pi@raspberry:/usr/local/sbin/thttpd-extras $ ls anvil_thttpd.gif rc.local robots-site.txt sitemap.xml thttpd_config thttpd-rotate thttpd_wrapper favicon.ico readme.txt robots.txt sitemap.xml.txt thttpd_config~ thttpd.sh pi@raspberry:/usr/local/sbin/thttpd-extras $ (Since these files are owned by root you will need to use sudo to copy them.) pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iv favicon.ico /usr/local/www/users/ 'favicon.ico' -> '/usr/local/www/users/favicon.ico' pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iv readme.txt /usr/local/www/users/ 'readme.txt' -> '/usr/local/www/users/readme.txt' pi@raspberry:/usr/local/sbin/thttpd-extras $ sudo cp -iv robots.txt /usr/local/www/users/ 'robots.txt' -> '/usr/local/www/users/robots.txt' pi@raspberry:/usr/local/sbin/thttpd-extras $ cat robots-site.txt User-agent: * Disallow: Sitemap: http://xxx.xxx.xxx.xxx/sitemap.xml/ pi@raspberry:/usr/local/sbin/thttpd-extras $ cat sitemap.xml http://xxx.xxx.xxx.xxx/ pi@raspberry:/usr/local/sbin/thttpd-extras $ You would use "robots-site.txt" replacing the XXX.xxx.xxx.xxx with your external static IPv4 address and then naming it "robots.txt". Likewise, with the "sitemap.xml" file and keep the same name for it. Adding both of these files to “/usr/local/www/users/”, if you have an external static IP address. pi@raspberry:~ $ pi@raspberry:~ $ cd /etc pi@raspberry:/etc $ sudo ./rc.local (Starting thttpd from rc.local, REMEMBER the sudo!) My internal IP address is 192.168.19.11 Starting thttpd. thttpdpi@raspberry:/etc $ (Notice the thttpd in front of pi@raspberry:/etc $ on the terminal screen, it is still running.) Typing “localhost” on the browser, we get: Index of / mode links bytes last-changed name dr-x 3 4096 Dec 31 00:01 ./ dr-x 5 4096 Dec 30 22:29 ../ dr-x 2 4096 Dec 20 23:22 ac0xl/ -r-- 1 533 Dec 31 00:00 favicon.ico -r-- 1 247 Dec 31 00:01 readme.txt -r-- 1 27 Dec 31 00:01 robots.txt pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ ls thttpd_log pi@raspberry:/usr/local/www/logs $ cat *log ::1 - - [30/Dec/2019:23:33:04 +0000] "UNKNOWN UNKNOWN" 400 0 "" "" ::1 - - [30/Dec/2019:23:33:04 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [30/Dec/2019:23:33:05 +0000] "GET /favicon.ico HTTP/1.1" 404 0 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:16:05 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:16:36 +0000] "GET /favicon.ico HTTP/1.1" 200 533 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:16:54 +0000] "GET /readme.txt HTTP/1.1" 200 247 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:17:14 +0000] "GET /robots.txt HTTP/1.1" 200 27 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:17:23 +0000] "GET /ac0xl/ HTTP/1.1" 200 25000 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" pi@raspberry:/usr/local/www/logs $ On our first test we didn't get a "/favicon.ico" thus the " 404 0 ", but by refreshing the browser the second test gave us "GET /favicon.ico HTTP/1.1" 200 533 "http://localhost/" a file with 533 bytes, 247 bytes for "readme.txt", and 27 bytes for "robots.txt" with directories getting 25000 bytes. pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ ps -A PID TTY TIME CMD 1 ? 00:00:07 systemd 2 ? 00:00:00 kthreadd 3 ? 00:00:00 rcu_gp 4 ? 00:00:00 rcu_par_gp ... 1591 pts/0 00:00:00 bash 1628 pts/1 00:00:00 bash 1661 ? 00:00:00 gvfsd-network 1692 ? 00:00:00 gvfsd-dnssd 2097 pts/2 00:00:00 bash 2122 ? 00:01:56 x-www-browser 2165 ? 00:00:35 Web Content 2197 ? 00:00:08 WebExtensions 2239 ? 00:00:01 Web Content 2307 ? 00:00:03 kworker/1:0-events 2370 ? 00:00:00 kworker/0:0-events 2386 ? 00:00:01 kworker/u4:2-phy0 2390 pts/2 00:00:00 thttpd_wrapper 2391 ? 00:00:05 thttpd 2404 ? 00:00:00 kworker/1:1-mm_percpu_wq 2415 ? 00:00:00 kworker/0:1-events 2417 ? 00:00:00 kworker/u4:0-events_unbound 2418 ? 00:00:00 kworker/1:2-events 2425 ? 00:00:00 kworker/0:2-events 2426 ? 00:00:00 kworker/u4:1-events_unbound 2429 pts/1 00:00:00 ps pi@raspberry:/usr/local/www/logs $ Here we see the "thttpd_wrapper" has a "pid" of 2390 and "thttpd" has a pid of 2391. http://192.168.19.11/ (eMachine wlan0:192.168.19.11/24) LAN (Local Area Network 192.168.19.0) Typing “http://192.168.19.11/” on the browser, we get: Index of / mode links bytes last-changed name dr-x 3 4096 Dec 31 00:01 ./ dr-x 5 4096 Dec 30 22:29 ../ dr-x 2 4096 Dec 20 23:22 ac0xl/ -r-- 1 533 Dec 31 00:00 favicon.ico -r-- 1 247 Dec 31 00:01 readme.txt -r-- 1 27 Dec 31 00:01 robots.txt http://192.168.19.2/ (Raspberry Pi 3B static eth0:192.168.19.2/24) LAN (Local Area Network 192.168.19.0) Typing “http://192.168.19.2/” on the browser, we get: Index of / mode links bytes last-changed name dr-x 11 4096 Dec 14 04:39 ./ dr-x 5 4096 Nov 6 18:41 ../ dr-x 6 4096 Nov 16 04:34 ac0xl/ dr-x 3 4096 Nov 11 20:14 delinquent-accounts/ dr-x 2 4096 Nov 10 04:19 documents/ dr-x 2 4096 Nov 10 04:20 downloads/ -r-- 1 533 Dec 2 07:32 favicon.ico dr-x 2 4096 Nov 10 04:21 memes/ dr-x 2 4096 Nov 10 04:23 music/ dr-x 2 4096 Nov 10 04:24 pictures/ -r-- 1 247 Dec 2 07:32 readme.txt -r-- 1 70 Dec 14 04:39 robots.txt -r-- 1 186 Dec 14 04:39 sitemap.xml dr-x 3 4096 Nov 20 18:22 va/ dr-x 2 4096 Nov 10 04:28 videos/ http://192.168.19.14/ (Raspberry Pi 3B wlan0:192.168.19.14/24) LAN (Local Area Network 192.168.19.0) Typing “http://192.168.19.14/” on the browser, we get: Index of / mode links bytes last-changed name dr-x 11 4096 Dec 14 04:39 ./ dr-x 5 4096 Nov 6 18:41 ../ dr-x 6 4096 Nov 16 04:34 ac0xl/ dr-x 3 4096 Nov 11 20:14 delinquent-accounts/ dr-x 2 4096 Nov 10 04:19 documents/ dr-x 2 4096 Nov 10 04:20 downloads/ -r-- 1 533 Dec 2 07:32 favicon.ico dr-x 2 4096 Nov 10 04:21 memes/ dr-x 2 4096 Nov 10 04:23 music/ dr-x 2 4096 Nov 10 04:24 pictures/ -r-- 1 247 Dec 2 07:32 readme.txt -r-- 1 70 Dec 14 04:39 robots.txt -r-- 1 186 Dec 14 04:39 sitemap.xml dr-x 3 4096 Nov 20 18:22 va/ dr-x 2 4096 Nov 10 04:28 videos/ http://162.250.19.7/ (My WAN (Wide Area Network) static IPv4 address /162.250.19.7/) Typing “http://162.250.19.7/” on the browser, we get: Index of / mode links bytes last-changed name dr-x 11 4096 Dec 14 04:39 ./ dr-x 5 4096 Nov 6 18:41 ../ dr-x 6 4096 Nov 16 04:34 ac0xl/ dr-x 3 4096 Nov 11 20:14 delinquent-accounts/ dr-x 2 4096 Nov 10 04:19 documents/ dr-x 2 4096 Nov 10 04:20 downloads/ -r-- 1 533 Dec 2 07:32 favicon.ico dr-x 2 4096 Nov 10 04:21 memes/ dr-x 2 4096 Nov 10 04:23 music/ dr-x 2 4096 Nov 10 04:24 pictures/ -r-- 1 247 Dec 2 07:32 readme.txt -r-- 1 70 Dec 14 04:39 robots.txt -r-- 1 186 Dec 14 04:39 sitemap.xml dr-x 3 4096 Nov 20 18:22 va/ dr-x 2 4096 Nov 10 04:28 videos/ Typing http://192.168.19.11/ from my Android Phone (IPv4 192.168.19.12) - showed the same as when I went there from the eMachine above. pi@raspberry:~ $ pi@raspberry:~ $ cd /usr/local/www/logs/ pi@raspberry:/usr/local/www/logs $ ls -al total 16 drwxr-xr-x 2 root www 4096 Dec 31 13:26 . drwxr-xr-x 5 root www 4096 Dec 30 15:29 .. -rw-r--r-- 1 nobody nogroup 2380 Dec 31 15:40 thttpd_log -rw-r--r-- 1 nobody nogroup 1459 Dec 31 13:26 thttpd_log.01 pi@raspberry:/usr/local/www/logs $ sudo cp -iv *log.01 2019.12.31 'thttpd_log.01' -> '2019.12.31' The log files show the from address first and sometimes the request address and machine or other information. pi@raspberry:/usr/local/www/logs $ cat *log (This is how to see the running log file.) Tue 31 Dec 2019 01:26:52 PM MST 13:26:52 up 5 min, 2 users, load average: 0.20, 0.48, 0.28 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT pi tty1 - 13:22 5:07 0.32s 0.28s -bash pi tty7 :0 13:22 5:06 5.89s 0.35s /usr/bin/lxsession -s LXDE-pi -e LXDE 192.168.19.11 - - [31/Dec/2019:22:15:08 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 192.168.19.11 - - [31/Dec/2019:22:15:09 +0000] "GET /favicon.ico HTTP/1.1" 200 533 "http://192.168.19.11/" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 192.168.19.11 - - [31/Dec/2019:22:15:40 +0000] "GET /ac0xl/ HTTP/1.1" 200 25000 "http://192.168.19.11/" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 192.168.19.11 - - [31/Dec/2019:22:15:53 +0000] "GET /readme.txt HTTP/1.1" 200 247 "http://192.168.19.11/" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 192.168.19.11 - - [31/Dec/2019:22:15:59 +0000] "GET /robots.txt HTTP/1.1" 200 27 "http://192.168.19.11/" "Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" 192.168.19.12 - - [31/Dec/2019:22:39:45 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (Android 4.4.2; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0" 192.168.19.12 - - [31/Dec/2019:22:39:47 +0000] "GET /favicon.ico HTTP/1.1" 200 533 "" "Mozilla/5.0 (Android 4.4.2; Mobile; rv:68.3.0) Gecko/68.3.0 Firefox/68.3.0" 192.168.19.12 - - [31/Dec/2019:22:39:58 +0000] "GET /ac0xl/ HTTP/1.1" 200 25000 "http://192.168.19.11/" "Mozilla/5.0 (Android 4.4.2; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0" 192.168.19.12 - - [31/Dec/2019:22:40:09 +0000] "GET /favicon.ico HTTP/1.1" 200 533 "http://192.168.19.11/" "Mozilla/5.0 (Android 4.4.2; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0" 192.168.19.12 - - [31/Dec/2019:22:40:20 +0000] "GET /readme.txt HTTP/1.1" 200 247 "http://192.168.19.11/" "Mozilla/5.0 (Android 4.4.2; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0" 192.168.19.12 - - [31/Dec/2019:22:40:28 +0000] "GET /robots.txt HTTP/1.1" 200 27 "http://192.168.19.11/" "Mozilla/5.0 (Android 4.4.2; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0" pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ ls -al total 20 drwxr-xr-x 2 root www 4096 Dec 31 15:45 . drwxr-xr-x 5 root www 4096 Dec 30 15:29 .. -rw-r--r-- 1 root root 1459 Dec 31 15:45 2019.12.31 -rw-r--r-- 1 nobody nogroup 2380 Dec 31 15:40 thttpd_log -rw-r--r-- 1 nobody nogroup 1459 Dec 31 13:26 thttpd_log.01 pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ pi@raspberry:/usr/local/www/logs $ cat 2019.12.31 ::1 - - [30/Dec/2019:23:33:04 +0000] "UNKNOWN UNKNOWN" 400 0 "" "" ::1 - - [30/Dec/2019:23:33:04 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [30/Dec/2019:23:33:05 +0000] "GET /favicon.ico HTTP/1.1" 404 0 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:16:05 +0000] "GET / HTTP/1.1" 200 25000 "" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:16:36 +0000] "GET /favicon.ico HTTP/1.1" 200 533 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:16:54 +0000] "GET /readme.txt HTTP/1.1" 200 247 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:17:14 +0000] "GET /robots.txt HTTP/1.1" 200 27 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" ::1 - - [31/Dec/2019:00:17:23 +0000] "GET /ac0xl/ HTTP/1.1" 200 25000 "http://localhost/" "Mozilla/5.0 (X11; Linux i686; rv:68.0) Gecko/20100101 Firefox/68.0" Tue 31 Dec 2019 01:26:52 PM MST 13:26:52 up 5 min, 2 users, load average: 0.20, 0.48, 0.28 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT pi tty1 - 13:22 5:07 0.32s 0.28s -bash pi tty7 :0 13:22 5:06 5.89s 0.35s /usr/bin/lxsession -s LXDE-pi -e LXDE pi@raspberry:/usr/local/www/logs $ pi@raspberry:/etc $ pi@raspberry:/etc $ less services ... (This file has a list of "Ports" that are in use. The default "HTTP port is 80.") thttpd's default port is 80, port numbers are 16-bit so can range from 1 - 65536. Only one service can use a port number at a time, thus we see that my Raspberry Pi web server will give the same information on all of the IPv4 addresses that are attached to it, i.e., eth0, and wlan0 with its different IP addresses both connected to the same http port 80. In a classroom situation, more than 200 students can be connected to the same "C" class network (192.168.xxx.0/24) and can each connect to each other's web servers, where xxx is the same for all, and the 0 position can very from 2 - 254, with 0 representing the network, 255 is reserved for the broadcast address, and 1 reserved for the router address. With the router set up as a “DHCP Server” all of the computers would receive dynamic IP addresses and all of their http websites would be available in the addresses they were assigned. The http port number (80) is assigned by the computers and the IP addresses are assigned from the router. The router separates the “Local Area Network” (LAN) from the “Wide Area Network” (WAN). Just as the HTTP default address is port 80 and is static, the router has to have the internal IP address for our website “static” so it can pass information back and forth from our internal web server to the external Internet. In the file “2019-10-01-website.txt” I discuss the process of setting the internal web server to a static internal IP address. In the router, under the “Advanced” tab, select “Virtual Server”, and it should display a message similar to: “This page allows you to configure a virtual server, so others can access the server through the Gateway.” This will probably very with different routers so one might have to search a bit to find the similar place. The “usual Service Name” should have a selection of something like “web” or “http” and choose this. It should then show the “Protocol” as “TCP”, “WAN Port” as “80”, and “LAN Open Port” as “80”. In the “LAN IP Address” type in the static internal IP address of your web server, and press, “Apply Changes”. This should fill in a table in “Current Virtual Server Forwarding Table” with “ServerName - WEB”, “Protocol - tcp”, “Local IP Address - 192.168.x.2” i.e., your IP address, “Local Port - 80-80”, “WAN Port - 80-80”, “State - Enable”, and possibly “Action either Delete or Disable”. With this enabled, your website should be available to the WAN. Since your ISP is providing your external IP address, it doesn’t matter if it is dynamic or static. Until you get an idea of the activity that is taking place on the web, it would probably be good just to have a dynamic address if that is what you have. If you are in an area of extreme censorship, it will make the censorship game more of a “Cat and Mouse” game since your site could be bouncing around all sorts of different IP addresses. “Free Speech for the WORLD!” Another reason we use "/home" user directories in the "www" group is to be able to keep all of our original web files there and then just send a copy to the "public_html" directory where it is instantly live. This also reduces the size of our web site by eliminating the bloat of having original files mixed in with our files needed for the web site. It will also reduce the time it will take for the Web Search "spiders" to see what content is available on our sites. When we use "HTML" code for our web pages, the root of the page will be in "index.html" and then the items listed in this file can be in the same directory or in sub directories. If you have a lot of "images" on your web page, you would probably want to put all of them in a sub-directory called, "images" just to keep similar things together and easier to find. To test your "index.html" file, you just open it with a web browser and see if everything is functioning. Then when everything is OK, just move your changes and additions to "public_html" and then open your web browser to "http://xxx.xxx.xxx.xxx/" and see if everything is working. Most web browsers keep a copy of your pages in cache so if the changes don't appear you will have to refresh your web page (usually the little circle with an arrow on it). If the changes still don't appear, possibly you forgot to move the changes to "public_html". Just a reminder, all of the directories in "public_html" need to be "0755" to work and files need to be "0644" to work. If you get to the point of using "cgi" programs they will also need to be "0755" so they can execute, and also need to have the right ending on those files, the documentation for "thttpd" talks about all of this. Links: These links are the easiest and best I have found for sharing the “Good News” I found around my seventh birthday, the Fall of 1955. Frank Anderson, ac0xl. http://4laws.com/laws/languages.html, 4 Spiritual Laws. https://www.cru.org/us/en/train-and-grow/spiritual-growth/the-spirit-filled-life.html, The Spirit Filled Life. https://www.cru.org, Exploring Your Life’s Purpose - Let’s journey together. https://godtoolsapp.com, GodTools - Helping You Share Your Faith. #