├── .screenrc ├── netware-screensaver.spec ├── COPYING ├── .gitignore ├── Makefile ├── netware-worms.c ├── netware-worms.h ├── README ├── README.md └── libnetware-screensaver.c /.screenrc: -------------------------------------------------------------------------------- 1 | blankerprg netware-worms 2 | idle 120 blanker 3 | -------------------------------------------------------------------------------- /netware-screensaver.spec: -------------------------------------------------------------------------------- 1 | %define _build_id_links none 2 | %define debug_package %{nil} 3 | 4 | Summary: Netware SMP Style Screensaver for Linux 5 | License: MIT 6 | Name: netware-screensaver 7 | Version: 1.23 8 | Release: 1%{?dist} 9 | 10 | URL: https://www.github.com/jeffmerkey/netware-screensaver-linux 11 | Source0: %{name}-%{version}.tar.gz 12 | 13 | Requires: ncurses 14 | BuildRequires: ncurses-devel 15 | 16 | %description 17 | The %{name} package contains the Netware SMP screensaver for Linux. 18 | 19 | %prep 20 | %setup -q -n %{name}-%{version} 21 | 22 | %build 23 | %{__make} 24 | 25 | %install 26 | [ -n "%{buildroot}" -a "%{buildroot}" != "/" ] && %{__rm} -rf %{buildroot} 27 | %{__mkdir_p} %{buildroot}%{_sbindir} 28 | %{__mkdir_p} %{buildroot}%{_bindir} 29 | %{__mkdir_p} %{buildroot}%{_includedir} 30 | %{__mkdir_p} %{buildroot}%{_libdir} 31 | %{__make} \ 32 | DESTDIR=%{buildroot} NOCHK=1 LIBDIR=%{_libdir} \ 33 | INCDIR=%{_includedir} BINDIR=%{_bindir} \ 34 | install 35 | 36 | %pre 37 | 38 | %post 39 | %{_sbindir}/ldconfig 40 | %{_sbindir}/ldconfig 41 | 42 | %preun 43 | 44 | %postun 45 | %{_sbindir}/ldconfig 46 | %{_sbindir}/ldconfig 47 | 48 | %files 49 | %defattr(-,root,root) 50 | %{_bindir}/netware-worms 51 | %{_includedir}/netware-worms.h 52 | %{_libdir}/libnetware-screensaver.a 53 | %{_libdir}/libnetware-screensaver.so 54 | 55 | %changelog 56 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright(c) Jeff V. Merkey 1997-2019. All rights reserved. 4 | * 5 | * Portions adapted from xscreensaver loadsnake program is 6 | * portions Copyright (c) 2007-2011 Cosimo Streppone 7 | * 8 | * Licensed under the MIT/X License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files (the "Software"), to 12 | * deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included 18 | * in all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | * 28 | * NetWare SMP style worm screesnsaver for Linux using ncurses 29 | * 30 | * USAGE: netware-worms [cpus|speedup] 31 | * i.e. worm cpus= speedup= 32 | * examples: 33 | * netware-worms cpus=8; 34 | * start worm screensaver with 8 worm threads 35 | * netware-worms speedup=4 36 | * run worm screensaver at 4X speed 37 | * 38 | **************************************************************************/ 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE! Don't add files that are generated in specific 3 | # subdirectories here. Add them in the ".gitignore" file 4 | # in that subdirectory instead. 5 | # 6 | # NOTE! Please use 'git ls-files -i --exclude-standard' 7 | # command after changing this file, to see if there are 8 | # any tracked files which get ignored after the change. 9 | # 10 | # Normal rules (sorted alphabetically) 11 | # 12 | .* 13 | *.a 14 | *.bin 15 | *.bz2 16 | *.c.[012]*.* 17 | *.dtb 18 | *.dtb.S 19 | *.dwo 20 | *.elf 21 | *.gcno 22 | *.gz 23 | *.i 24 | *.ko 25 | *.ll 26 | *.lst 27 | *.lz4 28 | *.lzma 29 | *.lzo 30 | *.mod.c 31 | *.o 32 | *.o.* 33 | *.order 34 | *.patch 35 | *.s 36 | *.so 37 | *.so.dbg 38 | *.su 39 | *.symtypes 40 | *.tar 41 | *.xz 42 | *.pcap 43 | Module.symvers 44 | modules.builtin 45 | 46 | # 47 | # Top-level generic files 48 | # 49 | /tags 50 | /TAGS 51 | /linux 52 | /vmlinux 53 | /vmlinux.32 54 | /vmlinux-gdb.py 55 | /vmlinuz 56 | /System.map 57 | /Module.markers 58 | /netware-worms 59 | 60 | # 61 | # RPM spec file (make rpm-pkg) 62 | # 63 | #/*.spec 64 | 65 | # 66 | # Debian directory (make deb-pkg) 67 | # 68 | /debian/ 69 | 70 | # 71 | # tar directory (make tar*-pkg) 72 | # 73 | /tar-install/ 74 | 75 | # 76 | # git files that we don't want to ignore even if they are dot-files 77 | # 78 | !.gitignore 79 | !.mailmap 80 | !.cocciconfig 81 | 82 | # 83 | # Generated include files 84 | # 85 | include/config 86 | include/generated 87 | arch/*/include/generated 88 | 89 | # stgit generated dirs 90 | patches-* 91 | 92 | # quilt's files 93 | patches 94 | series 95 | 96 | # cscope files 97 | cscope.* 98 | ncscope.* 99 | 100 | # gnu global files 101 | GPATH 102 | GRTAGS 103 | GSYMS 104 | GTAGS 105 | 106 | # id-utils files 107 | ID 108 | 109 | *.orig 110 | *~ 111 | \#*# 112 | 113 | # 114 | # Leavings from module signing 115 | # 116 | extra_certificates 117 | signing_key.pem 118 | signing_key.priv 119 | signing_key.x509 120 | x509.genkey 121 | 122 | # Kconfig presets 123 | all.config 124 | 125 | # Kdevelop4 126 | *.kdev4 127 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #*************************************************************************** 2 | # 3 | # Copyright (c) 1997-2019 Jeffrey Vernon Merkey 4 | # All Rights Reserved. 5 | # 6 | #************************************************************************** 7 | 8 | INCLUDES=netware-worms.h 9 | UTILFILES=libnetware-screensaver.a libnetware-screensaver.so netware-worms 10 | 11 | # user utility build flags 12 | U_CC = gcc 13 | U_CCP = g++ 14 | U_CFLAGSP = -g -O3 15 | U_CFLAGS_LIBP = -g -c -O3 16 | LD = ld 17 | AR = ar 18 | LDCONFIG = ldconfig 19 | LIBS = /usr/lib 20 | INCS = /usr/include 21 | BIN = /usr/bin 22 | 23 | ARCH := $(shell uname -m) 24 | ifeq ($(ARCH), x86_64) 25 | LIBS = /usr/lib64 26 | endif 27 | ifeq ($(ARCH), aarch64) 28 | LIBS = /usr/lib64 29 | endif 30 | ifeq ($(ARCH), i686) 31 | LIBS = /usr/lib 32 | endif 33 | 34 | ifdef LIBDIR 35 | LIBS = $(LIBDIR) 36 | endif 37 | 38 | ifdef INCDIR 39 | INCS = $(INCDIR) 40 | endif 41 | 42 | ifdef BINDIR 43 | BIN = $(BINDIR) 44 | endif 45 | 46 | ifeq ($(NOCHK),1) 47 | LDCONFIG = 48 | endif 49 | 50 | all : utilities 51 | 52 | libnetware-screensaver.so: libnetware-screensaver.o 53 | $(LD) -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 54 | 55 | libnetware-screensaver.a: libnetware-screensaver.o 56 | $(AR) r libnetware-screensaver.a libnetware-screensaver.o 57 | 58 | libnetware-screensaver.o: libnetware-screensaver.c $(INCLUDES) 59 | $(U_CCP) $(U_CFLAGS_LIBP) -fPIC -Wall libnetware-screensaver.c 60 | 61 | netware-worms: netware-worms.c libnetware-screensaver.a $(INCLUDES) 62 | $(U_CCP) $(U_CFLAGSP) netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 63 | 64 | clean: 65 | rm -rf *.o $(UTILFILES) 66 | 67 | utilities: $(UTILFILES) 68 | 69 | install: utilities 70 | install -m 0755 netware-worms $(DESTDIR)$(BIN) 71 | install -m 0755 libnetware-screensaver.so $(DESTDIR)$(LIBS) 72 | install -m 644 libnetware-screensaver.a $(DESTDIR)$(LIBS) 73 | install -m 644 netware-worms.h $(DESTDIR)$(INCS) 74 | $(LDCONFIG) 75 | $(LDCONFIG) 76 | 77 | uninstall: 78 | rm -vf $(DESTDIR)$(BIN)/netware-worms 79 | rm -vf $(DESTDIR)$(LIBS)/libnetware-screensaver.so 80 | rm -vf $(DESTDIR)$(LIBS)/libnetware-screensaver.a 81 | rm -vf $(DESTDIR)$(INCS)/netware-worms.h 82 | $(LDCONFIG) 83 | $(LDCONFIG) 84 | 85 | -------------------------------------------------------------------------------- /netware-worms.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright(c) Jeff V. Merkey 1997-2022. All rights reserved. 4 | * 5 | * Portions adapted from xscreensaver loadsnake program is 6 | * portions Copyright (c) 2007-2011 Cosimo Streppone 7 | * 8 | * Licensed under the MIT/X License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files (the "Software"), to 12 | * deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included 18 | * in all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | * 28 | * NetWare SMP style worm screesnsaver for Linux using ncurses 29 | * 30 | * USAGE: netware-worms [cpus|speedup] 31 | * i.e. worm cpus= speedup= 32 | * examples: 33 | * netware-worms cpus=8; 34 | * start worm screensaver with 8 worm threads 35 | * netware-worms speedup=4 36 | * run worm screensaver at 4X speed 37 | * 38 | **************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include "netware-worms.h" 54 | 55 | int main(int argc, char *argv[]) 56 | { 57 | int i, cpus, speedup, ret; 58 | 59 | for (i=0, cpus=0, speedup=0; i < argc && argv[i]; i++) 60 | { 61 | if (!strcasecmp(argv[i], "help") || !strcasecmp(argv[i], "-h") || 62 | !strcasecmp(argv[i], "-help") || !strcasecmp(argv[i], "--help") || 63 | !strcasecmp(argv[i], "/help") || !strcasecmp(argv[i], "/h")) { 64 | printf("Copyright (c) 1997-2022 Jeff V. Merkey. All Rights Reserved.\n"); 65 | printf("USAGE: netware-worms [cpus|speedup]\n"); 66 | printf(" (i.e. netware-worms cpus= speedup=)\n"); 67 | printf("examples:\n"); 68 | printf(" netware-worms cpus=8\n"); 69 | printf(" start screensaver with 8 worm threads\n"); 70 | printf(" netware-worms speedup=4\n"); 71 | printf(" run screensaver at 4X speed\n"); 72 | exit(0); 73 | } 74 | 75 | if (!strncasecmp(argv[i], "cpus=", 5)) 76 | cpus = atoi(&argv[i][5]); 77 | 78 | if (!strncasecmp(argv[i], "speedup=", 8)) { 79 | if (argv[i][8]) 80 | speedup = atoi(&argv[i][8]); 81 | } 82 | } 83 | ret = netware_screensaver(cpus, speedup); 84 | exit(ret); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /netware-worms.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright(c) Jeff V. Merkey 1997-2022. All rights reserved. 4 | * 5 | * Licensed under the MIT/X License 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to 9 | * deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | * DEALINGS IN THE SOFTWARE. 24 | * 25 | * NetWare SMP style worm screesnsaver for Linux using ncurses 26 | * 27 | * USAGE: netware-worms [cpus|speedup] 28 | * i.e. worm cpus= speedup= 29 | * examples: 30 | * netware-worms cpus=8\n"); 31 | * start worm screensaver with 8 worm threads 32 | * netware-worms speedup=4\n"); 33 | * run worm screensaver at 4X speed 34 | * 35 | **************************************************************************/ 36 | 37 | #define WORM_MIN_LEN 4 38 | #define WORM_MAX_LEN 36 39 | #define WORM_TAIL_LEN 3 40 | #define MAX_WORMS 64 41 | 42 | // adjust worm total length based on screen area size. smaller 43 | // displays have shorter worms. the current logic adjusts for 44 | // worm speedup based on the current max worm length. Here we 45 | // check a min and max screen area for worm length expansion. 46 | 47 | #define AREA_BASE_LEN (WORM_MAX_LEN / 2) 48 | #define AREA_MINLINES 19 49 | #define AREA_MINCOLS 80 50 | #define AREA_MIN (AREA_MINLINES * AREA_MINCOLS) 51 | #define AREA_MAXLINES 64 52 | #define AREA_MAXCOLS 160 53 | #define AREA_MAX (AREA_MAXLINES * AREA_MAXCOLS) 54 | #define AREA ((COLS * LINES) < (AREA_MINLINES * AREA_MINCOLS) \ 55 | ? (AREA_MINLINES * AREA_MINCOLS) : (COLS * LINES)) 56 | #define AREA_DIVISOR ((AREA_MAX - AREA_MIN) / AREA_BASE_LEN) 57 | #define AREA_EXT_LEN (((AREA - (AREA_MIN)) / (AREA_DIVISOR)) > \ 58 | AREA_BASE_LEN ? AREA_BASE_LEN : \ 59 | ((AREA - (AREA_MIN)) / (AREA_DIVISOR))) 60 | 61 | #define MAX_LOADAVG 100 62 | #define MAX_NANOSEC 100000000 63 | #define MIN_NANOSEC 10000000 64 | #define MAX_MICROSEC 100000 65 | #define MIN_MICROSEC 10000 66 | 67 | typedef struct _WORM 68 | { 69 | int cpu; 70 | int count; 71 | int limit; 72 | int x[WORM_MAX_LEN]; 73 | int y[WORM_MAX_LEN]; 74 | int x_prev[WORM_MAX_LEN]; 75 | int y_prev[WORM_MAX_LEN]; 76 | int length; 77 | int length_prev; 78 | int direction; 79 | int runlength; 80 | int windowlength; 81 | } WORM; 82 | 83 | typedef struct _STATE 84 | { 85 | int cpus; 86 | int delay; 87 | int divisor; 88 | int rows; 89 | int cols; 90 | unsigned long long usr[MAX_WORMS]; 91 | unsigned long long sys[MAX_WORMS]; 92 | unsigned long long nice[MAX_WORMS]; 93 | unsigned long long idle[MAX_WORMS]; 94 | unsigned long long io[MAX_WORMS]; 95 | unsigned long long irq[MAX_WORMS]; 96 | unsigned long long sirq[MAX_WORMS]; 97 | unsigned long long steal[MAX_WORMS]; 98 | unsigned long long guest[MAX_WORMS]; 99 | unsigned long long guest_nice[MAX_WORMS]; 100 | WORM *worms; 101 | } STATE; 102 | 103 | int netware_screensaver(int cpus, int speedup); 104 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | 3 | NETWARE-SCREENSAVER-LINUX 4 | 5 | 6 | NetWare SMP style worm screensaver for Linux using ncurses 7 | 8 | 9 | Table of Contents 10 | 11 | - Overview 12 | - Quick Start Guide 13 | - Building the Screensaver from Source 14 | - Installing and Uninstalling the Screensaver from Source 15 | - Running the Screensaver 16 | - Installing the Screensaver in the Bash Shell 17 | - ssh client returns “unknown terminal type” when remotely logging 18 | into the system 19 | - Using Libraries 20 | - Building the Screensaver as an RPM Package (Redhat/CentOS/SuSe) 21 | - Building the Screensaver as a Debian Package (Debian/Ubuntu) 22 | - Issues / Problems / Help 23 | 24 | 25 | Overview 26 | 27 | This code is Copyright(c) Jeff V. Merkey 1997-2022 and some portions 28 | were adapted from xscreensaver loadsnake program and those portions are 29 | Copyright (c) 2007-2011 Cosimo Streppone cosimo@cpan.org. 30 | 31 | This software is licensed under the MIT/X License. 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining a 34 | copy of this software and associated documentation files (the 35 | “Software”), to deal in the Software without restriction, including 36 | without limitation the rights to use, copy, modify, merge, publish, 37 | distribute, sublicense, and/or sell copies of the Software, and to 38 | permit persons to whom the Software is furnished to do so, subject to 39 | the following conditions: 40 | 41 | The above copyright notice and this permission notice shall be included 42 | in all copies or substantial portions of the Software. 43 | 44 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS 45 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 46 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 47 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 48 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 49 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 50 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 51 | 52 | USAGE: netware-worms [cpus|speedup] 53 | i.e. worm cpus= speedup= 54 | examples: 55 | netware-worms cpus=8; 56 | start worm screensaver with 8 worm threads 57 | netware-worms speedup=4 58 | run worm screensaver at 4X speed 59 | 60 | This screensaver is built as both a dynamic shared object (*.so) and 61 | static archive (*.a) library module which allows other user space 62 | programs and consoles to invoke this screen saver as well as tmux, 63 | screen, and other BASH type programs setups. 64 | 65 | This screensaver uses ncurses and is text based which is identical to 66 | the Novell Netware SMP multi processor screensaver which displayed a 67 | color coded worm for each processor running. As each processor load 68 | increases on a particular processor, the longer the worm becomes and the 69 | faster it moves across the screen corresponding to that particular 70 | processor. As the overall system load average across the system 71 | increases, the base clock rate for all the worms increases slightly to 72 | indicate load average is increasing. 73 | 74 | 75 | Quick Start Guide 76 | 77 | You can download precompiled RPM packages and Debian (DEB) packages from 78 | the release page for this project, or you can build the program from the 79 | git sources. 80 | 81 | If you want to build the program from scratch with the git sources 82 | rather than use the pre-compiled RPMS and DEB packages, then please skip 83 | to the section Building the Screensaver from Source for instructions on 84 | how to do this. 85 | 86 | Packages are provided in binary and source versions, and can be 87 | downloaded and installed directly or rebuilt for a different target 88 | architecture such as ARM64. Package types are Red Hat Package Manager 89 | (RPM) packages and Debian (DEB) packages for binary installation and 90 | Source RPM packages (SRPMS) and Debbuild SDEB packages for source code 91 | installation. 92 | 93 | RPM and DEB packages for each release include a binary architecture 94 | specific package and a source package which can be downloaded and 95 | built/rebuilt and which contains the source code. 96 | 97 | For example, the release v1.21 contains the following packages in the 98 | release section: 99 | 100 | RPM BASED PACKAGES (REDHAT, CENTOS, SUSE) 101 | 102 | - netware-screensaver-1.21-1.el8.src.rpm 103 | - netware-screensaver-1.21-1.el8.x86_64.rpm 104 | 105 | DEBIAN BASED PACKAGES (DEBIAN, UBUNTU) 106 | 107 | - netware-screensaver-1.21-1.sdeb 108 | - netware-screensaver_1.21-1_amd64.deb 109 | 110 | INSTALLING BINARY PACKAGES 111 | 112 | To install the binary package with the rpm package manager for x86_64: 113 | 114 | rpm -i netware-screensaver-1.21-1.el8.x86_64.rpm 115 | 116 | To deinstall the RPM binary package: 117 | 118 | rpm -e netware-screensaver 119 | 120 | To install the binary package with the Debian dpkg package manager for 121 | amd64: 122 | 123 | dpkg -i netware-screensaver_1.21-1_amd64.deb 124 | 125 | To deinstall the Debian dpkg binary package: 126 | 127 | dpkg -r netware-screensaver 128 | 129 | INSTALLING SOURCE PACKAGES 130 | 131 | To install the source package with the rpm package manager: 132 | 133 | rpm -i netware-screensaver-1.21-1.el8.src.rpm 134 | 135 | _(Note: rpm installs the source code files in /root/rpmbuild/ as top 136 | directory for RedHat and CentOS platforms. SuSe platforms install the 137 | source code files in /usr/src/packages/)_ 138 | 139 | To install the source package with the Debbuild package tool: 140 | 141 | debbuild -i netware-screensaver-1.21-1.sdeb 142 | 143 | _(Note: Debbuild installs the source code files in /root/debbuild/ as 144 | top directory)_ 145 | 146 | For building or rebuilding RPMS or DEB Packages after you have installed 147 | the associated source packages on your platform, refer to the following: 148 | 149 | - Building the Screensaver as an RPM Package (Redhat/CentOS/SuSe) 150 | - Building the Screensaver as a Debian Package (Debian/Ubuntu) 151 | 152 | 153 | Building the Screensaver from Source 154 | 155 | You must have the ncurses-devel packages installed in order to make 156 | ncurses apps on your system. you can try “dnf install ncurses\*” to get 157 | all of the ncurses packages for RedHat and CentOS systems. This version 158 | was developed on a Red Hat 7 / CentOS 7 system. 159 | 160 | to make, type: 161 | 162 | make -f Makefile 163 | 164 | the build process should display: 165 | 166 | g++ -g -c -O3 -fPIC -Wall libnetware-screensaver.c 167 | ar r libnetware-screensaver.a libnetware-screensaver.o 168 | ar: creating libnetware-screensaver.a 169 | ld -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 170 | g++ -g -O3 netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 171 | 172 | to perform a clean build: 173 | 174 | make -f Makefile clean 175 | 176 | should display: 177 | 178 | rm -rf *.o libnetware-screensaver.a libnetware-screensaver.so netware-worms 179 | 180 | 181 | Installing and Uninstalling the Screensaver from Source 182 | 183 | To install: 184 | 185 | make -f Makefile install 186 | 187 | should display: 188 | 189 | install -m 0755 netware-worms /usr/bin 190 | install -m 0755 libnetware-screensaver.so /usr/lib64 191 | install -m 644 libnetware-screensaver.a /usr/lib64 192 | install -m 644 netware-worms.h /usr/include 193 | ldconfig 194 | ldconfig 195 | 196 | To uninstall: 197 | 198 | make -f Makefile uninstall 199 | 200 | should display: 201 | 202 | rm -vf /usr/bin/netware-worms 203 | removed '/usr/bin/netware-worms' 204 | rm -vf /usr/lib64/libnetware-screensaver.so 205 | removed '/usr/lib64/libnetware-screensaver.so' 206 | rm -vf /usr/lib64/libnetware-screensaver.a 207 | removed '/usr/lib64/libnetware-screensaver.a' 208 | rm -vf /usr/include/netware-worms.h 209 | removed '/usr/include/netware-worms.h' 210 | ldconfig 211 | ldconfig 212 | 213 | 214 | Running the Screensaver 215 | 216 | you can execute the program directly as: 217 | 218 | ./netware-worms 219 | 220 | you can also add arguments to force number of cpus and a speedup divisor 221 | 222 | ./netware-worms cpus=8 speedup=4 223 | 224 | 225 | Installing the Screensaver in the Bash Shell 226 | 227 | To install the screensaver as a bash program which auto activates, use 228 | the program called “screen” coupled with Bash. The “screen” program has 229 | support for adding and invoking terminal based screensavers under Bash. 230 | 231 | You can install the program on CentOS and RHEL with dnf by typing “dnf 232 | install screen” if the program is not installed by default. On Debian 233 | based systems you can install the program with “apt-get install screen”. 234 | 235 | Red Hat based systems can use yum or dnf to install the screen files: 236 | 237 | dnf install screen 238 | 239 | Debian based systems can use apt or apt-get to install the screen files: 240 | 241 | apt-get install screen 242 | 243 | You should also install at the same time the terminfo and termcap files 244 | to support the “screen” terminal type for ncurses to avoid getting 245 | “unknown terminal type” errors when attempting to log into the system 246 | over ssh. 247 | 248 | Red Hat based systems can use yum or dnf to install the terminfo files: 249 | 250 | dnf install ncurses-term 251 | 252 | Debian based systems can use apt or apt-get to install the terminfo 253 | files: 254 | 255 | apt-get install ncurses-term 256 | 257 | You will need to create a .screenrc file in the user home directory 258 | (i.e. ~/.screenrc) which contains the following commands: 259 | 260 | SAMPLE ~/.SCREENRC FILE 261 | 262 | blankerprg netware-worms 263 | idle 60 blanker 264 | 265 | Please note the idle command which specifies how many seconds to delay 266 | before invoking the screensaver (in this example it is 60 seconds) 267 | 268 | You also need to modify the ~/.bash_profile default bash configuation 269 | file to invoke screen by default after login. Add the /bin/screen 270 | command to the end of the ~/.bash_profile config file: 271 | 272 | SAMPLE ~/.BASH_PROFILE 273 | 274 | # .bash_profile 275 | # Get the aliases and functions 276 | if [ -f ~/.bashrc ]; then 277 | . ~/.bashrc 278 | fi 279 | # User specific environment and startup programs 280 | PATH=$PATH:$HOME/bin 281 | export PATH 282 | /bin/screen 283 | 284 | It must be the last line in the file since following login, the 285 | /bin/screen program will be executed and run as a transparent bash 286 | shell. 287 | 288 | After you have configured these two files, logout and log back into the 289 | system for whichever account you have enabled and the screensaver will 290 | auto-activate after 60 seconds of idle time. The only disadvantage to 291 | using this method to enable a terminal based screensaver is you will 292 | need to type the “exit” command twice in order to logout of the session. 293 | 294 | 295 | ssh client returns unknown terminal type when remotely logging into the system 296 | 297 | Some older CentOS and Red Hat Enterprise Linux distributions do not 298 | properly detect or parse aliased terminal types such as 299 | “screen.xterm-256color” when using ssh to remotely access a system that 300 | has screen installed and running. This results in an “unknown terminal 301 | type” error being returned after logging in. This error can be fixed by 302 | changing the ~/.bashrc file for the affected account and add a check for 303 | the term type, then export a terminal type that matches one of the 304 | supported terminal types in the ncurses-term package. 305 | 306 | Add the following to the bottom of the .bashrc file to check the 307 | terminal type, then change and export it if necessary. 308 | 309 | if [[ "$TERM" == "screen.xterm-256color" ]]; then 310 | export TERM=screen-256color 311 | fi 312 | 313 | The “screen.xterm-256color” terminal type is the most common terminal 314 | type seen when this ssh error occurs and it is caused by the ncurses 315 | library terminfo and termcap files either not being installed or 316 | improperly configured. 317 | 318 | If you encounter this error and are running on version CentOS/RHEL 7 or 319 | earlier, then edit your .bashrc file to append the terminal type and 320 | remap check as shown in the example below: 321 | 322 | SAMPLE ~/.BASHRC 323 | 324 | # .bashrc 325 | # User specific aliases and functions 326 | 327 | alias rm='rm -i' 328 | alias cp='cp -i' 329 | alias mv='mv -i' 330 | 331 | # Source global definitions 332 | if [ -f /etc/bashrc ]; then 333 | . /etc/bashrc 334 | fi 335 | 336 | # add the following 3 lines to the end of the .bashrc file 337 | if [[ "$TERM" == "screen.xterm-256color" ]]; then 338 | export TERM=screen-256color 339 | fi 340 | 341 | 342 | Using Libraries 343 | 344 | You can also call the screensaver as a library function 345 | “netware_screensaver(cpus, speedup)” from another application with your 346 | own timer setup, just be sure to link to the “-lnetware-screensaver” .so 347 | library in your linker statements or link to the static library 348 | “libnetware-screensaver.a” 349 | 350 | 351 | Building as an RPM Package 352 | 353 | In order to build the screensaver as an RPM, the program must be 354 | compressed into a tar.gz file and the tar.gz file named to match the 355 | versioning information contained in the associated .spec file. 356 | 357 | Spec files are special files which contain instructions on how to build 358 | a particular package from a source code archive. On Red Hat and CentOS 359 | systems, RPMS are built in the /root/rpmbuild/ top directory. SuSe 360 | systems build RPMS in the /usr/src/packages/ as top directory. These 361 | “top directories” will contain BUILD, BUILDROOT, SPECS, RPMS, SRPMS, and 362 | SOURCES subdirectories. 363 | 364 | The SPECS directory contains the *.spec files used to build RPMS and 365 | SRPMS packages. The SOURCES subdirectory will contain the soure code 366 | archive file referred to in the *.spec file used to build the RPM 367 | package. 368 | 369 | See the Quick Start Guide on instructions for installing the source rpm 370 | which installs both the .spec file and source archive file (tar.gz) into 371 | the rpm build top directory (i.e. /root/rpmbuild/). You should have 372 | previously installed the src.rpm file before attempting to build the 373 | rpm. You can also manually install the .spec file into the /SPECS/ directory and the source code tarball in the 382 | 383 | The program should output the following if the build is successful and 384 | verify that the program wrote both the RPMS and SRPMS packages: 385 | 386 | Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.oqGyza 387 | + umask 022 388 | + cd /root/rpmbuild/BUILD 389 | + cd /root/rpmbuild/BUILD 390 | + rm -rf netware-screensaver-1.21 391 | + /usr/bin/gzip -dc /root/rpmbuild/SOURCES/netware-screensaver-1.21.tar.gz 392 | + /usr/bin/tar -xof - 393 | + STATUS=0 394 | + '[' 0 -ne 0 ']' 395 | + cd netware-screensaver-1.21 396 | + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . 397 | + exit 0 398 | Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.JTscEj 399 | + umask 022 400 | + cd /root/rpmbuild/BUILD 401 | + cd netware-screensaver-1.21 402 | + /usr/bin/make 403 | g++ -g -c -O3 -fPIC -Wall libnetware-screensaver.c 404 | ar r libnetware-screensaver.a libnetware-screensaver.o 405 | ar: creating libnetware-screensaver.a 406 | ld -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 407 | g++ -g -O3 netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 408 | + exit 0 409 | Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.GtWplM 410 | + umask 022 411 | + cd /root/rpmbuild/BUILD 412 | + '[' /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 '!=' / ']' 413 | + rm -rf /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 414 | ++ dirname /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 415 | + mkdir -p /root/rpmbuild/BUILDROOT 416 | + mkdir /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 417 | + cd netware-screensaver-1.21 418 | + '[' -n /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 -a /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 '!=' / ']' 419 | + /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 420 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/sbin 421 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/bin 422 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/include 423 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/lib64 424 | + /usr/bin/make DESTDIR=/root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 NOCHK=1 LIBDIR=/usr/lib64 INCDIR=/usr/include BINDIR=/usr/bin install 425 | install -m 0755 netware-worms /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/bin 426 | install -m 0755 libnetware-screensaver.so /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/lib64 427 | install -m 644 libnetware-screensaver.a /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/lib64 428 | install -m 644 netware-worms.h /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/include 429 | + /usr/lib/rpm/check-buildroot 430 | + /usr/lib/rpm/redhat/brp-ldconfig 431 | /sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory 432 | + /usr/lib/rpm/brp-compress 433 | + /usr/lib/rpm/brp-strip /usr/bin/strip 434 | + /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump 435 | + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip 436 | + /usr/lib/rpm/brp-python-bytecompile '' 1 437 | + /usr/lib/rpm/brp-python-hardlink 438 | + PYTHON3=/usr/libexec/platform-python 439 | + /usr/lib/rpm/redhat/brp-mangle-shebangs 440 | Processing files: netware-screensaver-1.21-1.el8.x86_64 441 | Provides: libnetware-screensaver.so()(64bit) netware-screensaver = 1.21-1.el8 netware-screensaver(x86-64) = 1.21-1.el8 442 | Requires(interp): /bin/sh /bin/sh /bin/sh /bin/sh 443 | Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 444 | Requires(pre): /bin/sh 445 | Requires(post): /bin/sh 446 | Requires(preun): /bin/sh 447 | Requires(postun): /bin/sh 448 | Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libm.so.6()(64bit) libncursesw.so.6()(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libstdc++.so.6()(64bit) libtinfo.so.6()(64bit) rtld(GNU_HASH) 449 | Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 450 | Wrote: /root/rpmbuild/SRPMS/netware-screensaver-1.21-1.el8.src.rpm 451 | Wrote: /root/rpmbuild/RPMS/x86_64/netware-screensaver-1.21-1.el8.x86_64.rpm 452 | Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.PbtDr4 453 | + umask 022 454 | + cd /root/rpmbuild/BUILD 455 | + cd netware-screensaver-1.21 456 | + /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 457 | + exit 0 458 | 459 | 460 | Building as a Debian Package 461 | 462 | In order to build the screensaver as a Debian package, the program must 463 | be compressed into a tar.gz file and the tar.gz file named to match the 464 | versioning information contained in the associated .spec file. Spec 465 | files are special files which contain instructions on how to build a 466 | particular package from a source code archive. 467 | 468 | Debian Packages can be built using a utility called “debbuild” and use a 469 | top directory structure which is similar to that used by the RPM tool 470 | but using /root/debbuild/ as the “top directory”. These “top 471 | directories” will contain BUILD, BUILDROOT, SPECS, DEBS, SDEBS, and 472 | SOURCES subdirectories and follows a similar layout that is used for RPM 473 | files. 474 | 475 | The SPECS directory contains the *.spec files used to build DEB and SDEB 476 | packages. The SOURCES subdirectory will contain the soure code archive 477 | file referred to in the *.spec file used to build the DEB and SDEB 478 | packages. 479 | 480 | See the Quick Start Guide on instructions for installing the source SDEB 481 | which installs both the .spec file and source archive file (tar.gz) into 482 | the debbuild top directory (i.e. /root/debbuild/). You should have 483 | previously installed the SDEB file before attempting to build the DEB 484 | package. You can also manually install the .spec file into the /SPECS/ directory and the source code tarball in the 492 | 493 | The program should output the following if the build is successful and 494 | verify that the program wrote both the DEB and SDEB packages: 495 | 496 | This is debbuild, version 22.02.1\ndebconfigdir:/usr/lib/debbuild\nsysconfdir:/etc\n 497 | Lua: No Lua module loaded 498 | Executing (%prep): /bin/sh -e /var/tmp/deb-tmp.prep.20277 499 | + umask 022 500 | + cd /root/debbuild/BUILD 501 | + /bin/rm -rf netware-screensaver-1.21 502 | + /bin/gzip -dc /root/debbuild/SOURCES/netware-screensaver-1.21.tar.gz 503 | + /bin/tar -xf - 504 | + STATUS=0 505 | + '[' 0 -ne 0 ']' 506 | + cd netware-screensaver-1.21 507 | + /bin/chmod -Rf a+rX,u+w,go-w . 508 | + exit 0 509 | Executing (%build): /bin/sh -e /var/tmp/deb-tmp.build.33585 510 | + umask 022 511 | + cd /root/debbuild/BUILD 512 | + cd netware-screensaver-1.21 513 | + /usr/bin/make 514 | g++ -g -c -O3 -fPIC -Wall libnetware-screensaver.c 515 | ar r libnetware-screensaver.a libnetware-screensaver.o 516 | ar: creating libnetware-screensaver.a 517 | ld -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 518 | g++ -g -O3 netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 519 | + exit 0 520 | Executing (%install): /bin/sh -e /var/tmp/deb-tmp.install.73931 521 | + umask 022 522 | + cd /root/debbuild/BUILD 523 | + cd netware-screensaver-1.21 524 | + '[' -n /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 -a /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 '!=' / ']' 525 | + /bin/rm -rf /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 526 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/sbin 527 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/bin 528 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/include 529 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/lib/x86_64-linux-gnu 530 | + /usr/bin/make DESTDIR=/root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 NOCHK=1 LIBDIR=/usr/lib/x86_64-linux-gnu INCDIR=/usr/include BINDIR=/usr/bin install 531 | install -m 0755 netware-worms /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/bin 532 | install -m 0755 libnetware-screensaver.so /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/lib/x86_64-linux-gnu 533 | install -m 644 libnetware-screensaver.a /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/lib/x86_64-linux-gnu 534 | install -m 644 netware-worms.h /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/include 535 | + exit 0 536 | Checking library requirements... 537 | dpkg-query: no path found matching pattern /lib64/libncursesw.so.6 538 | dpkg-query: no path found matching pattern /lib64/libtinfo.so.6 539 | dpkg-query: no path found matching pattern /lib64/libpthread.so.0 540 | dpkg-query: no path found matching pattern /lib64/libstdc++.so.6 541 | dpkg-query: no path found matching pattern /lib64/libm.so.6 542 | dpkg-query: no path found matching pattern /lib64/libgcc_s.so.1 543 | dpkg-query: no path found matching pattern /lib64/libc.so.6 544 | dpkg-query: no path found matching pattern /lib64/libdl.so.2 545 | dpkg-query: no path found matching pattern /lib64/libc.so.6 546 | Executing (package-creation): /bin/sh -e /var/tmp/deb-tmp.pkg.37356 for netware-screensaver 547 | + umask 022 548 | + cd /root/debbuild/BUILD 549 | + /usr/bin/fakeroot -- /usr/bin/dpkg-deb -b /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/main /root/debbuild/DEBS/amd64/netware-screensaver_1.21-1_amd64.deb 550 | dpkg-deb: warning: parsing file '/root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/main/DEBIAN/control' near line 10 package 'netware-screensaver': 551 | missing 'Maintainer' field 552 | dpkg-deb: warning: ignoring 1 warning about the control file(s) 553 | dpkg-deb: building package 'netware-screensaver' in '/root/debbuild/DEBS/amd64/netware-screensaver_1.21-1_amd64.deb'. 554 | + exit 0 555 | Executing (%clean): /bin/sh -e /var/tmp/deb-tmp.clean.95144 556 | + umask 022 557 | + cd /root/debbuild/BUILD 558 | + '[' /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 '!=' / ']' 559 | + /bin/rm -rf /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 560 | + exit 0 561 | Wrote source package netware-screensaver-1.21-1.sdeb in /root/debbuild/SDEBS. 562 | Wrote binary package netware-screensaver_1.21-1_amd64.deb in /root/debbuild/DEBS/amd64 563 | 564 | 565 | Issues / problems / help 566 | 567 | If you have any issues, please log them at 568 | https://github.com/jeffmerkey/netware-screensaver-linux/issues 569 | 570 | If you have any suggestions for improvements then pull requests are 571 | welcomed, or raise an issue. 572 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # netware-screensaver-linux 3 | 4 | NetWare SMP style worm screensaver for Linux using ncurses 5 | 6 | ## Table of Contents 7 | - [Overview](#overview) 8 | - [Quick Start Guide](#quick-start-guide) 9 | - [Building the Screensaver from Source](#building-the-screensaver-from-source) 10 | - [Installing and Uninstalling the Screensaver from Source](#installing-and-uninstalling-the-screensaver-from-source) 11 | - [Running the Screensaver](#running-the-screensaver) 12 | - [Installing the Screensaver in the Bash Shell](#installing-the-screensaver-in-the-bash-shell) 13 | - [ssh client returns "unknown terminal type" when remotely logging into the system](#ssh-client-returns-unknown-terminal-type-when-remotely-logging-into-the-system) 14 | - [Using Libraries](#using-libraries) 15 | - [Building the Screensaver as an RPM Package (Redhat/CentOS/SuSe)](#building-as-an-rpm-package) 16 | - [Building the Screensaver as a Debian Package (Debian/Ubuntu)](#building-as-a-debian-package) 17 | - [Issues / Problems / Help](#issues--problems--help) 18 | 19 | ## Overview 20 | 21 | This code is Copyright(c) Jeff V. Merkey 1997-2022 and some portions were adapted from xscreensaver loadsnake program and those portions are Copyright (c) 2007-2011 Cosimo Streppone . 22 | 23 | This software is licensed under the MIT/X License. 24 | 25 | Permission is hereby granted, free of charge, to any person obtaining a copy 26 | of this software and associated documentation files (the "Software"), to 27 | deal in the Software without restriction, including without limitation 28 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 29 | and/or sell copies of the Software, and to permit persons to whom the 30 | Software is furnished to do so, subject to the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be included 33 | in all copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 40 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 41 | DEALINGS IN THE SOFTWARE. 42 | 43 | ```sh 44 | USAGE: netware-worms [cpus|speedup] 45 | i.e. worm cpus= speedup= 46 | examples: 47 | netware-worms cpus=8; 48 | start worm screensaver with 8 worm threads 49 | netware-worms speedup=4 50 | run worm screensaver at 4X speed 51 | ``` 52 | 53 | This screensaver is built as both a dynamic shared object (\*.so) and static 54 | archive (\*.a) library module which allows other user space programs and 55 | consoles to invoke this screen saver as well as tmux, screen, and other 56 | BASH type programs setups. 57 | 58 | This screensaver uses ncurses and is text based which is identical 59 | to the Novell Netware SMP multi processor screensaver which displayed 60 | a color coded worm for each processor running. As each processor load 61 | increases on a particular processor, the longer the worm becomes and 62 | the faster it moves across the screen corresponding to that particular 63 | processor. As the overall system load average across the system increases, 64 | the base clock rate for all the worms increases slightly to indicate 65 | load average is increasing. 66 | 67 | ## Quick Start Guide 68 | 69 | You can download precompiled RPM packages and Debian (DEB) packages from 70 | the [release page](https://github.com/jeffmerkey/netware-screensaver-linux/releases) for 71 | this project, or you can build the program from the git sources. 72 | 73 | If you want to build the program from scratch with the git sources rather than use the pre-compiled RPMS and DEB packages, then please skip to the section [Building the Screensaver from Source](#building-the-screensaver-from-source) for instructions on how to do this. 74 | 75 | Packages are provided in binary and source versions, and can be downloaded and 76 | installed directly or rebuilt for a different target architecture such as ARM64. Package types are 77 | Red Hat Package Manager (RPM) packages and Debian (DEB) packages for binary installation and 78 | Source RPM packages (SRPMS) and Debbuild SDEB packages for source code installation. 79 | 80 | RPM and DEB packages for each release include a binary architecture specific package 81 | and a source package which can be downloaded and built/rebuilt and which contains the source code. 82 | 83 | For example, the release v1.21 contains the following packages in the release section: 84 | 85 | ### **RPM Based Packages (RedHat, CentOS, SuSe)** 86 | 87 | - [netware-screensaver-1.21-1.el8.src.rpm](https://github.com/jeffmerkey/netware-screensaver-linux/releases/download/v1.21/netware-screensaver-1.21-1.el8.src.rpm) 88 | - [netware-screensaver-1.21-1.el8.x86_64.rpm](https://github.com/jeffmerkey/netware-screensaver-linux/releases/download/v1.21/netware-screensaver-1.21-1.el8.x86_64.rpm) 89 | 90 | ### **Debian Based Packages (Debian, Ubuntu)** 91 | 92 | - [netware-screensaver-1.21-1.sdeb](https://github.com/jeffmerkey/netware-screensaver-linux/releases/download/v1.21/netware-screensaver-1.21-1.sdeb) 93 | - [netware-screensaver_1.21-1_amd64.deb](https://github.com/jeffmerkey/netware-screensaver-linux/releases/download/v1.21/netware-screensaver_1.21-1_amd64.deb) 94 | 95 | ### **Installing Binary Packages** 96 | 97 | To install the binary package with the rpm package manager for x86_64: 98 | ```sh 99 | rpm -i netware-screensaver-1.21-1.el8.x86_64.rpm 100 | ``` 101 | 102 | To deinstall the RPM binary package: 103 | ```sh 104 | rpm -e netware-screensaver 105 | ``` 106 | 107 | To install the binary package with the Debian dpkg package manager for amd64: 108 | ```sh 109 | dpkg -i netware-screensaver_1.21-1_amd64.deb 110 | ``` 111 | 112 | To deinstall the Debian dpkg binary package: 113 | ```sh 114 | dpkg -r netware-screensaver 115 | ``` 116 | 117 | 118 | ### **Installing Source Packages** 119 | 120 | To install the source package with the rpm package manager: 121 | ```sh 122 | rpm -i netware-screensaver-1.21-1.el8.src.rpm 123 | ``` 124 | *(Note: rpm installs the source code files in /root/rpmbuild/ as top directory for RedHat and CentOS 125 | platforms. SuSe platforms install the source code files in /usr/src/packages/)* 126 | 127 | To install the source package with the Debbuild package tool: 128 | ```sh 129 | debbuild -i netware-screensaver-1.21-1.sdeb 130 | ``` 131 | *(Note: Debbuild installs the source code files in /root/debbuild/ as top directory)* 132 | 133 | For building or rebuilding RPMS or DEB Packages after you have installed the associated source packages on your platform, refer to the following: 134 | 135 | - [Building the Screensaver as an RPM Package (Redhat/CentOS/SuSe)](#building-as-an-rpm-package) 136 | - [Building the Screensaver as a Debian Package (Debian/Ubuntu)](#building-as-a-debian-package) 137 | 138 | ## Building the Screensaver from Source 139 | 140 | You must have the ncurses-devel packages installed in order to make 141 | ncurses apps on your system. you can try "dnf install ncurses\\\*" to get 142 | all of the ncurses packages for RedHat and CentOS systems. This version 143 | was developed on a Red Hat 7 / CentOS 7 system. 144 | 145 | to make, type: 146 | ```sh 147 | make -f Makefile 148 | ``` 149 | 150 | the build process should display: 151 | ```sh 152 | g++ -g -c -O3 -fPIC -Wall libnetware-screensaver.c 153 | ar r libnetware-screensaver.a libnetware-screensaver.o 154 | ar: creating libnetware-screensaver.a 155 | ld -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 156 | g++ -g -O3 netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 157 | ``` 158 | 159 | to perform a clean build: 160 | ```sh 161 | make -f Makefile clean 162 | ``` 163 | 164 | should display: 165 | ```sh 166 | rm -rf *.o libnetware-screensaver.a libnetware-screensaver.so netware-worms 167 | ``` 168 | 169 | ## Installing and Uninstalling the Screensaver from Source 170 | 171 | To install: 172 | ```sh 173 | make -f Makefile install 174 | ``` 175 | 176 | should display: 177 | ```sh 178 | install -m 0755 netware-worms /usr/bin 179 | install -m 0755 libnetware-screensaver.so /usr/lib64 180 | install -m 644 libnetware-screensaver.a /usr/lib64 181 | install -m 644 netware-worms.h /usr/include 182 | ldconfig 183 | ldconfig 184 | ``` 185 | 186 | To uninstall: 187 | ```sh 188 | make -f Makefile uninstall 189 | ``` 190 | 191 | should display: 192 | ```sh 193 | rm -vf /usr/bin/netware-worms 194 | removed '/usr/bin/netware-worms' 195 | rm -vf /usr/lib64/libnetware-screensaver.so 196 | removed '/usr/lib64/libnetware-screensaver.so' 197 | rm -vf /usr/lib64/libnetware-screensaver.a 198 | removed '/usr/lib64/libnetware-screensaver.a' 199 | rm -vf /usr/include/netware-worms.h 200 | removed '/usr/include/netware-worms.h' 201 | ldconfig 202 | ldconfig 203 | ``` 204 | 205 | ## Running the Screensaver 206 | 207 | you can execute the program directly as: 208 | ```sh 209 | ./netware-worms 210 | ``` 211 | you can also add arguments to force number of cpus and a speedup divisor 212 | ```sh 213 | ./netware-worms cpus=8 speedup=4 214 | ``` 215 | 216 | ## Installing the Screensaver in the Bash Shell 217 | 218 | To install the screensaver as a bash program which auto activates, use the program called 219 | "screen" coupled with Bash. The "screen" program has support for adding and invoking 220 | terminal based screensavers under Bash. 221 | 222 | You can install the program on CentOS and RHEL with dnf by typing "dnf install screen" 223 | if the program is not installed by default. On Debian based systems you can install 224 | the program with "apt-get install screen". 225 | 226 | Red Hat based systems can use yum or dnf to install the screen files: 227 | ```sh 228 | dnf install screen 229 | ``` 230 | Debian based systems can use apt or apt-get to install the screen files: 231 | ```sh 232 | apt-get install screen 233 | ``` 234 | 235 | You should also install at the same time the terminfo and termcap files to support the "screen" 236 | terminal type for ncurses to avoid getting "unknown terminal type" errors when attempting to 237 | log into the system over ssh. 238 | 239 | Red Hat based systems can use yum or dnf to install the terminfo files: 240 | ```sh 241 | dnf install ncurses-term 242 | ``` 243 | Debian based systems can use apt or apt-get to install the terminfo files: 244 | ```sh 245 | apt-get install ncurses-term 246 | ``` 247 | 248 | You will need to create a .screenrc file in the user home directory (i.e. ~/.screenrc) 249 | which contains the following commands: 250 | 251 | **sample ~/.screenrc file** 252 | ```sh 253 | blankerprg netware-worms 254 | idle 60 blanker 255 | ``` 256 | 257 | Please note the idle command which specifies how many seconds to delay before invoking 258 | the screensaver (in this example it is 60 seconds) 259 | 260 | You also need to modify the ~/.bash\_profile default bash configuation file to invoke 261 | screen by default after login. Add the /bin/screen command to the end of the 262 | ~/.bash\_profile config file: 263 | 264 | **sample ~/.bash\_profile** 265 | ```sh 266 | # .bash_profile 267 | # Get the aliases and functions 268 | if [ -f ~/.bashrc ]; then 269 | . ~/.bashrc 270 | fi 271 | # User specific environment and startup programs 272 | PATH=$PATH:$HOME/bin 273 | export PATH 274 | /bin/screen 275 | ``` 276 | It must be the last line in the file since following login, the /bin/screen 277 | program will be executed and run as a transparent bash shell. 278 | 279 | After you have configured these two files, logout and log back into the system for 280 | whichever account you have enabled and the screensaver will auto-activate after 281 | 60 seconds of idle time. The only disadvantage to using this method to enable 282 | a terminal based screensaver is you will need to type the "exit" command twice 283 | in order to logout of the session. 284 | 285 | ## ssh client returns unknown terminal type when remotely logging into the system 286 | 287 | Some older CentOS and Red Hat Enterprise Linux distributions do not properly detect 288 | or parse aliased terminal types such as "screen.xterm-256color" when using ssh to remotely 289 | access a system that has screen installed and running. This results in an "unknown terminal type" 290 | error being returned after logging in. This error can be fixed by changing the ~/.bashrc file for 291 | the affected account and add a check for the term type, then export a terminal type that matches 292 | one of the supported terminal types in the ncurses-term package. 293 | 294 | Add the following to the bottom of the .bashrc file to check the terminal type, then change and 295 | export it if necessary. 296 | ```sh 297 | if [[ "$TERM" == "screen.xterm-256color" ]]; then 298 | export TERM=screen-256color 299 | fi 300 | ``` 301 | The "screen.xterm-256color" terminal type is the most common terminal type seen when this ssh error 302 | occurs and it is caused by the ncurses library terminfo and termcap files either not being installed 303 | or improperly configured. 304 | 305 | If you encounter this error and are running on version CentOS/RHEL 7 or earlier, then 306 | edit your .bashrc file to append the terminal type and remap check as shown in the example 307 | below: 308 | 309 | **sample ~/.bashrc** 310 | ```sh 311 | # .bashrc 312 | # User specific aliases and functions 313 | 314 | alias rm='rm -i' 315 | alias cp='cp -i' 316 | alias mv='mv -i' 317 | 318 | # Source global definitions 319 | if [ -f /etc/bashrc ]; then 320 | . /etc/bashrc 321 | fi 322 | 323 | # add the following 3 lines to the end of the .bashrc file 324 | if [[ "$TERM" == "screen.xterm-256color" ]]; then 325 | export TERM=screen-256color 326 | fi 327 | ``` 328 | 329 | ## Using Libraries 330 | 331 | You can also call the screensaver as a library function "netware\_screensaver(cpus, speedup)" 332 | from another application with your own timer setup, just be sure to link to the 333 | "-lnetware-screensaver" .so library in your linker statements or link to the static 334 | library "libnetware-screensaver.a" 335 | 336 | ## Building as an RPM Package 337 | 338 | In order to build the screensaver as an RPM, the program must be compressed into a tar.gz 339 | file and the tar.gz file named to match the versioning information contained in the 340 | associated .spec file. 341 | 342 | Spec files are special files which contain instructions on how to build a particular package 343 | from a source code archive. On Red Hat and CentOS systems, RPMS are built in the /root/rpmbuild/ 344 | top directory. SuSe systems build RPMS in the /usr/src/packages/ as top directory. These 345 | "top directories" will contain BUILD, BUILDROOT, SPECS, RPMS, SRPMS, and SOURCES subdirectories. 346 | 347 | The SPECS directory contains the \*.spec files used to build RPMS and SRPMS packages. The SOURCES subdirectory will contain the soure code archive file referred to in the \*.spec file used to build the 348 | RPM package. 349 | 350 | See the [Quick Start Guide](#quick-start-guide) on instructions for installing the 351 | source rpm which installs both the .spec file and source archive file (tar.gz) into 352 | the rpm build top directory (i.e. /root/rpmbuild/). You should have previously 353 | installed the src.rpm file before attempting to build the rpm. You can also 354 | manually install the .spec file into the \/SPECS/ directory and 355 | the source code tarball in the \ 361 | ``` 362 | The program should output the following if the build is successful and verify that the program 363 | wrote both the RPMS and SRPMS packages: 364 | 365 | ```sh 366 | Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.oqGyza 367 | + umask 022 368 | + cd /root/rpmbuild/BUILD 369 | + cd /root/rpmbuild/BUILD 370 | + rm -rf netware-screensaver-1.21 371 | + /usr/bin/gzip -dc /root/rpmbuild/SOURCES/netware-screensaver-1.21.tar.gz 372 | + /usr/bin/tar -xof - 373 | + STATUS=0 374 | + '[' 0 -ne 0 ']' 375 | + cd netware-screensaver-1.21 376 | + /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w . 377 | + exit 0 378 | Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.JTscEj 379 | + umask 022 380 | + cd /root/rpmbuild/BUILD 381 | + cd netware-screensaver-1.21 382 | + /usr/bin/make 383 | g++ -g -c -O3 -fPIC -Wall libnetware-screensaver.c 384 | ar r libnetware-screensaver.a libnetware-screensaver.o 385 | ar: creating libnetware-screensaver.a 386 | ld -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 387 | g++ -g -O3 netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 388 | + exit 0 389 | Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.GtWplM 390 | + umask 022 391 | + cd /root/rpmbuild/BUILD 392 | + '[' /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 '!=' / ']' 393 | + rm -rf /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 394 | ++ dirname /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 395 | + mkdir -p /root/rpmbuild/BUILDROOT 396 | + mkdir /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 397 | + cd netware-screensaver-1.21 398 | + '[' -n /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 -a /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 '!=' / ']' 399 | + /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 400 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/sbin 401 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/bin 402 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/include 403 | + /usr/bin/mkdir -p /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/lib64 404 | + /usr/bin/make DESTDIR=/root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 NOCHK=1 LIBDIR=/usr/lib64 INCDIR=/usr/include BINDIR=/usr/bin install 405 | install -m 0755 netware-worms /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/bin 406 | install -m 0755 libnetware-screensaver.so /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/lib64 407 | install -m 644 libnetware-screensaver.a /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/lib64 408 | install -m 644 netware-worms.h /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64/usr/include 409 | + /usr/lib/rpm/check-buildroot 410 | + /usr/lib/rpm/redhat/brp-ldconfig 411 | /sbin/ldconfig: Warning: ignoring configuration file that cannot be opened: /etc/ld.so.conf: No such file or directory 412 | + /usr/lib/rpm/brp-compress 413 | + /usr/lib/rpm/brp-strip /usr/bin/strip 414 | + /usr/lib/rpm/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump 415 | + /usr/lib/rpm/brp-strip-static-archive /usr/bin/strip 416 | + /usr/lib/rpm/brp-python-bytecompile '' 1 417 | + /usr/lib/rpm/brp-python-hardlink 418 | + PYTHON3=/usr/libexec/platform-python 419 | + /usr/lib/rpm/redhat/brp-mangle-shebangs 420 | Processing files: netware-screensaver-1.21-1.el8.x86_64 421 | Provides: libnetware-screensaver.so()(64bit) netware-screensaver = 1.21-1.el8 netware-screensaver(x86-64) = 1.21-1.el8 422 | Requires(interp): /bin/sh /bin/sh /bin/sh /bin/sh 423 | Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 424 | Requires(pre): /bin/sh 425 | Requires(post): /bin/sh 426 | Requires(preun): /bin/sh 427 | Requires(postun): /bin/sh 428 | Requires: libc.so.6()(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libgcc_s.so.1()(64bit) libm.so.6()(64bit) libncursesw.so.6()(64bit) libpthread.so.0()(64bit) libpthread.so.0(GLIBC_2.2.5)(64bit) libstdc++.so.6()(64bit) libtinfo.so.6()(64bit) rtld(GNU_HASH) 429 | Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 430 | Wrote: /root/rpmbuild/SRPMS/netware-screensaver-1.21-1.el8.src.rpm 431 | Wrote: /root/rpmbuild/RPMS/x86_64/netware-screensaver-1.21-1.el8.x86_64.rpm 432 | Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.PbtDr4 433 | + umask 022 434 | + cd /root/rpmbuild/BUILD 435 | + cd netware-screensaver-1.21 436 | + /usr/bin/rm -rf /root/rpmbuild/BUILDROOT/netware-screensaver-1.21-1.el8.x86_64 437 | + exit 0 438 | ``` 439 | 440 | ## Building as a Debian Package 441 | 442 | In order to build the screensaver as a Debian package, the program must be compressed into a tar.gz 443 | file and the tar.gz file named to match the versioning information contained in the associated .spec file. Spec files are special files which contain instructions on how to build a particular package from a source code archive. 444 | 445 | Debian Packages can be built using a utility called "debbuild" and use a top directory structure which is similar to that used by the RPM tool but using /root/debbuild/ as the "top directory". These "top directories" will contain BUILD, BUILDROOT, SPECS, DEBS, SDEBS, and SOURCES subdirectories and follows a similar layout that is used for RPM files. 446 | 447 | The SPECS directory contains the \*.spec files used to build DEB and SDEB packages. The SOURCES subdirectory will contain the soure code archive file referred to in the \*.spec file used to build the 448 | DEB and SDEB packages. 449 | 450 | See the [Quick Start Guide](#quick-start-guide) on instructions for installing the 451 | source SDEB which installs both the .spec file and source archive file (tar.gz) into 452 | the debbuild top directory (i.e. /root/debbuild/). You should have previously installed 453 | the SDEB file before attempting to build the DEB package. You can also manually 454 | install the .spec file into the \/SPECS/ directory and the source 455 | code tarball in the \ 461 | ``` 462 | The program should output the following if the build is successful and verify that the program 463 | wrote both the DEB and SDEB packages: 464 | 465 | ```sh 466 | This is debbuild, version 22.02.1\ndebconfigdir:/usr/lib/debbuild\nsysconfdir:/etc\n 467 | Lua: No Lua module loaded 468 | Executing (%prep): /bin/sh -e /var/tmp/deb-tmp.prep.20277 469 | + umask 022 470 | + cd /root/debbuild/BUILD 471 | + /bin/rm -rf netware-screensaver-1.21 472 | + /bin/gzip -dc /root/debbuild/SOURCES/netware-screensaver-1.21.tar.gz 473 | + /bin/tar -xf - 474 | + STATUS=0 475 | + '[' 0 -ne 0 ']' 476 | + cd netware-screensaver-1.21 477 | + /bin/chmod -Rf a+rX,u+w,go-w . 478 | + exit 0 479 | Executing (%build): /bin/sh -e /var/tmp/deb-tmp.build.33585 480 | + umask 022 481 | + cd /root/debbuild/BUILD 482 | + cd netware-screensaver-1.21 483 | + /usr/bin/make 484 | g++ -g -c -O3 -fPIC -Wall libnetware-screensaver.c 485 | ar r libnetware-screensaver.a libnetware-screensaver.o 486 | ar: creating libnetware-screensaver.a 487 | ld -shared -lc -o libnetware-screensaver.so libnetware-screensaver.o 488 | g++ -g -O3 netware-worms.c libnetware-screensaver.a -Wall -o netware-worms -lncursesw -lpthread -ltinfo 489 | + exit 0 490 | Executing (%install): /bin/sh -e /var/tmp/deb-tmp.install.73931 491 | + umask 022 492 | + cd /root/debbuild/BUILD 493 | + cd netware-screensaver-1.21 494 | + '[' -n /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 -a /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 '!=' / ']' 495 | + /bin/rm -rf /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 496 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/sbin 497 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/bin 498 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/include 499 | + /bin/mkdir -p /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/lib/x86_64-linux-gnu 500 | + /usr/bin/make DESTDIR=/root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 NOCHK=1 LIBDIR=/usr/lib/x86_64-linux-gnu INCDIR=/usr/include BINDIR=/usr/bin install 501 | install -m 0755 netware-worms /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/bin 502 | install -m 0755 libnetware-screensaver.so /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/lib/x86_64-linux-gnu 503 | install -m 644 libnetware-screensaver.a /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/lib/x86_64-linux-gnu 504 | install -m 644 netware-worms.h /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/usr/include 505 | + exit 0 506 | Checking library requirements... 507 | dpkg-query: no path found matching pattern /lib64/libncursesw.so.6 508 | dpkg-query: no path found matching pattern /lib64/libtinfo.so.6 509 | dpkg-query: no path found matching pattern /lib64/libpthread.so.0 510 | dpkg-query: no path found matching pattern /lib64/libstdc++.so.6 511 | dpkg-query: no path found matching pattern /lib64/libm.so.6 512 | dpkg-query: no path found matching pattern /lib64/libgcc_s.so.1 513 | dpkg-query: no path found matching pattern /lib64/libc.so.6 514 | dpkg-query: no path found matching pattern /lib64/libdl.so.2 515 | dpkg-query: no path found matching pattern /lib64/libc.so.6 516 | Executing (package-creation): /bin/sh -e /var/tmp/deb-tmp.pkg.37356 for netware-screensaver 517 | + umask 022 518 | + cd /root/debbuild/BUILD 519 | + /usr/bin/fakeroot -- /usr/bin/dpkg-deb -b /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/main /root/debbuild/DEBS/amd64/netware-screensaver_1.21-1_amd64.deb 520 | dpkg-deb: warning: parsing file '/root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64/main/DEBIAN/control' near line 10 package 'netware-screensaver': 521 | missing 'Maintainer' field 522 | dpkg-deb: warning: ignoring 1 warning about the control file(s) 523 | dpkg-deb: building package 'netware-screensaver' in '/root/debbuild/DEBS/amd64/netware-screensaver_1.21-1_amd64.deb'. 524 | + exit 0 525 | Executing (%clean): /bin/sh -e /var/tmp/deb-tmp.clean.95144 526 | + umask 022 527 | + cd /root/debbuild/BUILD 528 | + '[' /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 '!=' / ']' 529 | + /bin/rm -rf /root/debbuild/BUILDROOT/netware-screensaver-1.21-1.amd64 530 | + exit 0 531 | Wrote source package netware-screensaver-1.21-1.sdeb in /root/debbuild/SDEBS. 532 | Wrote binary package netware-screensaver_1.21-1_amd64.deb in /root/debbuild/DEBS/amd64 533 | ``` 534 | 535 | ## Issues / problems / help 536 | 537 | If you have any issues, please log them at 538 | 539 | If you have any suggestions for improvements then pull requests are 540 | welcomed, or raise an issue. 541 | -------------------------------------------------------------------------------- /libnetware-screensaver.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * 3 | * Copyright(c) Jeff V. Merkey 1997-2022. All rights reserved. 4 | * 5 | * Portions adapted from xscreensaver loadsnake program is 6 | * portions Copyright (c) 2007-2011 Cosimo Streppone 7 | * 8 | * Licensed under the MIT/X License 9 | * 10 | * Permission is hereby granted, free of charge, to any person obtaining a copy 11 | * of this software and associated documentation files (the "Software"), to 12 | * deal in the Software without restriction, including without limitation 13 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 | * and/or sell copies of the Software, and to permit persons to whom the 15 | * Software is furnished to do so, subject to the following conditions: 16 | * 17 | * The above copyright notice and this permission notice shall be included 18 | * in all copies or substantial portions of the Software. 19 | * 20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 | * DEALINGS IN THE SOFTWARE. 27 | * 28 | * NetWare SMP style worm screesnsaver for Linux using ncurses 29 | * 30 | * USAGE: netware-worms [cpus|speedup] 31 | * i.e. worm cpus= speedup= 32 | * examples: 33 | * netware-worms cpus=8; 34 | * start worm screensaver with 8 worm threads 35 | * netware-worms speedup=4 36 | * run worm screensaver at 4X speed 37 | * 38 | **************************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #include "netware-worms.h" 54 | 55 | #ifndef LONGLONG 56 | typedef long long LONGLONG; 57 | #endif 58 | #ifndef ULONG 59 | typedef unsigned long ULONG; 60 | #endif 61 | #ifndef WORD 62 | typedef unsigned short WORD; 63 | #endif 64 | #ifndef BYTE 65 | typedef unsigned char BYTE; 66 | #endif 67 | 68 | // 6845 color codes for PC displays 69 | #define BLINK 0x80 70 | #define BLACK 0x00 71 | #define BLUE 0x01 72 | #define GREEN 0x02 73 | #define CYAN 0x03 74 | #define RED 0x04 75 | #define MAGENTA 0x05 76 | #define BROWN 0x06 77 | #define WHITE 0x07 78 | #define GRAY 0x08 79 | #define LTBLUE 0x09 80 | #define LTGREEN 0x0A 81 | #define LTCYAN 0x0B 82 | #define LTRED 0x0C 83 | #define LTMAGENTA 0x0D 84 | #define YELLOW 0x0E 85 | #define BRITEWHITE 0x0F 86 | #define BGBLACK 0x00 87 | #define BGBLUE 0x10 88 | #define BGGREEN 0x20 89 | #define BGCYAN 0x30 90 | #define BGRED 0x40 91 | #define BGMAGENTA 0x50 92 | #define BGBROWN 0x60 93 | #define BGWHITE 0x70 94 | #define UP_CHAR 0x1E 95 | #define DOWN_CHAR 0x1F 96 | 97 | static ULONG worm_chars[] = 98 | { 99 | (219 | A_ALTCHARSET), 100 | (178 | A_ALTCHARSET), 101 | (177 | A_ALTCHARSET), 102 | (176 | A_ALTCHARSET), 103 | }; 104 | 105 | static ULONG worm_colors[]= 106 | { 107 | (LTRED | BGBLACK), 108 | (BLUE | BGBLACK), 109 | (LTGREEN | BGBLACK), 110 | (LTCYAN | BGBLACK), 111 | (YELLOW | BGBLACK), 112 | (BRITEWHITE | BGBLACK), 113 | (MAGENTA | BGBLACK), 114 | (BROWN | BGBLACK), 115 | (RED | BGBLACK), 116 | (LTBLUE | BGBLACK), 117 | (LTMAGENTA | BGBLACK), 118 | (GRAY | BGBLACK), 119 | (LTRED | BGBLACK), 120 | (WHITE | BGBLACK), 121 | (GREEN | BGBLACK), 122 | (CYAN | BGBLACK), 123 | }; 124 | static int worm_max_length = WORM_MAX_LEN; 125 | static int has_color; 126 | 127 | // Here we attempt to map the ncurses color pair numbers into 128 | // something a little more PC friendly. 129 | 130 | static int color_map[128]= 131 | { 132 | 1, 2, 3, 4, 5, 6, 7, 8, 8, 2, 3, 4, 5, 6, 7, 8, 133 | 9, 10, 11, 12, 13, 14, 15, 16, 16, 10, 11, 12, 13, 14, 15, 16, 134 | 17, 18, 19, 20, 21, 22, 23, 24, 24, 18, 19, 20, 21, 22, 23, 24, 135 | 25, 26, 27, 28, 29, 30, 31, 32, 32, 26, 27, 28, 29, 30, 31, 32, 136 | 33, 34, 35, 36, 37, 38, 39, 40, 40, 34, 35, 36, 37, 38, 39, 40, 137 | 41, 42, 43, 44, 45, 46, 47, 48, 48, 42, 43, 44, 45, 46, 47, 48, 138 | 49, 50, 51, 52, 53, 54, 55, 56, 56, 50, 51, 52, 53, 54, 55, 56, 139 | 57, 58, 59, 60, 61, 62, 53, 64, 64, 58, 59, 60, 61, 62, 53, 64 140 | }; 141 | 142 | static int attr_map[128]= 143 | { 144 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 145 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 146 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 147 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 148 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 149 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 150 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 151 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 152 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 153 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 154 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 155 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 156 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 157 | A_BOLD, A_BOLD, A_BOLD, A_BOLD, 158 | 0, 0, 0, 0, 0, 0, 0, A_BOLD, 0, A_BOLD, A_BOLD, A_BOLD, 159 | A_BOLD, A_BOLD, A_BOLD, A_BOLD 160 | }; 161 | 162 | static ULONG get_color_pair(ULONG attr) 163 | { 164 | return ((COLOR_PAIR(color_map[attr & 0x7F]) | 165 | attr_map[attr & 0x7F] | ((attr & BLINK) ? A_BLINK : 0))); 166 | } 167 | 168 | static void set_color(ULONG attr) 169 | { 170 | if (has_color) 171 | attrset(get_color_pair(attr)); 172 | } 173 | 174 | static void clear_color(void) 175 | { 176 | attroff(A_BOLD | A_BLINK | A_REVERSE); 177 | } 178 | 179 | static int init_ncurses() 180 | { 181 | int i, pair, ret; 182 | unsigned long w = 0; 183 | FILE *f; 184 | char wait[100], *s; 185 | int bg_colors[8]= 186 | { 187 | COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, 188 | COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE 189 | }; 190 | 191 | setlocale(LC_ALL, ""); 192 | initscr(); 193 | nonl(); 194 | intrflush(stdscr, FALSE); 195 | keypad(stdscr, TRUE); 196 | noecho(); 197 | 198 | // if the terminal does not support colors, or if the 199 | // terminal cannot support at least eight primary colors 200 | // for foreground/background color pairs, then default 201 | // the library to use ASCII characters < 127 (7 bit), disable 202 | // ncurses color attributes, and do not attempt to use 203 | // the alternate character set for graphic characters. 204 | 205 | if (has_colors()) 206 | { 207 | if (start_color() == OK) 208 | { 209 | if (COLORS >= 8) 210 | { 211 | has_color = TRUE; 212 | pair = 1; 213 | 214 | // We create our color pairs in the order defined 215 | // by the PC based text attribute color scheme. We do 216 | // this to make it relatively simple to use a table 217 | // driven method for mapping the PC style text attributes 218 | // to ncurses. 219 | 220 | for (i=0; i < 8; i++) 221 | { 222 | init_pair(pair++, COLOR_BLACK, bg_colors[i]); 223 | init_pair(pair++, COLOR_BLUE, bg_colors[i]); 224 | init_pair(pair++, COLOR_GREEN, bg_colors[i]); 225 | init_pair(pair++, COLOR_CYAN, bg_colors[i]); 226 | init_pair(pair++, COLOR_RED, bg_colors[i]); 227 | init_pair(pair++, COLOR_MAGENTA, bg_colors[i]); 228 | init_pair(pair++, COLOR_YELLOW, bg_colors[i]); 229 | init_pair(pair++, COLOR_WHITE, bg_colors[i]); 230 | } 231 | } 232 | } 233 | } 234 | 235 | wclear(stdscr); 236 | curs_set(0); // turn off the cursor 237 | refresh(); 238 | 239 | f = fopen("/sys/module/kernel/parameters/consoleblank", "r"); 240 | if (f != NULL) 241 | { 242 | s = fgets(wait, 98, f); 243 | if (s) { 244 | sscanf(wait, "%lu", &w); 245 | #if VERBOSE 246 | printf("console blank timer: %lu\n", w); 247 | #endif 248 | } 249 | fclose(f); 250 | } 251 | // disable screen blanking 252 | if (w) { 253 | ret = system("setterm -blank 0"); 254 | if (ret < 0) 255 | return ret; 256 | } 257 | return 0; 258 | } 259 | 260 | static int clear_ncurses() 261 | { 262 | curs_set(1); // turn on the cursor 263 | endwin(); 264 | 265 | // reset terminal escape sequence 266 | printf("%c%c", 0x1B, 'c'); 267 | 268 | // enable screen blanking 269 | #if 0 270 | system("setterm -blank 10"); 271 | #endif 272 | return 0; 273 | } 274 | 275 | // this function remaps single byte box and line characters into utf8 276 | // unicode characters for display on wide character terminals. This 277 | // allows the program to store multi byte characters as single byte 278 | // ASCII codes for ncurses. 279 | 280 | static void mvputc(ULONG row, ULONG col, const chtype ch) 281 | { 282 | switch (ch & 0xFF) 283 | { 284 | // solid block 285 | case 219: 286 | mvprintw(row, col, "\u2588"); 287 | break; 288 | // dark shade block 289 | case 178: 290 | mvprintw(row, col, "\u2593"); 291 | break; 292 | // medium shade block 293 | case 177: 294 | mvprintw(row, col, "\u2592"); 295 | break; 296 | // light shade block 297 | case 176: 298 | mvprintw(row, col, "\u2591"); 299 | break; 300 | 301 | default: 302 | mvaddch(row, col, ch); 303 | break; 304 | } 305 | return; 306 | } 307 | 308 | static void worm_put_char(int c, long row, long col, ULONG attr) 309 | { 310 | if (col >= COLS) 311 | return; 312 | if (row >= LINES) 313 | return; 314 | set_color(attr); 315 | mvputc(row, col, c); 316 | clear_color(); 317 | return; 318 | } 319 | 320 | static int worm_kbhit(void) 321 | { 322 | int STDIN = 0, bytes = 0; 323 | struct termios init; 324 | struct termios term; 325 | 326 | // setup the terminal to check 327 | // for pending keystrokes 328 | tcgetattr(STDIN, &init); 329 | tcgetattr(STDIN, &term); 330 | term.c_lflag &= ~ICANON; 331 | tcsetattr(STDIN, TCSANOW, &term); 332 | 333 | setbuf(stdin, NULL); 334 | ioctl(STDIN, FIONREAD, &bytes); 335 | // set the terminal to default 336 | tcsetattr(STDIN, TCSANOW, &init); 337 | return bytes; 338 | } 339 | 340 | static int get_processors(void) 341 | { 342 | int cpus = 0; 343 | cpus = sysconf(_SC_NPROCESSORS_ONLN); 344 | if (cpus < 1) 345 | cpus = 1; 346 | return (cpus); 347 | } 348 | 349 | static int get_cpu_load(STATE *st, int cpu) 350 | { 351 | static char line[1024], *s; 352 | unsigned long long p_usr = 0, p_nice = 0, p_sys = 0, p_idle = 0; 353 | unsigned long long load = 0, idle = 0, util = 0, len; 354 | unsigned long long p_io = 0, p_irq = 0, p_sirq = 0; 355 | unsigned long long p_steal = 0, p_guest = 0, p_guest_nice = 0; 356 | FILE *f; 357 | char src[1024] = "\0"; 358 | 359 | if (cpu > st->cpus) 360 | return 0; 361 | 362 | if (cpu > MAX_WORMS) 363 | return 0; 364 | 365 | // convert cpu num to ascii text number 366 | // and null terminate 367 | snprintf(src, 100, "cpu%d", cpu); 368 | len = strlen(src); 369 | 370 | if (NULL != (f = fopen("/proc/stat", "r"))) 371 | { 372 | while (!feof(f) && !load) 373 | { 374 | s = fgets(line, sizeof(line) - 1, f); 375 | if (s && !strncasecmp(src, line, len)) 376 | { 377 | p_usr = st->usr[cpu]; 378 | p_nice = st->nice[cpu]; 379 | p_sys = st->sys [cpu]; 380 | p_idle = st->idle[cpu]; 381 | p_io = st->io[cpu]; 382 | p_irq = st->irq[cpu]; 383 | p_sirq = st->sirq[cpu]; 384 | p_steal = st->steal[cpu]; 385 | p_guest = st->guest[cpu]; 386 | p_guest_nice = st->guest_nice[cpu]; 387 | 388 | if (sscanf(&line[len + 1], "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", 389 | &(st->usr[cpu]), &(st->nice[cpu]), 390 | &(st->sys[cpu]), &(st->idle[cpu]), 391 | &(st->io[cpu]), &(st->irq[cpu]), 392 | &(st->sirq[cpu]), &(st->steal[cpu]), 393 | &(st->guest[cpu]), &(st->guest_nice[cpu])) == 10) 394 | { 395 | // calculate total cycles 396 | unsigned long long user, nice; 397 | unsigned long long idletime; 398 | unsigned long long deltaidle; 399 | unsigned long long systime; 400 | unsigned long long virtalltime; 401 | unsigned long long totaltime; 402 | unsigned long long deltatime; 403 | 404 | // Guest time is already accounted in usertime 405 | user = st->usr[cpu] - st->guest[cpu]; 406 | nice = st->nice[cpu] - st->guest_nice[cpu]; 407 | // io is added in the total idle time 408 | idletime = st->idle[cpu] + st->io[cpu]; 409 | systime = st->sys[cpu] + st->irq[cpu] + st->sirq[cpu]; 410 | virtalltime = st->guest[cpu] + st->guest_nice[cpu]; 411 | totaltime = user + nice + systime + idletime + 412 | st->steal[cpu] + virtalltime; 413 | 414 | // Guest time is already accounted in usertime 415 | user = p_usr - p_guest; 416 | nice = p_nice - p_guest_nice; 417 | // io is added in the total idle time 418 | deltaidle = p_idle + p_io; 419 | systime = p_sys + p_irq + p_sirq; 420 | virtalltime = p_guest + p_guest_nice; 421 | deltatime = user + nice + systime + deltaidle + 422 | p_steal + virtalltime; 423 | 424 | load = totaltime - deltatime; 425 | idle = idletime - deltaidle; 426 | // prevent divide by zero if result is 0 427 | if (!load) { 428 | load = 1; 429 | idle = 1; 430 | } 431 | 432 | // subtract idle cycles from load and mulitply * 100 433 | // to express as percentage 434 | util = (load - idle) * 100 / load; 435 | idle = (idle * 100) / load; 436 | break; 437 | } 438 | else 439 | { 440 | fclose(f); 441 | return 0; 442 | } 443 | } 444 | } 445 | fclose(f); 446 | } 447 | 448 | len = util * util * worm_max_length / 10000.0; 449 | if (len < WORM_MIN_LEN) 450 | len = WORM_MIN_LEN; 451 | #if VERBOSE 452 | set_color(WHITE | BGBLACK); 453 | mvprintw(cpu, 2, "Load on cpu %d is %d%% length %d idle %d%%\n", cpu, util, len, idle); 454 | clear_color(); 455 | #endif 456 | return (len); 457 | } 458 | 459 | static int get_system_load(void) 460 | { 461 | char load[100], *s; 462 | float l1 = 0; 463 | int l2 = 0; 464 | FILE *f; 465 | 466 | f = fopen("/proc/loadavg", "r"); 467 | if (f != NULL) 468 | { 469 | s = fgets(load, 98, f); 470 | if (s) { 471 | sscanf(load, "%f", &l1); 472 | #if VERBOSE 473 | printw("Load from /proc/loadavg is %f\n", l1); 474 | #endif 475 | } 476 | fclose(f); 477 | } 478 | else 479 | l1 = 0; 480 | 481 | // convert from float to integer 482 | l1 *= 1000.0; 483 | l2 = (int) l1; 484 | l2 /= 1000; 485 | 486 | return l2; 487 | } 488 | 489 | static void move_worm(STATE *st, WORM *s) 490 | { 491 | int n = 0, dir = 0; 492 | int x = 0, y = 0; 493 | 494 | /* worm head position */ 495 | x = s->x[0]; 496 | y = s->y[0]; 497 | 498 | /* and direction */ 499 | dir = s->direction; 500 | 501 | /* 0=up, 2=right, 4=down, 6=left */ 502 | switch(dir) 503 | { 504 | case 0: y++; break; 505 | case 1: y++; x++; break; 506 | case 2: x += 2; break; 507 | case 3: y--; x++; break; 508 | case 4: y--; break; 509 | case 5: y--; x--; break; 510 | case 6: x -= 2; break; 511 | case 7: y++; x--; break; 512 | } 513 | 514 | /* Check bounds and change direction */ 515 | if (x < 0 && (dir >= 5 && dir <= 7)) { 516 | x = 1; 517 | dir -= 4; 518 | } 519 | else if (y < 0 && (dir >= 3 && dir <= 5)) { 520 | y = 1; 521 | dir -= 4; 522 | } 523 | else if (x >= (st->cols - 2) && (dir >= 1 && dir <= 3)) { 524 | x = st->cols - 2; 525 | dir += 4; 526 | } 527 | else if (y >= st->rows && (dir == 7 || dir == 0 || dir == 1)) { 528 | y = st->rows - 1; 529 | dir += 4; 530 | } 531 | else if (s->runlength == 0) { 532 | int rnd; 533 | 534 | rnd = random() % 128; 535 | if(rnd > 90) 536 | dir += 2; 537 | else if(rnd == 1) 538 | dir++; 539 | else if(rnd == 2) 540 | dir--; 541 | // set this to the current worm length 542 | s->runlength = s->length; 543 | } 544 | else { 545 | int rnd; 546 | 547 | s->runlength--; 548 | rnd = random() % 128; 549 | if(rnd == 1) 550 | dir++; 551 | else if(rnd == 2) 552 | dir--; 553 | } 554 | 555 | if (dir < 0) 556 | dir = -dir; 557 | dir = dir % 8; 558 | 559 | s->direction = dir; 560 | 561 | /* Copy x,y coords in "tail" positions */ 562 | for(n = s->length - 1; n > 0; n--) { 563 | s->x[n] = s->x[n-1]; 564 | s->y[n] = s->y[n-1]; 565 | } 566 | 567 | /* New head position */ 568 | s->x[0] = x; 569 | s->y[0] = y; 570 | 571 | } 572 | 573 | static int grow_worm(STATE *st, WORM *s) 574 | { 575 | int newlen = get_cpu_load(st, s->cpu); 576 | int len = s->length; 577 | 578 | #if VERBOSE 579 | printw("grow: cpu %d len %d newlen %d\n", s->cpu, len, newlen); 580 | #endif 581 | if (newlen > len) { 582 | int x, y; 583 | 584 | x = s->x[len - 1]; 585 | y = s->y[len - 1]; 586 | 587 | switch(s->direction) { 588 | case 0: y--; break; 589 | case 1: y--; x--; break; 590 | case 2: x -= 2; break; 591 | case 3: y++; x--; break; 592 | case 4: y++; break; 593 | case 5: y++; x++; break; 594 | case 6: x += 2; break; 595 | case 7: y--; x++; break; 596 | } 597 | len++; 598 | 599 | if (len >= worm_max_length) 600 | len = worm_max_length - 1; 601 | 602 | s->x[len] = x; 603 | s->y[len] = y; 604 | } 605 | else if (newlen < len) { 606 | len--; 607 | if (len < WORM_MIN_LEN) 608 | len = WORM_MIN_LEN; 609 | s->x[len + 1] = 0; 610 | s->y[len + 1] = 0; 611 | } 612 | s->length = len; 613 | return(len); 614 | } 615 | 616 | static void clear_worm(STATE *st, WORM *s) 617 | { 618 | int n; 619 | 620 | for (n = s->length_prev - 1; n >= 0; n--) { 621 | worm_put_char(' ', s->y_prev[n], s->x_prev[n], 622 | WHITE | BGBLACK); 623 | worm_put_char(' ', s->y_prev[n], s->x_prev[n] + 1, 624 | WHITE | BGBLACK); 625 | } 626 | } 627 | 628 | /* 629 | 630 | For drawing the worm the following set of equations map the 631 | worm chars to create the effect of the worm moving and expanding. 632 | 633 | The logic is non-intuitive but it is described below. There are 634 | four worm drawing characters in total. The mapping is defined as: 635 | 636 | current char position = n 637 | div = length / 4 638 | mod = length % 4 639 | c = n < (div + 1) * mod ? n / (div + 1) : (n - mod) / div 640 | 641 | the above routine produces the following output: 642 | 643 | LENGTH DIV/MOD WINDOW CHARACTER MAP 644 | ---------------------------------------------------------- 645 | length 04 div 1 mod 0 (div + 1) * mod = 00 0 1 2 3 646 | length 05 div 1 mod 1 (div + 1) * mod = 02 0 0 1 2 3 647 | length 06 div 1 mod 2 (div + 1) * mod = 04 0 0 1 1 2 3 648 | length 07 div 1 mod 3 (div + 1) * mod = 06 0 0 1 1 2 2 3 649 | length 08 div 2 mod 0 (div + 1) * mod = 00 0 0 1 1 2 2 3 3 650 | length 09 div 2 mod 1 (div + 1) * mod = 03 0 0 0 1 1 2 2 3 3 651 | length 10 div 2 mod 2 (div + 1) * mod = 06 0 0 0 1 1 1 2 2 3 3 652 | length 11 div 2 mod 3 (div + 1) * mod = 09 0 0 0 1 1 1 2 2 2 3 3 653 | length 12 div 3 mod 0 (div + 1) * mod = 00 0 0 0 1 1 1 2 2 2 3 3 3 654 | length 13 div 3 mod 1 (div + 1) * mod = 04 0 0 0 0 1 1 1 2 2 2 3 3 3 655 | length 14 div 3 mod 2 (div + 1) * mod = 08 0 0 0 0 1 1 1 1 2 2 2 3 3 3 656 | length 15 div 3 mod 3 (div + 1) * mod = 12 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 657 | length 16 div 4 mod 0 (div + 1) * mod = 00 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 658 | length 17 div 4 mod 1 (div + 1) * mod = 05 0 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 659 | length 18 div 4 mod 2 (div + 1) * mod = 10 0 0 0 0 0 1 1 1 1 1 2 2 2 2 3 3 3 3 660 | length 19 div 4 mod 3 (div + 1) * mod = 15 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 661 | length 20 div 5 mod 0 (div + 1) * mod = 00 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 662 | length 21 div 5 mod 1 (div + 1) * mod = 06 0 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 663 | length 22 div 5 mod 2 (div + 1) * mod = 12 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 664 | length 23 div 5 mod 3 (div + 1) * mod = 18 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 665 | length 24 div 6 mod 0 (div + 1) * mod = 00 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 666 | length 25 div 6 mod 1 (div + 1) * mod = 07 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 667 | length 26 div 6 mod 2 (div + 1) * mod = 14 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 668 | length 27 div 6 mod 3 (div + 1) * mod = 21 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 669 | length 28 div 7 mod 0 (div + 1) * mod = 00 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 670 | length 29 div 7 mod 1 (div + 1) * mod = 08 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 671 | length 30 div 7 mod 2 (div + 1) * mod = 16 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 3 3 3 3 3 3 3 672 | length 31 div 7 mod 3 (div + 1) * mod = 24 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 673 | length 32 div 8 mod 0 (div + 1) * mod = 00 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 674 | length 33 div 8 mod 1 (div + 1) * mod = 09 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 675 | length 34 div 8 mod 2 (div + 1) * mod = 18 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 676 | length 35 div 8 mod 3 (div + 1) * mod = 27 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 677 | length 36 div 9 mod 0 (div + 1) * mod = 00 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 678 | 679 | */ 680 | 681 | static void save_worm(WORM *s) 682 | { 683 | int n; 684 | 685 | // save last worm position and coordinates 686 | // for clearing later 687 | for (n = s->length - 1; n >= 0; n--) { 688 | s->x_prev[n] = s->x[n]; 689 | s->y_prev[n] = s->y[n]; 690 | } 691 | s->length_prev = s->length; 692 | } 693 | 694 | static void draw_worm(STATE *st, WORM *s) 695 | { 696 | int n, div, mod, c; 697 | 698 | // get character interval and draw worm it is 699 | // assumed that the minimum worm length is 4 700 | div = s->length / 4; 701 | mod = s->length % 4; 702 | for (n = s->length - 1; n >= 0 && div; n--) { 703 | c = n < (div + 1) * mod ? n / (div + 1) : (n - mod) / div; 704 | worm_put_char(worm_chars[c % 4], 705 | s->y[n], s->x[n], worm_colors[s->cpu % 16]); 706 | worm_put_char(worm_chars[c % 4], 707 | s->y[n], s->x[n] + 1, worm_colors[s->cpu % 16]); 708 | #if VERBOSE 709 | printw("cpu %d x[n] = %d y[n] = %d n = %d\n", 710 | s->cpu, s->x[n], s->y[n], n); 711 | #endif 712 | } 713 | #if VERBOSE 714 | printw("\n"); 715 | #endif 716 | } 717 | 718 | #define NANOSLEEP 719 | 720 | static unsigned long run_worms(STATE *st) 721 | { 722 | float range, increment; 723 | int n; 724 | 725 | // reset columns and lines in case the screen was resized 726 | worm_max_length = AREA_BASE_LEN + AREA_EXT_LEN; 727 | if (worm_max_length > WORM_MAX_LEN) 728 | worm_max_length = WORM_MAX_LEN; 729 | st->cols = COLS; 730 | st->rows = LINES; 731 | 732 | for (n = 0; n < st->cpus; n++) { 733 | WORM *s = (WORM *) &st->worms[n]; 734 | 735 | if (++s->count >= s->limit) { 736 | s->count = 0; 737 | grow_worm(st, s); 738 | move_worm(st, s); 739 | clear_worm(st, s); 740 | s->limit = 4 - (s->length / (worm_max_length / 4)); 741 | #if VERBOSE 742 | printw("length %d limit %d\n", s->length, s->limit); 743 | #endif 744 | } 745 | save_worm(s); 746 | 747 | // update all worms even those sleeping to 748 | // maintain worm overwrite stacking order 749 | // when one worm overwrites another during 750 | // display 751 | draw_worm(st, s); 752 | refresh(); 753 | } 754 | 755 | // decrease base wait time if system load increases 756 | // range is 0-100 load average before reaching 757 | // minimum st->delay wait time 758 | n = get_system_load(); 759 | #ifdef NANOSLEEP 760 | range = MAX_NANOSEC - MIN_NANOSEC; 761 | increment = range / MAX_LOADAVG; 762 | st->delay = MAX_NANOSEC - (n * increment); 763 | if (st->delay < MIN_NANOSEC) 764 | st->delay = MIN_NANOSEC; 765 | st->delay /= st->divisor; 766 | #else 767 | range = MAX_MICROSEC - MIN_MICROSEC; 768 | increment = range / MAX_LOADAVG; 769 | st->delay = MAX_MICROSEC - (n * increment); 770 | if (st->delay < MIN_MICROSEC) 771 | st->delay = MIN_MICROSEC; 772 | st->delay /= st->divisor; 773 | #endif 774 | #if VERBOSE 775 | printw("delay %d load(n) = %d\n", st->delay, n); 776 | #endif 777 | return st->delay; 778 | } 779 | 780 | #include 781 | #include 782 | 783 | int netware_screensaver(int cpus, int speedup) 784 | { 785 | int n, i, ret, prio = 0; 786 | STATE state, *st = &state; 787 | 788 | memset(st, 0, sizeof(STATE)); 789 | st->cpus = get_processors(); 790 | if (!st->cpus) 791 | exit(1); 792 | 793 | // set nice value to highest priority 794 | prio = getpriority(PRIO_PROCESS, 0); 795 | setpriority(PRIO_PROCESS, 0, -20); 796 | 797 | if (cpus > st->cpus) 798 | st->cpus = cpus; 799 | 800 | if (st->cpus > MAX_WORMS) 801 | st->cpus = MAX_WORMS; 802 | 803 | if (speedup > 0) 804 | st->divisor = speedup; 805 | else 806 | st->divisor = 1; 807 | 808 | ret = init_ncurses(); 809 | if (ret < 0) 810 | return 1; 811 | 812 | // initialize random number generator 813 | srand(time(0)); 814 | 815 | #if VERBOSE 816 | printw("cols: %d lines: %d base: %d len: %d area: %d" 817 | " max: %d min: %d adj: %d divisor: %d\n", 818 | COLS, LINES, AREA_BASE_LEN, AREA_EXT_LEN, AREA, 819 | AREA_MAX, AREA_MIN, (AREA) - (AREA_MIN), AREA_DIVISOR); 820 | #endif 821 | 822 | worm_max_length = AREA_BASE_LEN + AREA_EXT_LEN; 823 | if (worm_max_length > WORM_MAX_LEN) 824 | worm_max_length = WORM_MAX_LEN; 825 | st->cols = COLS; 826 | st->rows = LINES; 827 | 828 | #ifdef NANOSLEEP 829 | st->delay = MAX_NANOSEC / st->divisor; 830 | #else 831 | st->delay = MAX_MICROSEC / st->divisor; 832 | #endif 833 | 834 | st->worms = (WORM *)calloc(st->cpus, sizeof(WORM)); 835 | if (!st->worms) 836 | exit(1); 837 | memset(st->worms, 0, st->cpus * sizeof(WORM)); 838 | 839 | for (n = 0; n < st->cpus; n++) { 840 | WORM *s = (WORM *)&st->worms[n]; 841 | 842 | s->cpu = n; 843 | s->x[0] = random() % (COLS - 1); 844 | s->y[0] = random() % LINES; 845 | for (i=1; i < WORM_MAX_LEN; i++) 846 | { 847 | s->x[i] = s->x[0]; 848 | s->y[i] = s->y[0]; 849 | } 850 | s->direction = ((random() % 9) >> 1) << 1; 851 | s->length = WORM_MIN_LEN; 852 | s->runlength = WORM_MIN_LEN; 853 | #if VERBOSE 854 | printw(stderr, "worm %d starting at %d,%d dir %d length %d\n", 855 | s->cpu, s->x[0], s->y[0], s->direction, s->length); 856 | #endif 857 | } 858 | 859 | while (!worm_kbhit()) 860 | { 861 | #ifdef NANOSLEEP 862 | struct timespec ts = { 0, st->delay }; 863 | #endif 864 | run_worms(st); 865 | #ifdef NANOSLEEP 866 | nanosleep(&ts, NULL); 867 | #else 868 | usleep(st->delay); 869 | #endif 870 | } 871 | 872 | if (st->worms) 873 | free(st->worms); 874 | 875 | clear_ncurses(); 876 | setpriority(PRIO_PROCESS, 0, prio); 877 | return 0; 878 | } 879 | 880 | --------------------------------------------------------------------------------