Snippets
Autor : Gerd Raudenbusch
Stand : 26.12.2023
Contents
- Matrix Bot
- RSS File writer
- Control script for dockered apps
- Extract GitHub snippets in file
- Python functions for log file filtering
- Logging Macro for C
- Match a regular expression in C
- Execute shell command and consume output in C
- MAC address calculations
- Simple socket implementation in C
- Parse file and process functions with bash
- Longtime recording of top outputs
- FIFO implementation in C
- Get expiration dates of certificates
- Get git logs
- Plot 1-dimensional cellular automata in python
- Perceptron in python
- Shortest crashing C program
- Plot mandelbrot in python
- Plot julia in python
- Plot another mandelbrot in python
- Plot feigenbaum diagram
- Extract tgz without leading directories to target directory
- Copy only new files and keep the old
- Creates and mounts a new virtual loop file system
- Generate a test report from a Unit test XML result output
- Simple AES encryption and decryption of files
- Send an Email in python
- Convert textfile to UTF-8
- Calculates the seconds until the next quarter hour in bash
- Conversion between DER and ASCII
- Colorful text outputs in bash
- Open image and play sound in ununtu bash
- Backup public media contents
- Webserver 127.0.0.1:8000
- Website downloader
- Soundcloud downloader
- Display PHP environment
- Pretty print in shell
- Extract opkg package (.ipk)
- Shell execution capsuler
- Generate big HTTP POST data
- Display all toilet fonts
- Time tracker for test cases
Matrix Bot
#!/bin/bash
botmessages="./matrixbot-messages.txt"
python3 --version >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo "Must install python3"
sudo apt update && sudo apt -y upgrade && sudo apt install -y python3 python3-pip
fi
matrix-commander --version >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo "Must install matrix-commander"
sudo pip3 install matrix-commander
fi
inotifywait >/dev/null 2>&1
if [ "$?" != "1" ]; then
echo "Must install inotify tools"
sudo apt update && sudo apt -y upgrade && sudo apt-get install inotify-tools
fi
processmsg () {
if [ "${1}" == "Ping" ]; then
echo "${0} : PROCESSING ${1}"
matrix-commander -m "Voila!" >/dev/null 2>&1
else
echo "The message '${1}' has no scripted reactions"
fi
}
killold () {
echo "Removing old instances of matrix-commander..."
kill -9 $(ps axn | grep matrix-commander | grep -v grep | sed "s/^ *//g" | cut -d " " -f1 | tr '\n' ' ')
}
trap 'killold' SIGINT SIGTERM
if [ ! -f ${HOME}/.config/matrix-commander/credentials.json ]; then
echo "There are no credentials saved, yet. Please create a default room for the bot and register credentials :"
matrix-commander --login password
if [ "$?" == "0" ] && [ -f ./credentials.json ]; then
mkdir -p ${HOME}/.config/matrix-commander
mv -i ./credentials.json $HOME/.config/matrix-commander
mkdir -p ${HOME}/.local/share/matrix-commander
mv -i ./store ${HOME}/.local/share/matrix-commander
else
echo "Exitting due to errors"
exit 1
fi
else
echo "Logging in"
matrix-commander --credentials ${HOME}/.config/matrix-commander/credentials.json >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo "Error logging in"
exit 1
fi
echo "Starting listener for messages, dropping files in ${botmessages}"
matrix-commander --listen forever --listen-self >${botmessages} 2>/dev/null &
while inotifywait -e modify "${botmessages}" >/dev/null 2>&1; do
lastline="$(tail -1 ${botmessages})"
operation="$(echo ${lastline} | cut -d "|" -f1)"
sender="$(echo ${lastline} | cut -d "|" -f2 | sed "s/^ //g; s/sender //g")"
timestamp="$(echo ${lastline} | cut -d "|" -f3 | sed "s/^ //g")"
message="$(echo ${lastline} | cut -d "|" -f4 | sed "s/^ //g")"
if [ "$(echo "${operation}" | grep -c "Message received")" != "0" ]; then
echo "${0}: [${timestamp} ${sender}] : ${message}"
processmsg "${message}"
fi
done
fi
RSS File writer
#!/bin/bash
#
# This script creates RSS Feed Files
# for webpages and adds new feed entries.
#
# @author: gerd@raudenbusch.net
#
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
BLACK=`tput setaf 0`
RED=`tput setaf 1`
GREEN=`tput setaf 2`
YELLOW=`tput setaf 3`
BLUE=`tput setaf 4`
MAGENTA=`tput setaf 5`
CYAN=`tput setaf 6`
WHITE=`tput setaf 7`
BOLD=`tput bold`
RESET=`tput sgr0`
fi
fi
log () {
>&2 echo "${1}"
}
printInfo () {
log "${BOLD}${WHITE}${1}${RESET}"
}
printWarning () {
log "${BOLD}${YELLOW}${1}${RESET}"
}
printSuccess () {
log "${BOLD}${GREEN}${1}${RESET}"
}
printError () {
log "${BOLD}${RED}${1}${RESET}"
}
createFeed () {
local TITLE="${1}"
local DOMAIN="${2}"
local DESCRIPTION="${3}"
local FILENAME="${4}"
cat << EOF >${FILENAME}
<rss version="2.0">
<channel>
<title>${TITLE}</title>
<link>${DOMAIN}</link>
<description>${DESCRIPTION}</description>
<!-- ENTRIES -->
</channel>
</rss>
EOF
printSuccess "Success !"
}
addEntry () {
local TITLE="${1}"
local LINK="${2}"
local DESCRIPTION="${3}"
local FILENAME="${4}"
feedentry="\\\t<item>\n\t\t<title>${TITLE}</title>\n\t\t<link>${LINK}</link>\n\t\t<description>${DESCRIPTION}</description>\n\t</item>\n"
sed "/<\!-- ENTRIES -->/a ${feedentry}" -i ${FILENAME}
if [ "$?" == "0" ]; then
printSuccess "Success !"
else
printError "Failed !"
fi
}
printUsage () {
printInfo "RSS Feed writer"
log "This script can create RSS feed XML files and add new entries to them."
log "The XML file has to be placed on the webserver."
log "Users will be able to follow with a feed reader."
log ""
printInfo "Usage :"
log ""
printInfo "create <options> <RSS feed output XML filename>"
log "creates a new RSS feed XML file."
log " -t or --title : The title of the webpage"
log " -D or --domain : The domain of the feed channel"
log " -d or --description : The description of the feed channel"
log ""
printInfo "add <option> <RSS feed output XML filename>"
log "adds a new entry to an existing RSS feed XML file."
log " -t or --title : The title of the feed entry"
log " -l or --link : The URL to be announced by the new feed entry"
log " -d or --description : The description of the feed entry"
}
# Evaluate command line options
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
printUsage
exit 1
;;
-D|--domain)
DOMAIN="${2}"
shift # past argument
shift # past value
;;
-t|--title)
TITLE="${2}"
shift # past argument
shift # past value
;;
-l|--link)
LINK="${2}"
shift # past argument
shift # past value
;;
-d|--description)
DESCRIPTION="${2}"
shift # past argument
shift # past value
;;
-*|--*)
log "Unknown option $1"
(return 0 2>/dev/null) && return 1 || exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
# Process operations
case ${1} in
create)
if [ "${TITLE}" == "" ]; then
printError "Title is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ "${DOMAIN}" == "" ]; then
printError "Domain is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ "${DESCRIPTION}" == "" ]; then
printError "Domain is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ "${2}" == "" ]; then
printError "RSS XML output file name is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ -f ${2} ]; then
printError "File ${FILENAME} already exists!"
else
createFeed "${TITLE}" "${DOMAIN}" "${DESCRIPTION}" "${2}"
fi
;;
add)
if [ "${TITLE}" == "" ]; then
printError "Title of feed entry is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ "${LINK}" == "" ]; then
printError "Link of webpage to be feeded is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ "${DESCRIPTION}" == "" ]; then
printError "Description of feed entry mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ "${2}" == "" ]; then
printError "File name of RSS feed XML file is mandatory !"
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
elif [ ! -f ${2} ]; then
printError "File ${FILENAME} does not exist !"
else
addEntry "${TITLE}" "${LINK}" "${DESCRIPTION}" "${2}"
fi
;;
*)
printUsage
(return 0 2>/dev/null) && return 1 || exit 1
;;
esac
(return 0 2>/dev/null) && return 0 || exit 0
Control script for dockered apps
#!/bin/bash
tag="latest"
if [ "${2}" != "" ]; then
tag="${2}"
fi
name=$(basename ${0} |cut -d "." -f1)
img="ubuntu"
options="-d -t"
mkdir -p /etc/containers/${name}
mkdir -p /var/www/${name}
mkdir -p /var/log/containers/${name}
#########################
echo "Container: ${name}"
if [ "${1}" == "start" ]; then
echo "Starting"
docker run --name ${name} ${options} ${img}:${tag} sleep infinity
elif [ "${1}" == "stop" ]; then
echo "Stopping"
docker rm -f ${name}
elif [ "${1}" == "restart" ]; then
docker rm -f ${name} && docker run --name ${name} ${options} ${img}:${tag}
elif [ "${1}" == "login" ]; then
docker exec -it ${name} /bin/bash
elif [ "${1}" == "commit" ]; then
docker commit ${name} ${img}:${tag}
elif [ "${1}" == "load" ]; then
echo "Loading"
docker load < ${name}.tar.gz
elif [ "${1}" == "save" ]; then
echo "Saving"
docker save ${img}:${tag} | gzip > ${name}.tar.gz
else
echo "Unknown : ${1}"
exit 1
fi
Extract GitHub snippets in file
####################################################################
# Snippet 61 : "get_snippets.sh"
# Get your personal Git snippets via the Git-API
# - Using curl for http requests
# - Using jq to parse json
####################################################################
#!/bin/bash
personal_gittoken="your-personal-git-api-token"
jsonout=$(curl --header "PRIVATE-TOKEN: ${personal_gittoken}" "https://git-intern2.ppc-ag.de/api/v4/snippets" 2>/dev/null)
length=$(echo ${jsonout} | jq "length")
for (( id=0; id<${length}; id++ ))
do
snippetid=$(echo ${jsonout} | jq ".[${id}].id")
echo "####################################################################"
echo ${jsonout} | jq -r ".[${id}] | \"# Snippet \(.id) : \\\"\(.file_name)\\\"\n# \(.title)\n# \(.description)\""
echo "####################################################################"
curl --header "PRIVATE-TOKEN: ${personal_gittoken}" "https://git-intern2.ppc-ag.de/api/v4/snippets/${snippetid}/raw" 2>/dev/null
echo ""
done
Python functions for log file filtering
####################################################################
# Snippet 60 : "filterlog.py"
# Logfilter
# To improve : Make `startmatch` sed-compatible
####################################################################
def get_latest_logline(self, servicelogfile="/var/log/messages.log"):
"""
@return The latest log line of a log file
"""
return self.cm.run(f"tail -n1 {servicelogfile}").output.decode('utf-8').strip()
def wait_for_servicelog(self, searchstring, timeout=180, sleeptime=5, servicelogfile="/var/log/messages.log", startmatch=None):
"""
Waits for a new line in a log file that contains the given search string
@param searchstring the string to be found
@param timeout maximum time in seconds so scan for
@param sleeptime pause time in seconds between single checks
@param servicelogfile the full filename of the logfile to scanned
@param startmatch The search considers all lines AFTER startmatch. If not given, the last logline will be taken
@return the whole line containing the searchstring if found, else None
"""
starttime = time.time()
if startmatch is not None:
#self.log.info(f"Taking given startmatch {startmatch}")
latestline = startmatch
else:
#self.log.info("Gathering latest log line as start match")
latestline = self.get_latest_logline(servicelogfile)
#self.log.info(f"Using Start match : {latestline}")
while True:
now = time.time()
output = self.cm.run(f"tail -n100 {servicelogfile} | sed -n '/{latestline}/,$p' | grep \"{searchstring}\" | tail -n1").output.decode('utf-8').strip()
if len(output)>0:
self.log.info(f"Search string \"{searchstring}\" FOUND in log {servicelogfile} : {output}")
return output
else:
if (now-starttime) > timeout:
self.log.info(f"Search string \"{searchstring}\" NOT FOND in log {servicelogfile}, timeout!")
return None
else:
self.log.info(f"Search string \"{searchstring}\" not found in log {servicelogfile}, remaining {timeout-now+starttime} secs")
time.sleep(sleeptime)
Logging Macro for C
//####################################################################
//# Snippet 57 : "logging.h"
//# Logger Makro for C
//#
//####################################################################
#define errout(msg, ...) fprintf(stderr, "%s:%d (%s) : " msg, \
__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
Match a regular expression in C
//####################################################################
//# Snippet 56 : "regexmatch.c"
//# Get regex group match in C
//#
//####################################################################
int getmatch(char *searchstring, char *regex, char *result, int maxsize)
{
size_t maxGroups = 2;
regex_t regexCompiled;
regmatch_t groupArray[maxGroups];
int len = 0;
if (result == NULL)
{
perror("Invalid result pointer for regex\n");
return -1;
}
memset(result, 0, maxsize);
if (regcomp(®exCompiled, regex, REG_EXTENDED))
{
perror("Could not compile regular expression\n");
return -1;
};
if (regexec(®exCompiled, searchstring, maxGroups, groupArray, 0) == 0)
{
if (groupArray[1].rm_so != (size_t)-1)
{
len = groupArray[1].rm_eo - groupArray[1].rm_so;
if (len > maxsize)
{
len = maxsize - 1;
}
memcpy(result, searchstring + groupArray[1].rm_so, len);
}
else
{
perror("Regex did not match\n");
}
}
regfree(®exCompiled);
return len;
}
Execute shell command and consume output in C
//####################################################################
//# Snippet 55 : "readcommand.c"
//# Execute shell command in C with catching results into string buffer
//#
//####################################################################
int readcommand(char *command, char *buff, int maxlen)
{
char ch;
int i;
FILE *fp;
i = 0;
fp = popen(command, "r"); // read mode
if (fp == NULL)
{
perror("Error while opening command\n");
return -1;
}
while ((ch = fgetc(fp)) != EOF)
{
if (i < maxlen)
{
buff[i] = ch;
i++;
}
else
{
perror("Buffer full\n");
break;
}
}
fclose(fp);
return 0;
}
MAC address calculations
####################################################################
# Snippet 54 : "calc_macaddr.sh"
# MAC address calculations and transformations
#
####################################################################
#
# This function adds an offset to a MAC address
# ${1} = MAC address
# ${2} = offset to be added to the MAC address
function add_to_macaddr {
mac=$(echo ${1} | /bin/tr '[:lower:]' '[:upper:]' | /bin/tr -d ':') # upper case and remove :
macdec=$( /bin/printf '%d\n' 0x${mac} ) # convert to decimal
macadd=$( expr ${macdec} + ${2} ) # add offset
machex=$( /bin/printf '%012X\n' ${macadd} ) # convert to hex
macnew=$(echo ${machex} | /bin/sed 's/../&:/g;s/:$//') # put it in the right notation.
echo ${macnew}
}
Simple socket implementation in C
//####################################################################
//# Snippet 52 : "sockets.c"
//# TCP / UDP socket communication
//# This snippet is a suggestion for some TCP or UDP clients or servers.
//Additionally to the standard snippets which you can easily find in the internet I have worked out solutions for some pitfalls here (especially in the UDP communication) that I met during the clshks3proxy implementation in the libCLS
//####################################################################
//////////////////////////////////////////////////////////////////////////////////
// //
// Simple TCP / UDP socket communication snippet //
// @author : g.raudenbusch //
// //
//////////////////////////////////////////////////////////////////////////////////
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/time.h>
#define TCP_PROTOCOL_ID 6
#define UDP_PROTOCOL_ID 17
// Note: The very small packet size here ist just used for testing purposes,
// practically something like 16384 or 65536 speeds up the transfer
#define PKT_SIZE 128
/**
* Note: The OS can sometimes prevent correct UDP transfer of large data.
* To fix that, the adaption of the following sysctl parameters has
* helped me :
*
* echo 26214400 >/proc/sys/net/core/rmem_max
* echo 26214400 >/proc/sys/net/core/rmem_default
**/
/**
* This structue contains all variables that are needed
* for the basic socket communication
*/
typedef struct socketParams
{
int protocol_id; // The protocol id
char *ipaddr; // IP address
int port; // Port number
int sockfd; // Socket descriptor
int connfd; // Socket descriptor for TCP connections
struct sockaddr_in sockaddr; // Socket address
} socketParameters;
// [ Library functions ] //////////////////////////////////////////////////////////////////
/**
* This helper function dumps out the socket structure content
* @param params pointer to socket structure
*/
#ifdef DEBUG
static void sock_dumpSocketParams(socketParameters *params)
{
if (!params)
{
printf("Params = NULL!\n");
return;
}
if (params->protocol_id == TCP_PROTOCOL_ID)
{
printf("Protocol = TCP\n");
}
else if (params->protocol_id == UDP_PROTOCOL_ID)
{
printf("Protocol = UDP\n");
}
else
{
printf("Unknown protocol ID!\n");
}
printf("ipaddr = %s\n", params->ipaddr);
printf("port = %d\n", params->port);
printf("sockfd = %d\n", params->sockfd);
printf("connfd = %d\n", params->connfd);
}
#endif // DEBUG
/**
* This function initializes the socket, binds it to an IP and port and sets the receive timeout
* @param pSocketParams pointer to the structure containing the socket configuration
* @param asServer if set > 0 the socket will be bound for further usage as server
* @return socket descriptor on success, else negative value
*/
static int sock_init(socketParameters *pSocketParams, int asServer)
{
int sockfd = -1;
int retval = 0;
struct timeval tv;
if (pSocketParams == NULL)
{
fprintf(stderr, "Error, no thread params!\n");
return -1;
}
pSocketParams->connfd = -1;
do
{
// Use timeout of 1 sec.
tv.tv_sec = 1;
tv.tv_usec = 0;
// Create the socket
if (pSocketParams->protocol_id == TCP_PROTOCOL_ID)
{
fprintf(stderr, "Initializing TCP socket\n");
sockfd = socket(AF_INET, SOCK_STREAM, pSocketParams->protocol_id);
}
else if (pSocketParams->protocol_id == UDP_PROTOCOL_ID)
{
fprintf(stderr, "Initializing UDP socket\n");
sockfd = socket(AF_INET, SOCK_DGRAM, pSocketParams->protocol_id);
}
else
{
fprintf(stderr, "Invalid protocol id %d\n", pSocketParams->protocol_id);
break;
}
if (sockfd < 0)
{
fprintf(stderr, "Cannot create socket: %s", strerror(errno));
break;
}
memset(&(pSocketParams->sockaddr), 0, sizeof(struct sockaddr_in));
pSocketParams->sockaddr.sin_family = AF_INET;
pSocketParams->sockaddr.sin_addr.s_addr = inet_addr(pSocketParams->ipaddr);
pSocketParams->sockaddr.sin_port = htons(pSocketParams->port);
if (asServer > 0)
{
// Bind to the address to the socket
fprintf(stderr, "Binding socket\n");
retval = bind(sockfd, (const struct sockaddr *)&(pSocketParams->sockaddr), sizeof(struct sockaddr_in));
if (retval != 0)
{
fprintf(stderr, "Could not bind socket to %s:%u, error %s, aborting\n", pSocketParams->ipaddr, pSocketParams->port, strerror(errno));
break;
}
// Set the socket option: timeout on receive
fprintf(stderr, "Setting receive timeout of %ld seconds for socket\n", tv.tv_sec);
retval = setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval));
// Enable socket reuse (optional)
int optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval, sizeof(int));
// For testing purposes : Set nonblocking
//int status = fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
}
} while (0);
// If mandatory socket operations failed, close it and retun -1
if (retval != 0)
{
fprintf(stderr, "Error occured, closing socket finally\n");
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
sockfd = -1;
}
pSocketParams->sockfd = sockfd;
if (pSocketParams->protocol_id == UDP_PROTOCOL_ID)
{
// UDP isn't connection based
pSocketParams->connfd = sockfd;
}
return sockfd;
}
/**
* Sends the buffer content to the destination
* @param pSocketParams pointer to the structure containing the socket configuration
* @param buf pointer to the message to be sent
* @param lentosend length in bytes to send
* @return the length of successfully sent bytes or -1 on errors
*/
static int sock_send(socketParameters *pSocketParams, char *buf, int lentosend)
{
ssize_t len = 0;
socklen_t socklen = sizeof(struct sockaddr);
if (pSocketParams->protocol_id == TCP_PROTOCOL_ID)
{
len = write(pSocketParams->connfd, (void *)buf, lentosend);
}
else if (pSocketParams->protocol_id == UDP_PROTOCOL_ID)
{
len = sendto(pSocketParams->connfd, (void *)buf, lentosend, 0, (struct sockaddr *)&(pSocketParams->sockaddr), socklen);
}
else
{
fprintf(stderr, "Invalid protocol id %d\n", pSocketParams->protocol_id);
}
return len;
}
/**
* Receives content from socket into the destinated buffer
* @param pSocketParams pointer to the structure containing the socket configuration
* @param buf pointer to receive buffer
* @param tries amount of tries in case of errors
* @return the length of received bytes or -1 on errors
*/
static int sock_recv(socketParameters *pSocketParams, char *buf, int tries)
{
ssize_t len = -1;
socklen_t socklen = sizeof(struct sockaddr);
if (tries < 1)
{
tries = 1;
}
while (len < 0)
{
if (pSocketParams->protocol_id == TCP_PROTOCOL_ID)
{
fprintf(stderr, "sock_recv : read() from TCP socket\n");
errno = 0;
len = read(pSocketParams->connfd, (void *)buf, PKT_SIZE);
}
else if (pSocketParams->protocol_id == UDP_PROTOCOL_ID)
{
fprintf(stderr, "sock_recv : read() from UDP socket\n");
errno = 0;
// NOTE : When the source sends a datagram bigger than your receive buffer size,
// the rest of the UDP datagram will be lost forever!! But it is possible that
// the source sends multiple datagrams smaller/equal than your receive buffer size.
// These can be get by calling recvfrom multiple times.
len = recvfrom(pSocketParams->connfd, (void *)buf, PKT_SIZE, 0, (struct sockaddr *)&(pSocketParams->sockaddr), &socklen);
}
else
{
fprintf(stderr, "Invalid protocol id %d\n", pSocketParams->protocol_id);
}
if (len < 0)
{
// Do some error handling
if (EAGAIN == errno && --tries)
{
fprintf(stderr, "sock_recv : Socket timeout, %d tries left\n", tries);
}
else if (EINTR == errno)
{
fprintf(stderr, "sock_recv : Interrupted by signal\n");
}
else
{
// client has nothing (more) to say
fprintf(stderr, "sock_recv : Unhandled errno %s\n", strerror(errno));
break;
}
}
}
return len;
}
/**
* Listens for TCP connections
* @param pSocketParams pointer to the structure containing the socket configuration
* @return 0 on success, else -1
*/
static int sock_listen(socketParameters *pSockparams)
{
return listen(pSockparams->sockfd, 1);
}
/**
* Accepts a new TCP connection on the server side
* @param pSocketParams pointer to the structure containing the socket configuration
* @return the file descriptor of the new connection on success, else -1
*/
static int sock_accept(socketParameters *pSockparams)
{
pSockparams->connfd = accept(pSockparams->sockfd, NULL, NULL);
return pSockparams->connfd;
}
/**
* Starts a new TCP connection on the client side
* @param pSocketParams pointer to the structure containing the socket configuration
* @return 0 on success, else -1
*/
static int sock_connect(socketParameters *pSockparams)
{
int retval = -1;
retval = connect(pSockparams->sockfd, (const struct sockaddr *)&(pSockparams->sockaddr), sizeof(struct sockaddr_in));
if (retval >= 0)
{
pSockparams->connfd = pSockparams->sockfd;
}
return retval;
}
// [ Example implementations ] //////////////////////////////////////////////////////////////////
/**
* Opens a TCP server
* @param addr IP adress of server
* @param port TCP port of server
* @return -1 on errors
*/
static int sock_tcpserver(char *addr, int port)
{
socketParameters sockparams;
int len = -1;
char buf[PKT_SIZE];
sockparams.protocol_id = TCP_PROTOCOL_ID;
sockparams.ipaddr = addr;
sockparams.port = port;
memset(buf, 0, PKT_SIZE);
if (sock_init(&sockparams, 1) < 0)
{
return -1;
}
if (sock_listen(&sockparams) < 0)
{
return -1;
}
while (1) // Run server until CTRL-C pressed
{
while (1) // Waiting for valid client connection
{
if (sock_accept(&sockparams) < 0)
{
// Timeout
fprintf(stderr, "No new client connection: %s\n", strerror(errno));
sleep(1);
continue;
}
break;
}
// Here we should have a new connection
while (1) // Run as long as the client keeps the connection up
{
if (sockparams.connfd < 0)
{
fprintf(stderr, "Client connection has been closed in between\n");
break;
}
fprintf(stderr, "Reading from client\n");
memset(buf, 0, PKT_SIZE);
len = sock_recv(&sockparams, buf, 3);
if (len <= 0)
{
// client has nothing (more) to say
fprintf(stderr, "No more packets from client\n");
break;
}
else
{
// Here you can to different stuff, i.E. appending the packet content
// to a global buffer. For testing purposes we are just printing it here
fprintf(stdout, "Client sent (%d): %s\n", len, buf);
}
}
close(sockparams.connfd);
}
close(sockparams.sockfd);
return 0;
}
/**
* Connects to a TCP server and sends some data
* @param addr IP adress of server
* @param port TCP port of server
* @param msg some message
* @param msglen the length of the message to send
* @return -1 on errors, else 0
*/
static int sock_tcpclient(char *addr, int port, char *msg, int msglen)
{
socketParameters sockparams;
int totalsent = 0;
int retval = 0;
sockparams.protocol_id = TCP_PROTOCOL_ID;
sockparams.ipaddr = addr;
sockparams.port = port;
if (sock_init(&sockparams, 0) < 0)
{
return -1;
}
// connect the client socket to server socket
retval = sock_connect(&sockparams);
if (retval < 0)
{
fprintf(stderr, "No connection: %s\n", strerror(errno));
return -1;
}
else
{
fprintf(stderr, "Connected to server\n");
}
printf("msg = %s, msglen = %d, totalsent = %d\n", msg, msglen, totalsent);
while (totalsent < msglen)
{
// Because this is TCP, we can use the full message length here in sock_send
retval = sock_send(&sockparams, &msg[totalsent], msglen);
if (retval < 0)
{
fprintf(stderr, "Send error: %s\n", strerror(errno));
break;
}
else
{
fprintf(stderr, "Sent %d bytes\n", retval);
totalsent += retval;
}
}
fprintf(stderr, "Closing socket\n");
close(sockparams.sockfd);
return 0;
}
/**
* Opens a UDP server
* @param addr IP adress of server
* @param port UDP port of server
* @return -1 on errors
*/
static int sock_udpserver(char *addr, int port)
{
socketParameters sockparams;
int len = -1;
char buf[PKT_SIZE];
sockparams.protocol_id = UDP_PROTOCOL_ID;
sockparams.ipaddr = addr;
sockparams.port = port;
if (sock_init(&sockparams, 1) < 0)
{
return -1;
}
while (1) // Run server until CTRL-C pressed
{
if (sockparams.sockfd < 0)
{
sock_init(&sockparams, 1);
if (sockparams.sockfd < 0)
{
// Failed to initialize socket
fprintf(stderr, "Could not initialize socket: %s\n", strerror(errno));
sleep(1);
continue;
}
}
else
{
fprintf(stderr, "Reusing UDP socket %d\n", sockparams.sockfd);
}
memset(buf, 0, PKT_SIZE);
len = sock_recv(&sockparams, buf, 3);
if (len == 0)
{
fprintf(stderr, "Read 0 bytes, peer has performed an orderly shutdown\n");
break;
}
else if (len < 0)
{
fprintf(stderr, "Nothing read from client\n");
sleep(1);
}
// Do what you like with the data here :
fprintf(stdout, "Client sent (%d): %s\n", len, buf);
}
close(sockparams.sockfd);
return 0;
}
/**
* Connects to a UDP server and sends some data
* @param addr IP adress of server
* @param port UDP port of server
* @param msg some message
* @param msglen the length of the message to send
* @return -1 on errors, else 0
*/
static int sock_udpclient(char *addr, int port, char *msg, int msglen)
{
socketParameters sockparams;
int totalsent = 0;
int tosend = msglen;
int retval = 0;
sockparams.protocol_id = UDP_PROTOCOL_ID;
sockparams.ipaddr = addr;
sockparams.port = port;
if (sock_init(&sockparams, 0) < 0)
{
return -1;
}
while (totalsent < msglen)
{
// NOTE: The overlength data of a UDP datagram (when the sent datagram is greater
// than the receive buffer for it on the other side) will NEVER be processed by
// the receiver and gets lost forever!
// This is why we use PKT_SIZE here in sock_send as maximum and not msglen
tosend = (msglen - totalsent) > PKT_SIZE ? PKT_SIZE : (msglen - totalsent);
retval = sock_send(&sockparams, &msg[totalsent], tosend);
if (retval < 0)
{
fprintf(stderr, "Send error: %s\n", strerror(errno));
break;
}
else
{
fprintf(stderr, "Sent %d bytes\n", retval);
totalsent += retval;
}
}
close(sockparams.sockfd);
return 0;
}
// [ Main function to test the example implementations ] ////////////////////////////////////////
// Example calls :
// ./yourfilename server tcp 127.0.0.1 12345
// ./yourfilename client tcp 127.0.0.1 12345 Hello123
int main(int argc, char **argv)
{
if (argc < 5)
{
fprintf(stderr, "Too few arguments\n");
return -1;
}
if (strcmp(argv[1], "server") == 0)
{
if (strcmp(argv[2], "tcp") == 0)
{
return sock_tcpserver(argv[3], atoi(argv[4]));
}
else if (strcmp(argv[2], "udp") == 0)
{
return sock_udpserver(argv[3], atoi(argv[4]));
}
else
{
fprintf(stderr, "Argument 2 must be 'tcp' or 'udp'\n");
}
}
else if (strcmp(argv[1], "client") == 0)
{
if (strcmp(argv[2], "tcp") == 0)
{
return sock_tcpclient(argv[3], atoi(argv[4]), argv[5], strlen(argv[5]));
}
else if (strcmp(argv[2], "udp") == 0)
{
return sock_udpclient(argv[3], atoi(argv[4]), argv[5], strlen(argv[5]));
}
else
{
fprintf(stderr, "Argument 2 must be 'tcp' or 'udp'\n");
}
}
else
{
fprintf(stderr, "Argument 1 must be 'client' or 'server'\n");
}
}
//####################################################################
//# Snippet 51 : "bufferdump.c"
//# Output hexdump
//# This snippet outputs a hexdump of a memory area. It is very useful for debugging purposes.
//####################################################################
/**
* Prints out a hexdump
*/
void bufferdump(const unsigned char *buff, int size, char* title)
{
int col, line, linecount, linelen;
printf("************* HEXDUMP (%s) *************\n", title);
linecount = size / 16 + (size % 16 > 0);
for (line = 0; line < linecount; line++)
{
linelen = (line == linecount - 1) ? 16 * (size % 16 == 0) + size % 16 : 16;
printf("%p | ", buff + line * 16);
for (col = 0; col < 16; col++)
{
if (col < linelen)
{
printf("%02x ", buff[16 * line + col]);
}
else
{
printf(" ");
}
}
printf(" | ");
for (col = 0; col < 16; col++)
{
char c;
if (col < linelen)
{
c = buff[16 * line + col];
}
else
{
c = ' ';
}
if (c < 32)
{
c = '.';
}
printf("%c", c);
}
printf("\n");
}
printf("*********** HEXDUMP END (%s) ***********\n", title);
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <mqueue.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>
/**
* This function gets the hardware address (MAC) of a named ethernet interface.
* @param intf_asc input parameter, string containing the interface name (i.e. "eth0")
* @param mac_asc output parameter, pointer to the hex ascii MAC address string, minimum length 13 char.
* @return 0 on success else error code
*/
int32_t get_macaddr( const char* intf_asc, char* mac_asc)
{
int iRet = 0;
int sock = -1;
int i = 0;
struct ifreq sintf;
size_t len = 0;
do{
/* Checking parameters. */
if(!intf_asc && !mac_asc){
iRet = -EINVAL;
break;
}
len = strlen(intf_asc);
/* Special check for the interface name. */
if((len < 1) || (len > IFNAMSIZ)){
iRet = -EINVAL;
break;
}
/* Open a socket file descriptor just to get the interface parameters. */
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if(sock < 0){
iRet = -EIO;
break;
}
/* Get the interface MAC address from the lowest depth of the kernel. */
strcpy(sintf.ifr_name, intf_asc);
iRet = ioctl(sock, SIOCGIFHWADDR, &sintf);
if(iRet != EXIT_SUCCESS){
break;
}
/* Build the hex ascii reprezentation of the MAC address. */
for(i = 0; i < 6; i++){
sprintf((mac_asc+(2*i)), "%02x", (unsigned char)sintf.ifr_addr.sa_data[i]);
}
}while(0);
/* Close the socket to not leak descriptors. */
if( sock >= 0) close(sock);
return iRet;
}
Parse file and process functions with bash
####################################################################
# Snippet 49 : "testrunner.sh"
# LyraBox
# This script implements # some basic functions. Then it reads in a textfile which calls that basic functions like organ pipes in a lyrabox as scripted in the textfile
#
# Very useful for functional integration testing with different permutations of the function order.
####################################################################
#!/bin/bash
# [ Functions to be triggered ] ######################################################
function setmode {
echo "Setting mode ${1}"
return $?
}
# [ Main processing ] ######################################################
# All parameters present ?
if [ $# -lt 1 ]; then
echo "Parameters missing"
echo "Usage $0 <text file containing script commands>"
exit 1
fi
testscript=${1}
test_failed=0
# Start reading script
while IFS= read -r line
do
# Ignore too short lines
if [ "${#line}" -lt "4" ]; then
echo ${line}
continue
fi
# Ignore comment lines starting with '#'
if [[ ${line:0:1} == "#" ]]; then
echo ${line}
continue
fi
# Process mode change command
# Syntax : MODE=X
if [[ ${line:0:5} == "MODE=" ]]; then
# This reads only one character
mode=${line:5:1}
# This reads all remaining chars till end
mode=${line:5}
setmode ${mode}
result=$?
if [ "${result}" != "0" ]; then
test_failed=1
break
fi
continue
fi
done < ${testscript}
if [[ "${test_failed}" != "0" ]]; then
echo "A test has failed!"
exit 1
else
echo "All tests executed without errors"
fi
exit 0
Longtime recording of top outputs
####################################################################
# Snippet 48 : "topit.sh"
# Record longtime trace of CPU load for selected processes
#
####################################################################
#!/bin/sh
# Traces the CPU load for selected services
SERVICES="Service1 Service2 Service3"
RESULTFILE="/usr/local/tmp/topresult.txt"
write_headline() {
RESULT="timestamp"
for s in $SERVICES
do
RESULT="${RESULT};${s}"
done
echo $RESULT >$RESULTFILE
}
get_topvalues() {
TOPFILE="/tmp/top-snapshot.txt"
RESULT=""
rm -f ${TOPFILE}
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
top -b -n1 >$TOPFILE
RESULT=${TIMESTAMP}
for s in $SERVICES
do
SINGLERES=$(cat $TOPFILE | grep "/usr/local/bin/$s" | grep -v "grep" | grep -v "tail" | awk ' { print $8 } ')
RESULT="${RESULT};${SINGLERES}"
done
echo $RESULT >>$RESULTFILE
}
write_headline
while true
do
get_topvalues
sleep 5
done
FIFO implementation in C
//####################################################################
//# Snippet 47 : "fifo_read.c"
//# Sending data via FIFO from command line console to daemonized processes
//# While a simple command line program can read data piped into it ( i.E. with `echo "blabla" | myprogram` ) from console by reading stdin ( i.E. `while (!std::getline(std::cin, inputline).eof())` ), this is not possible for a daemon process. For that purpose the daemon process can open a FIFO instead to receive data from the command line. The suggested function is destinated to be implemented into the daemon process. The FIFO node will then appear in the /tmp folder and you can directly echo or cat something to it.
####################################################################
#define FIFONODE "/tmp/myinput"
/**
* This function returns the current time in usecs
* @return time in usecs
*/
uint64_t get_usecs()
{
uint64_t result;
struct timeval tv;
gettimeofday(&tv, NULL);
result = tv.tv_sec * (uint64_t)1000000 + tv.tv_usec;
return result;
}
/**
* This function reads from FIFO and initially also creates it.
* @param fifofd pointer to FIFO file descriptor
* @param serbuf the receive buffer
* @param uSampleSize the awaited count of bytes to be read
* @param uSampleRate the time in usecs until the read times out
* @return number of bytes read or -1 when timed out
*/
int fifo_read(int *fifofd, uint8_t *serbuf, uint32_t uSampleSize, uint32_t uSampleRate)
{
int iGet = 0; // Return value
uint32_t total = 0; // Count of bytes read from FIFO
uint64_t starttime = get_usecs();
// Read from FIFO
if (*fifofd < 0)
{
printf("Creating FIFO '%s'\n", FIFONODE);
mkfifo(FIFONODE, 0666);
*fifofd = open(FIFONODE, O_RDONLY | O_NONBLOCK);
}
total = 0;
iGet = -1;
memset(serbuf, 0, MAX_DATA_LEN);
while ((iGet <= 0) && (total < uSampleSize) && (get_usecs() - starttime) < uSampleRate)
{
iGet = read(*fifofd, &serbuf[total], uSampleSize);
if (iGet > 0)
{
total += iGet;
}
}
return iGet;
}
// Example Usage :
int fifofd = -1;
uint8_t serbuf[MAX_DATA_LEN] = { 0 };
char* debug_serial = getenv("DEBUGFLAG"); // to set with 'export DEBUGFLAG=1'
if (debug_serial)
{
int iGet = fifo_read(&fifofd, serbuf, 123, 1000*1000*1000);
if (iGet > 0)
{
printf("Read %d chars from '%s' : %s\n", iGet, FIFONODE, serbuf);
}
}
Get expiration dates of certificates
####################################################################
# Snippet 46 : "grabCertDates.sh"
# Get validity window of TLS certificates
#
####################################################################
#!/bin/sh
#
# Copyright OpenLimit SignCubes AG, 2019
#
# Helper script to grab certificate validity period(s)
prg="$0"
optCSV="n"
optDir=""
optFile=""
dateNow=""
showHelp()
{
cat <<EOF
Helper script to find certificates and grab their validity periods
Usage: ${prg} [options]
-h, --help ........ show this help
-c, --csv ......... create comma-separated list items for csv import
* -d <dir> .......... base directory for searching (recursively)
or
* -f <file> ......... single file to be used
-m, --mark ........ mark expired items
* ........ required parameter
EOF
}
while [ $# -ne 0 ] ; do
case ${1} in
"-h"|"--help")
showHelp
exit 0
;;
"-c"|"--csv")
optCSV="y"
;;
"-d")
optDir="${2}"
if [ ! -d "${optDir}" ] ; then
echo "Error - directory not found: '${optDir}'"
exit 1
fi
shift 1
;;
"-f")
optFile="${2}"
if [ ! -r "${optFile}" ] ; then
echo "Error - file not found: '${optFile}'"
exit 1
fi
shift 1
;;
"-m"|"--mark")
dateNow="`date -u +\"%Y-%m-%d %H:%M:%S\"`"
;;
*)
showHelp
exit 1
;;
esac
shift 1
done
OSSL="`which openssl`"
OSSLOPT="x509 -noout -dates"
OSSLOPTDER="-inform DER"
OSSLOPTPEM="-inform PEM"
if [ -z "${OSSL}" ] ; then
echo "Error - openssl binary not found but required, please install and/or adopt PATH"
exit 1
fi
listFile="`mktemp`"
optQuit="n"
createListFile()
{
if [ ! -z "${optFile}" ] ; then
echo "${optFile}" > ${listFile}
else
find ${optDir} -type f | sort > ${listFile}
fi
#echo "`ls -lsa ${listFile}`" >&2
#cat ${listFile} >&2
}
checkExpiration()
{
dtChk=$(date -d "${1}" +%s)
dtNow=$(date -d "${dateNow}" +%s)
#echo "Checking expiration of date '${1} - ${dtChk} against now (${dtNow})'" >&2
if [ ${dtChk} -lt ${dtNow} ] ; then
echo "expired"
else
if [ "y" = "${optCSV}" ] ; then
echo ""
else
echo " "
fi
fi
}
grabDate()
{
if [ ! -r "${1}" ] ; then
echo "Failed read of '${1}'"
return
fi
osslCmdDER="${OSSL} ${OSSLOPT} ${OSSLOPTDER} -in ${1}"
osslCmdPEM="${OSSL} ${OSSLOPT} ${OSSLOPTPEM} -in ${1}"
dates="`${osslCmdDER} 2>/dev/null`"
if [ -z "${dates}" ] ; then
dates="`${osslCmdPEM} 2>/dev/null`"
fi
if [ -z "${dates}" ] ; then
return
fi
#echo "dates: '${dates}'"
notBefore="`echo -n ${dates} | sed -e 's/notBefore=//g' -e 's/ notAfter.*//g' | date -u +\"%Y-%m-%d %H:%M:%S\" -f -`"
notAfter="`echo -n ${dates} | sed -e 's/.*notAfter=//g' | date -u +\"%Y-%m-%d %H:%M:%S\" -f -`"
markExp=""
if [ ! -z "${dateNow}" ] ; then
markExp=$(checkExpiration "${notAfter}")
fi
if [ "y" = "${optCSV}" ] ; then
echo "${markExp},${notBefore},${notAfter},${1}"
else
echo "${markExp} ${notBefore} ${notAfter} ${1}"
fi
}
prtHeader()
{
if [ "y" = "${optCSV}" ] ; then
if [ ! -z "${dateNow}" ] ; then
echo "Called at,${dateNow},,pwd: `pwd`"
echo ",,,"
echo "Expired,Not before,Not after,File name"
else
echo "Not before,Not after,File name"
fi
else
if [ ! -z "${dateNow}" ] ; then
echo "Expired Not before Not after File name"
else
echo "Not before Not after File name"
fi
fi
}
grabDates()
{
if [ ! -s ${listFile} ] ; then
return
fi
prtHeader
while IFS= read -r filename ; do
if [ "y" = "${optQuit}" ] ; then
break
fi
grabDate "${filename}"
done < ${listFile}
}
stopScript()
{
optQuit="y"
#echo "${prg}: stopScript called" >&2
}
trap stopScript INT QUIT TERM
createListFile
grabDates
rm -f ${listFile}
# EOF
Get git logs
####################################################################
# Snippet 45 : "get_gitlogs.sh"
# Get Git logs
#
####################################################################
#!/bin/bash
echo "Date |Author |Hash |Subject"
git log --no-merges --date=format:'%Y-%m-%d %H:%M:%S' --pretty=format:"%C(green)%ad|%C(yellow)%<(20)%cn|%C(reset)%h|%C(white bold)%s" $@
Plot 1-dimensional cellular automata in python
####################################################################
# Snippet 44 : "cellular.py"
# Wolfram automata
#
####################################################################
#!/usr/bin/python3
from __future__ import division
import sys
import numpy as np
import matplotlib.pyplot as plt
if __name__ == "__main__":
rule = sys.argv[1]
w = 1000
r = s = [0] * w
r[int(w/2)] = 1
d = 0
xlist = []
ylist = []
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(18, 10))
for j in range(0, int(w/2)):
n = (r[0] << 1) + r[1]
for i in range(1, w):
if r[i] == 1:
xlist.append(i)
ylist.append(d)
for i in range(2, w):
n = (n << 1) + r[i]
if n >= 8:
n -= 8
s[i-1] = (int(rule) >> n) % 2
r = s
d += 1
plt.plot(xlist, ylist, ",k")
plt.savefig("cellular.png")
plt.show()
Perceptron in python
####################################################################
# Snippet 43 : "perceptron.py"
# Perceptron
#
####################################################################
#!/usr/bin/python3
from numpy import array, random, dot
from random import choice
from pylab import ylim, plot
from matplotlib import pyplot as plt
# Aktivierungsfunktion
def step_function(x): return 0 if x < 0 else 1
# Trainingsdaten
training_dataset = [
(array([0, 0, 1]), 0),
(array([0, 1, 1]), 1),
(array([1, 0, 1]), 1),
(array([1, 1, 1]), 1),
]
weights = random.rand(3)
error = []
learning_rate = 0.2
n = 100
# Training
for j in range(n):
x, expected = choice(training_dataset) # Zufälligen Datensatz wählen
result = dot(weights, x) # Skalarprodukt bilden
err = expected - step_function(result) # Fehler berechnen
error.append(err)
weights += learning_rate * err * x # Gewichte anpassen
# Abrufen der gelernten Inhalte
for x, _ in training_dataset:
result = dot(x, weights)
print("{}: {} -> {}".format(x[:2], result, step_function(result)))
# Plot der Fehler
ylim([-1, 1])
plot(error)
plt.show()
Shortest crashing C program
//####################################################################
//# Snippet 42 : "crashtest.c"
//# Shortest crashing C program
//#
//####################################################################
main;
Plot mandelbrot in python
####################################################################
# Snippet 41 : "plot_mandelbrot_readable.py"
# Mandelbrot (more readable)
#
####################################################################
#!/usr/bin/python3
import matplotlib.pyplot as plt
import numpy as np
def mandelbrot_set(width, height, zoom=1, x_off=0, y_off=0, niter=256):
""" A mandelbrot set of geometry (width x height) and iterations 'niter' """
w,h = width, height
pixels = np.arange(w*h, dtype=np.uint16).reshape(h, w)
# The mandelbrot set represents every complex point "c" for which
# the Julia set is connected or every julia set that contains
# the origin (0, 0). Hence we always start with c at the origin.
for x in range(w):
for y in range(h):
# calculate the initial real and imaginary part of z,
# based on the pixel location and zoom and position values
# We use (x-3*w/4) instead of (x-w/2) to fully visualize
# the fractal along the x-axis
px = 1.5*(x + x_off - 3*w/4)/(0.5*zoom*w)
py = 1.0*(y + y_off - h/2)/(0.5*zoom*h)
c = complex(px, py)
z = complex(0, 0)
# Julia :
#z = complex(px, py)
#c = complex(-0.4, 0.6)
for i in range(niter):
if abs(z) > 4: break
# Iterate till the point c is outside
# the circle with radius 2.
# Calculate new positions
z = z**2 + c
color = (i << 21) + (i << 10) + i * 8
pixels[y,x] = color
return pixels
def display(width=1024, height=768, zoom=1.0, x_off=0, y_off=0, cmap='magma'):
""" Display a mandelbrot set of width `width` and height `height` and zoom `zoom`
and offsets (x_off, y_off) """
pixels = mandelbrot_set(width, height, zoom=zoom, x_off=x_off, y_off=y_off)
# Let us turn off the axes
plt.axis('off')
# to display the created fractal
plt.imshow(pixels, cmap=cmap)
plt.show()
if __name__== "__main__":
display()
Plot julia in python
####################################################################
# Snippet 40 : "plot_julia.py"
# Julia
#
####################################################################
#!/usr/bin/python3
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
m = 1024
n = 768
s = 600 # Scale.
x = np.linspace(-m / s, m / s, num=m).reshape((1, m))
y = np.linspace(-n / s, n / s, num=n).reshape((n, 1))
Z = np.tile(x, (n, 1)) + 1j * np.tile(y, (1, m))
C = np.full((n, m), -0.4 + 0.6j)
M = np.full((n, m), True, dtype=bool)
N = np.zeros((n, m))
for i in range(256):
Z[M] = Z[M] * Z[M] + C[M]
M[np.abs(Z) > 2] = False
N[M] = i
# Save with Matplotlib using a colormap.
fig = plt.figure()
fig.set_size_inches(m / 100, n / 100)
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(np.flipud(N), cmap='hot')
plt.savefig('julia-plt.png')
plt.show()
#plt.close()
Plot another mandelbrot in python
####################################################################
# Snippet 39 : "plot_mandelbrot.py"
# Mandelbrot
#
####################################################################
#!/usr/bin/python3
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
m = 1024
n = 768
s = 600 # Scale.
x = np.linspace(-m / s, m / s, num=m).reshape((1, m))
y = np.linspace(-n / s, n / s, num=n).reshape((n, 1))
C = np.tile(x, (n, 1)) + 1j * np.tile(y, (1, m))
Z = np.full((n, m), -0.0 + 0.0j)
M = np.full((n, m), True, dtype=bool)
N = np.zeros((n, m))
for i in range(256):
Z[M] = Z[M] * Z[M] + C[M]
M[np.abs(Z) > 2] = False
N[M] = i
# Save with Matplotlib using a colormap.
fig = plt.figure()
fig.set_size_inches(m / 100, n / 100)
ax = fig.add_axes([0, 0, 1, 1], frameon=False, aspect=1)
ax.set_xticks([])
ax.set_yticks([])
plt.imshow(np.flipud(N), cmap='hot')
plt.savefig('mandel-plt.png')
plt.show()
#plt.close()
Plot feigenbaum diagram
#####################################################################
# Snippet 38 : "plot_feigenbaum.py"
# Feigenbaum
#
####################################################################
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
def plot_feigenbaum():
MU_MIN = 2.7
MU_MAX = 4.0
MU_DELTA = 0.001
NUM_IT = 400
X_INIT = 0.05
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(18, 10))
x = X_INIT
x_list = np.arange(MU_MIN, MU_MAX, MU_DELTA).tolist()
y_list = []
for k in x_list:
y = []
for it in range(NUM_IT):
x = k * x * (1.0 - x)
y.append(x)
y_list.append(y)
ax.plot(x_list, y_list, ",k")
ax.set_xlabel('Wachstumsfaktor K')
ax.set_ylabel('{} x-Werte'.format(NUM_IT))
plt.savefig("feigenbaum.png")
plt.show()
if __name__== "__main__":
plot_feigenbaum()
Extract tgz without leading directories to target directory
####################################################################
# Snippet 37 : "snippetfile1.txt"
# Extract tgz without leading directories to specific target directory
#
####################################################################
#!/bin/bash
tar zxf yourfile.tgz --xform='s#^.+/##x' -C your_existing_targetdirectory
Copy only new files and keep the old
####################################################################
# Snippet 36 : "snippetfile1.txt"
# Copy only new files
# Keep the old files in the target directory untouched
####################################################################
#!/bin/bash
false | cp -i /fromdir/* /todir/ > /dev/null 2>&1
Creates and mounts a new virtual loop file system
####################################################################
# Snippet 35 : "createloopfs.sh"
# Create and mount virtual loop file system
#
####################################################################
#!/bin/bash
#
# Handle virtual log container
#
VARLOG_MOUNTED=$(/bin/mount | grep -c "/var/log type ext4")
if [ "${VARLOG_MOUNTED}" -gt "0" ]; then
echo "The log container was aready mounted successfully" > /dev/kmsg
else
# Mount image for log files and create it before, if not existing
if [ ! -f /opt/logfs.img ]; then
echo "No log container found, creating it now" > /dev/kmsg
/bin/dd if=/dev/zero of=/opt/logfs.img bs=1M count=512
echo 'type=83' | /sbin/sfdisk /opt/logfs.img
echo "y" | /sbin/mkfs.ext4 /opt/logfs.img
fi
/sbin/losetup /dev/loop0 /opt/logfs.img
/bin/mount /opt/logfs.img /var/log/
ERRORCODE=$?
if [ "${ERRORCODE}" == "0" ]; then
echo "Successfully mounted the log container" > /dev/kmsg
else
echo "Mounting the log container returned errorcode ${ERRORCODE}, Stop!" > /dev/kmsg
exit ${ERRORCODE}
fi
fi
Generate a test report from a Unit test XML result output
<project name="genTestReport" default="gen" basedir=".">
<description>
Generate the HTML report from JUnit XML files
</description>
<target name="gen">
<property name="genReportDir" location="${basedir}/unitTestReports"/>
<delete dir="${genReportDir}"/>
<mkdir dir="${genReportDir}"/>
<junitreport todir="${basedir}/unitTestReports">
<fileset dir="${basedir}">
<include name="**/TEST-*.xml"/>
</fileset>
<report format="frames" todir="${genReportDir}/html"/>
</junitreport>
</target>
</project>
Simple AES encryption and decryption of files
####################################################################
# Snippet 29 : "cipher.sh"
# Encrypt and decrypt files with AES-256-CBC
# A simple openssl wrapper
####################################################################
#!/bin/bash
if [ $# -ne 3 ]; then
echo "Usage: $0 <encode / decode> <filename> <passphrase>"
exit 1
fi
if [ ! -e $2 ]; then
echo "File $2 does not exist"
exit 1
fi
if [ "$1" == "encode" ]; then
openssl enc -aes-256-cbc -e -in $2 -out $2.encoded -k $3
echo "Encoded fie is : $2.encoded"
exit 0
elif [ "$1" == "decode" ]; then
openssl enc -aes-256-cbc -d -in $2 -out $2.decoded -k $3
if [ "$?" -eq "0" ]; then
echo "Decoded file is : $2.decoded"
exit 0
else
exit 1
fi
else
echo "Unknown parameter: $1 (must be 'encode' or 'decode')"
exit 1
fi
Send an Email in python
####################################################################
# Snippet 28 : "sendemail.py"
# Send automated Email
#
####################################################################
#!/usr/bin/python3
import smtplib, ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import sys
import os
import argparse
def send(sender, receivers, subject, message, password):
port = 25 # For starttls
smtp_server = "mail.mailserver.de"
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receivers
msg['Subject'] = subject
msg.attach(MIMEText(message, 'plain'))
recvlist=receivers.split(", ")
context = ssl.create_default_context()
server = smtplib.SMTP(smtp_server, port)
server.ehlo() # Can be omitted
server.starttls(context=context)
server.ehlo() # Can be omitted
server.login(sender, password)
server.sendmail(sender, recvlist, msg.as_string())
server.quit()
def main():
parser = argparse.ArgumentParser(description='My Email sender"\n')
parser.add_argument("--sender", default="", help="Sender email address")
parser.add_argument("--to", default="", help="Receiver email address")
parser.add_argument("--subject", default="", help="Subject of email")
parser.add_argument("--message", default="", help="Email message content")
parser.add_argument("--password", default="", help="Password for email account of sender")
args = parser.parse_args()
password=args.password
if len(password)<=0:
password = input("Type password of your email account :")
send(args.sender, args.to, args.subject, args.message, password)
sys.exit(0)
if __name__== "__main__":
main()
Convert textfile to UTF-8
####################################################################
# Snippet 27 : "convert_to_utf8.sh"
# Convert a text file to UTF-8
#
####################################################################
#!/bin/bash
vim '+set fileencoding=utf-8' '+wq' $1
Calculates the seconds until the next quarter hour in bash
####################################################################
# Snippet 26 : "nextreftime.sh"
# Calculate seconds to next quarter hour
#
####################################################################
#!/bin/bash
now_clear=$(date '+%Y-%m-%d %H:%M:%S')
now_epoch=$(date '+%s' -d "$now_clear")
nextref_epoch=$(($now_epoch / 900 * 900 + 900))
nextref_clear=$(date '+%Y-%m-%d %H:%M:%S' -d @$nextref_epoch)
echo "now = $now_clear ( $now_epoch ), next reference time = $nextref_clear ( $nextref_epoch )"
secs_to_sleep=$(($nextref_epoch - $now_epoch))
echo "Time to sleep : $secs_to_sleep seconds"
Conversion between DER and ASCII
####################################################################
# Snippet 23 : "convert_der_ascii.sh"
# Conversion between DER and human readable HEX
#
####################################################################
#!/bin/bash
#DER-TO-ASCII :
cat <yourfilename>.der | od -tx1 -An | sed -e 's/\ //g' | tr -d '\n'
#ASCII-TO-DER :
echo -n 1234abcdef | perl -e 'print pack("H*", <>),' > <yourfilename>.der
Colorful text outputs in bash
####################################################################
# Snippet 22 : "colors.sh"
# Colorful shell outputs
#
####################################################################
#!/bin/bash
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
BLACK=`tput setaf 0`
RED=`tput setaf 1`
GREEN=`tput setaf 2`
YELLOW=`tput setaf 3`
BLUE=`tput setaf 4`
MAGENTA=`tput setaf 5`
CYAN=`tput setaf 6`
WHITE=`tput setaf 7`
BOLD=`tput bold`
RESET=`tput sgr0`
fi
fi
echo -e "hello ${RED}some red text${RESET} world"
echo -n "Testresult : "
echo -e "${GREEN}${BOLD}PASSED${RESET}"
echo -n "Testresult : "
echo -e "${RED}${BOLD}FAILED${RESET}"
Open image and play sound in ununtu bash
#!/bin/bash
xdg-open ~/Bilder/miracoli.png
paplay /usr/share/sounds/ubuntu/notifications/Amsterdam.ogg
Backup public media contents
#!/bin/sh
#
# To run this script in the
# Alpine Linux (iSH) on iOS
# you need to install bash,
# python3, pip3 and youtube-dl
# in it with these commands :
#
# apk add python3
# apk add pip
# apk add py3-pip
# pip install yt-dlp
# apk add ffmpeg
# apk add bash
#
# To use 'tput' :
# apk add ncurses
#
#
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
bold="$(tput bold)"
underline="$(tput smul)"
standout="$(tput smso)"
normal="$(tput sgr0)"
black="$(tput setaf 0)"
red="$(tput setaf 1)"
green="$(tput setaf 2)"
yellow="$(tput setaf 3)"
blue="$(tput setaf 4)"
magenta="$(tput setaf 5)"
cyan="$(tput setaf 6)"
white="$(tput setaf 7)"
fi
fi
echo "${bold}${yellow}§ 53 Abs. 1 des Urheberrechtsgesetzes (UrhG) beschreibt, wann die Kopie eines fremden Werkes erlaubt ist. Sinngemäß lautet es dort: \"Wenn ein Nutzer einzelne Vervielfältigungen (auch das Herunterladen) eines fremden Werks für den eigenen privaten Gebrauch ohne Erwerbszweck herstellt und diese weder verbreitet noch veröffentlicht und die benutzte Vorlage nicht offensichtlich rechtswidrig ist oder offensichtlich rechtswidrig öffentlich zugänglich gemacht wurde, ist das Kopieren grundsätzlich erlaubt.\"${normal}"
while [ true ]; do
echo "-------------------"
# postprocessing not needed for m4a
#-x --audio-format m4a \
#--add-metadata \
yt-dlp --no-post-overwrites -ciw \
-f bestaudio[ext=m4a] \
--add-metadata \
-o '%(playlist_title)s/%(playlist_index)s-%(title)s.%(ext)s' \
$@
if [ "$?" == "0" ]; then
echo "==================="
echo "${green}${bold}Success!${normal}"
exit 0
else
echo "${bold}${yellow}Continuing after errors${normal}"
fi
sleep 2
done
#
# Use --playlist-start x to append/update at position x
Webserver 127.0.0.1:8000
#!/bin/bash
python3 -m http.server
Website downloader
#!/bin/bash
domain=$(echo "${1}" | sed -En "s/^http[s]?:\/\/(.*\.)
*(.*\..*)\/.*/\2/p")
wget --no-parent --recursive --no-clobber --page-requisites --convert-links -e robots=off --domains ${domain} ${1}
Soundcloud downloader
#!/bin/sh
#
# To run this script in the
# Alpine Linux (iSH) on iOS
# you need to install bash,
# python3, pip3 and youtube-dl
# in it with these commands :
#
# apk add python3
# apk add pip
# apk add py3-pip
# pip install youtube-dl
# apk add ffmpeg
# apk add bash
#
# To use 'tput' :
# apk add ncurses
#
#
if test -t 1; then
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
bold="$(tput bold)"
underline="$(tput smul)"
standout="$(tput smso)"
normal="$(tput sgr0)"
black="$(tput setaf 0)"
red="$(tput setaf 1)"
green="$(tput setaf 2)"
yellow="$(tput setaf 3)"
blue="$(tput setaf 4)"
magenta="$(tput setaf 5)"
cyan="$(tput setaf 6)"
white="$(tput setaf 7)"
fi
fi
echo "${bold}${yellow}§ 53 Abs. 1 des Urheberrechtsgesetzes (UrhG) beschreibt, wann die Kopie eines fremden Werkes erlaubt ist. Sinngemäß lautet es dort: \"Wenn ein Nutzer einzelne Vervielfältigungen (auch das Herunterladen) eines fremden Werks für den eigenen privaten Gebrauch ohne Erwerbszweck herstellt und diese weder verbreitet noch veröffentlicht und die benutzte Vorlage nicht offensichtlich rechtswidrig ist oder offensichtlich rechtswidrig öffentlich zugänglich gemacht wurde, ist das Kopieren grundsätzlich erlaubt.\"${normal}"
while [ true ]; do
echo "-------------------"
# postprocessing not needed for mp3
#-x --audio-format mp3 \
#--add-metadata \
youtube-dl --no-post-overwrites -ciw \
-f bestaudio[ext=mp3] \
--add-metadata \
-o '%(playlist_title)s/%(playlist_index)s-%(title)s.%(ext)s' \
$@
if [ "$?" == "0" ]; then
echo "==================="
echo "${green}${bold}Success!${normal}"
exit 0
else
echo "${bold}${yellow}Continuing after errors${normal}"
fi
sleep 2
done
#
# Use --playlist-start x to append/update at position x
Display PHP environment
<?php
ini_set('display_errors', 1);
error_reporting(E_ALL);
var_dump(get_defined_vars())
?>
Pretty print in shell
#
# Pretty print function
# Can be skipped with optional parameter 'simple'
# (Jenkins cannot display archived text which was pretty printed)
#
pprint () {
echo "#"
if [ "${format}" != "simple" ] && [ -x /usr/bin/toilet ]; then
toilet -w 160 -f future ${1} | sed -E "s/^/# /g"
else
echo "# ${1}"
fi
echo "#"
}
export -f pprint
Extract opkg package (.ipk)
_openipk () {
local filename="${1}"
local tmpdir="$(basename ${filename}).extracted"
rm -rf "${tmpdir}" &&
mkdir "${tmpdir}"
(
cd ${tmpdir}
log "Unpack ipk ${filename} in $(pwd)/${tmpdir}"
ar x ${filename} && _opentars
local retval=$?
# For combi packets :
moreipks=$(find . -iname "*.ipk" 2>/dev/null | tr '\n' ' ')
for i in ${moreipks}; do
_openipk "$(pwd)/${i}"
done
exit ${retval}
)
local retval=$?
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
#
# Unpacks ipk packet and subpackets
#
packet-extract-ipk () {
local retval=0
local filename="${1}"
if [ "${filename}" == "" ]; then
log "Unpacks an ipk packet and subpackets"
log "Give filename as first parameter !"
retval=1
else
if [ -f ${filename} ]; then
if [ "$(dirname ${filename})" == "." ]; then
filename="${PWD}/${filename}"
fi
_openipk ${filename}
retval=$?
else
log "Unknown file '${filename}"
retval=1
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
export -f packet-extract-ipk
Shell execution capsuler
# This function runs a command within its own context
# of stdout and stderr to not disturb the outter sourcing scripts.
# The SSH command that we use here to gather the BSPNAME,
# destroys old contents of stdout and stderr.
# When sourcing scripts exchange data via pipes, then these data could
# be destroyed.
# ( The described problem was observed when running 'autoinit force';
# only the first line of the piped meter config was processed,
# the remaining lines got lost after gathering the BSPNAME right here. )
#
capsule () {
local PIPE_DIRECTORY=$(mktemp -d)
trap "rm -rf '$PIPE_DIRECTORY'" EXIT
mkfifo "$PIPE_DIRECTORY/stdout"
mkfifo "$PIPE_DIRECTORY/stderr"
"$@" >"$PIPE_DIRECTORY/stdout" 2>"$PIPE_DIRECTORY/stderr" &
local CHILD_PID=$!
sed 's/^//' "$PIPE_DIRECTORY/stdout" &
sed 's/^//' "$PIPE_DIRECTORY/stderr" >&2 &
wait "$CHILD_PID"
rm -rf "$PIPE_DIRECTORY"
}
export -f capsule
Generate big HTTP POST data
#!/bin/bash
size=$1
sendfile=$2
blocks=$((size / 16))
rm -f ${sendfile}
echo "Writing HTTP header to $sendfile"
printf "POST /test HTTP/1.1\r\n" >$sendfile
printf "Content-Length: $size\r\n" >>$sendfile
printf "\r\n" >>$sendfile
echo "Writing ${blocks} 16-byte-blocks (=${size} bytes total) to ${sendfile}"
for i in `seq 1 ${blocks}`;
do
printf %s "0123456789abcdef" >>${sendfile}
done
Display all toilet fonts
#!/bin/bash
toiletfonts=$(ls /usr/share/figlet/* | sed -En "s,.*/(.*).tlf,\1,p"); for font in $toiletfonts; do echo "toilet -f $font $(echo $font | rev)"; toilet -f $font $(echo $font | rev); echo ""; echo ""; done
Time tracker for test cases
#!/bin/bash
#set -x
DBPATH="/usr/share//var/db"
TIMEDB="${DBPATH}/timetracking-tests.sqlite"
######################################
#
# Lower functions
#
######################################
log () {
>&2 echo "${1}"
}
assuredb () {
mkdir -p ${DBPATH}
sqlite3 ${TIMEDB} "create table if not exists runtimes(version text, tcs text, mintime int, avgtime int, maxtime int, primary key(version, tcs));"
}
getsubquery () {
local version="${1}"
local tcs="${2}"
local whereclause=""
local joinclause=""
if [ "${tcs}" != "" ]; then
# We want to evaluate also double entries
local intcs="$(echo "${tcs}" | sed "s/ /\" as tcs union all select \"/g;s/^/\"/;s/$/\" as tcs/")"
joinclause=" join (select ${intcs}) matches using(tcs)"
fi
if [ "${version}" != "" ]; then
whereclause=" where version=\"${version}\" "
fi
echo "${joinclause} ${whereclause}"
}
removetcs () {
local version="${1}"
local tcs="${2}"
local intcs="$(echo "${tcs}" | sed "s/ /\", \"/g;s/^/(\"/g;s/$/\")/g")"
query="delete from runtimes where tcs in ${intcs};"
#log "Query: \"${query}\""
sqlite3 ${TIMEDB} "${query}"
return $?
}
converttime () {
TIMES="${1}"
FORMAT="${2}"
CONVERTED=""
TIMES=$(echo "${TIMES}" | tr '|' ' ')
for time in ${TIMES}; do
if [ "${CONVERTED}" == "" ]; then
CONVERTED="$(date -d@${time} -u +${FORMAT})"
else
CONVERTED="${CONVERTED}|$(date -d@${time} -u +${FORMAT})"
fi
done
echo "${CONVERTED}"
}
getmintime () {
assuredb
query="select ${BATCHSLEEP}+(select ${TCSLEEP}*count(*) from runtimes $(getsubquery "${1}" "${2}"))+(select sum(mintime) from runtimes $(getsubquery "${1}" "${2}"));"
#log "Query: \"${query}\""
local testtime=$(sqlite3 ${TIMEDB} "${query}")
if [ "${3}" != "" ]; then
testtime=$(converttime "${testtime}" "${3}")
fi
echo "${testtime}"
}
getavgtime () {
assuredb
query="select ${BATCHSLEEP}+(select ${TCSLEEP}*count(*) from runtimes $(getsubquery "${1}" "${2}"))+(select sum(avgtime) from runtimes $(getsubquery "${1}" "${2}"));"
#log "Query: \"${query}\""
local testtime=$(sqlite3 ${TIMEDB} "${query}")
if [ "${3}" != "" ]; then
testtime=$(converttime "${testtime}" "${3}")
fi
echo "${testtime}"
}
getmaxtime () {
assuredb
query="select ${BATCHSLEEP}+(select ${TCSLEEP}*count(*) from runtimes $(getsubquery "${1}" "${2}"))+(select sum(maxtime) from runtimes $(getsubquery "${1}" "${2}"));"
#log "Query: \"${query}\""
local testtime=$(sqlite3 ${TIMEDB} "${query}")
if [ "${3}" != "" ]; then
testtime=$(converttime "${testtime}" "${3}")
fi
echo "${testtime}"
}
getalltimes () {
assuredb
minquery="${BATCHSLEEP}+(select ${TCSLEEP}*count(*) from runtimes $(getsubquery "${1}" "${2}"))+(select sum(mintime) from runtimes $(getsubquery "${1}" "${2}"))"
avgquery="${BATCHSLEEP}+(select ${TCSLEEP}*count(*) from runtimes $(getsubquery "${1}" "${2}"))+(select sum(avgtime) from runtimes $(getsubquery "${1}" "${2}"))"
maxquery="${BATCHSLEEP}+(select ${TCSLEEP}*count(*) from runtimes $(getsubquery "${1}" "${2}"))+(select sum(maxtime) from runtimes $(getsubquery "${1}" "${2}"))"
query="select ${minquery}, ${avgquery}, ${maxquery}"
#log "Query: \"${query}\""
local testtime=$(sqlite3 ${TIMEDB} "${query}")
if [ "${3}" != "" ]; then
testtime=$(converttime "${testtime}" "${3}")
fi
echo "${testtime}"
}
listtcs () {
assuredb
query="select tcs, ${TCSLEEP}+mintime, ${TCSLEEP}+avgtime, ${TCSLEEP}+maxtime from runtimes $(getsubquery "${1}" "${2}")"
#log "Query: \"${query}\""
local lines=$(sqlite3 ${TIMEDB} "${query}")
if [ "${3}" != "" ]; then
lines=$(echo "${lines}" | tr '\n' ' ')
newlines=""
for line in ${lines}; do
tcs=$(echo "${line}" | cut -d "|" -f1)
testtimes=$(echo "${line}" | sed "s/[^|]*|//")
testtimes=$(converttime "${testtimes}" "${3}")
if [ "${newlines}" == "" ]; then
newlines="${tcs}|${testtimes}"
else
newlines="${newlines} ${tcs}|${testtimes}"
fi
done
lines=$(echo "${newlines}" | tr ' ' '\n')
fi
echo "${lines}"
}
updatetime () {
assuredb
local version="${1}"
local tcs="${2}"
local newtime="${3}"
local oldavgtime=$(getavgtime "${version}" "${tcs}")
local oldmintime=$(getmintime "${version}" "${tcs}")
local oldmaxtime=$(getmaxtime "${version}" "${tcs}")
if [ "${oldavgtime}" == "" ]; then
oldavgtime="${newtime}"
oldmintime="${newtime}"
oldmaxtime="${newtime}"
query="insert into runtimes values (\"${version}\", \"${tcs}\", ${newtime}, ${newtime}, ${newtime});"
#log "Query: \"${query}\""
sqlite3 ${TIMEDB} "${query}"
fi
local mintime=$(python -c "print(min(${oldmintime}, ${newtime}))")
local maxtime=$(python -c "print(max(${oldmaxtime}, ${newtime}))")
local avgtime=$(python -c "print((${oldavgtime}+${newtime})/2)")
#local avgtime=$(echo "scale=0;(${oldavgtime}+${newtime})/2" | bc)
query="update runtimes set mintime=${mintime}, avgtime=${avgtime}, maxtime=${maxtime} where version=\"${version}\" and tcs=\"${tcs}\""
#log "Query : \"${query}\""
sqlite3 ${TIMEDB} "${query}"
return $?
}
######################################
#
# Upper functions
#
######################################
printusage () {
log ""
log "This script reads or updates testcase duration times."
log "Available options :"
log "-v or --version : Specifies the SMGW version (1 or 2)"
log "-t or --testcase : Specifies the testcase(s) (TCS), separated by spaces"
log "-d or --duration : Specifies the duration in seconds"
log "-f or --format : Specifies the time output format, i.E. '%H:%M:%S'. Default output is in seconds"
log "--sleep-tc : Sleep time between testcases"
log "--sleep-run : Sleep time after testrun"
log ""
log "Available operations :"
log "get : Returns all times (min, avg, max)"
log "getmin : Returns the minimal measured execution time"
log "getavg : Returns the average execution time"
log "getmax : Returns the maximal measured execution time"
log "update : Feeds a new execution time for a test case into the database"
log "delete : Deletes testcase(s) from the database"
log "list : Returns detailed list of tescase times"
log ""
}
update () {
local VERSION="${1}"
local TCS="${2}"
local DURATION="${3}"
local retval=0
if [ "${VERSION}" == "" ] || [ "${TCS}" == "" ] || [ "${DURATION}" == "" ]; then
log "Give version, testcase and duration for update !"
retval=1
else
updatetime "${VERSION}" "${TCS}" "${DURATION}"
retval=$?
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
getmin () {
local VERSION="${1}"
local TCS="${2}"
local FORMAT="${3}"
if [ "${VERSION}" == "" ]; then
log "Specify the version !"
retval=1
else
if [ "${TCS}" != "" ]; then
echo "$(getmintime "${VERSION}" "${TCS}" "${FORMAT}")"
retval=$?
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
getavg () {
local VERSION="${1}"
local TCS="${2}"
local FORMAT="${3}"
if [ "${VERSION}" == "" ]; then
log "Specify the version !"
retval=1
else
if [ "${TCS}" != "" ]; then
echo "$(getavgtime "${VERSION}" "${TCS}" "${FORMAT}")"
retval=$?
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
getmax () {
local VERSION="${1}"
local TCS="${2}"
local FORMAT="${3}"
if [ "${VERSION}" == "" ]; then
log "Specify the version !"
retval=1
else
if [ "${TCS}" != "" ]; then
echo "$(getmaxtime "${VERSION}" "${TCS}" "${FORMAT}")"
retval=$?
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
getall () {
local VERSION="${1}"
local TCS="${2}"
local FORMAT="${3}"
if [ "${VERSION}" == "" ]; then
log "Specify the version !"
retval=1
else
if [ "${TCS}" != "" ]; then
echo "$(getalltimes "${VERSION}" "${TCS}" "${FORMAT}")"
retval=$?
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
getlist () {
local VERSION="${1}"
local TCS="${2}"
local FORMAT="${3}"
if [ "${VERSION}" == "" ]; then
log "Specify the version !"
retval=1
else
if [ "${TCS}" != "" ]; then
echo "$(listtcs "${VERSION}" "${TCS}" "${FORMAT}")"
retval=$?
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
delete () {
local VERSION="${1}"
local TCS="${2}"
if [ "${VERSION}" == "" ]; then
log "Specify the version !"
retval=1
else
if [ "${TCS}" != "" ]; then
removetcs "${VERSION}" "${TCS}"
retval=$?
fi
fi
(return 0 2>/dev/null) && return ${retval} || exit ${retval}
}
##########
## main ##
##########
TCSLEEP="0"
BATCHSLEEP="0"
# Evaluate command line options
POSITIONAL_ARGS=()
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
printusage
exit 1
;;
-v|--version)
VERSION="${2}"
shift # past argument
shift # past value
;;
-t|--testcase)
TCS="${2}"
shift # past argument
shift # past value
;;
-d|--duration)
DURATION="${2}"
shift # past argument
shift # past value
;;
-f|--format)
TIMEFORMAT="${2}"
shift # past argument
shift # past value
;;
--sleep-tc)
TCSLEEP="${2}"
shift # past argument
shift # past value
;;
--sleep-run)
BATCHSLEEP="${2}"
shift # past argument
shift # past value
;;
-*|--*)
log "Unknown option $1"
(return 0 2>/dev/null) && return 1 || exit 1
;;
*)
POSITIONAL_ARGS+=("$1") # save positional arg
shift # past argument
;;
esac
done
set -- "${POSITIONAL_ARGS[@]}" # restore positional parameters
# Process script operations
case ${1} in
update)
update "${VERSION}" "${TCS}" "${DURATION}"
;;
getmin)
getmin "${VERSION}" "${TCS}" "${TIMEFORMAT}"
;;
getavg)
getavg "${VERSION}" "${TCS}" "${TIMEFORMAT}"
;;
getmax)
getmax "${VERSION}" "${TCS}" "${TIMEFORMAT}"
;;
get)
getall "${VERSION}" "${TCS}" "${TIMEFORMAT}"
;;
delete)
delete "${VERSION}" "${TCS}"
;;
list)
getlist "${VERSION}" "${TCS}" "${TIMEFORMAT}"
;;
*)
printusage
(return 0 2>/dev/null) && return 1 || exit 1
;;
esac
(return 0 2>/dev/null) && return 0 || exit 0